From 81b834cb2a034456b2a2dece137cc95d7fffe604 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 1 Jan 2020 15:51:24 +0900 Subject: [PATCH 1/3] decaffeinate: Rename assertions.coffee and 6 other files from .coffee to .js --- packages/driver/src/cy/{assertions.coffee => assertions.js} | 0 .../driver/src/cypress/{chai_jquery.coffee => chai_jquery.js} | 0 packages/driver/src/cypress/{mocha.coffee => mocha.js} | 0 .../cypress/integration/issues/{510_spec.coffee => 510_spec.js} | 0 .../cypress/integration/issues/{565_spec.coffee => 565_spec.js} | 0 .../cypress/integration/issues/{573_spec.coffee => 573_spec.js} | 0 .../cypress/integration/issues/{652_spec.coffee => 652_spec.js} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename packages/driver/src/cy/{assertions.coffee => assertions.js} (100%) rename packages/driver/src/cypress/{chai_jquery.coffee => chai_jquery.js} (100%) rename packages/driver/src/cypress/{mocha.coffee => mocha.js} (100%) rename packages/driver/test/cypress/integration/issues/{510_spec.coffee => 510_spec.js} (100%) rename packages/driver/test/cypress/integration/issues/{565_spec.coffee => 565_spec.js} (100%) rename packages/driver/test/cypress/integration/issues/{573_spec.coffee => 573_spec.js} (100%) rename packages/driver/test/cypress/integration/issues/{652_spec.coffee => 652_spec.js} (100%) diff --git a/packages/driver/src/cy/assertions.coffee b/packages/driver/src/cy/assertions.js similarity index 100% rename from packages/driver/src/cy/assertions.coffee rename to packages/driver/src/cy/assertions.js diff --git a/packages/driver/src/cypress/chai_jquery.coffee b/packages/driver/src/cypress/chai_jquery.js similarity index 100% rename from packages/driver/src/cypress/chai_jquery.coffee rename to packages/driver/src/cypress/chai_jquery.js diff --git a/packages/driver/src/cypress/mocha.coffee b/packages/driver/src/cypress/mocha.js similarity index 100% rename from packages/driver/src/cypress/mocha.coffee rename to packages/driver/src/cypress/mocha.js diff --git a/packages/driver/test/cypress/integration/issues/510_spec.coffee b/packages/driver/test/cypress/integration/issues/510_spec.js similarity index 100% rename from packages/driver/test/cypress/integration/issues/510_spec.coffee rename to packages/driver/test/cypress/integration/issues/510_spec.js diff --git a/packages/driver/test/cypress/integration/issues/565_spec.coffee b/packages/driver/test/cypress/integration/issues/565_spec.js similarity index 100% rename from packages/driver/test/cypress/integration/issues/565_spec.coffee rename to packages/driver/test/cypress/integration/issues/565_spec.js diff --git a/packages/driver/test/cypress/integration/issues/573_spec.coffee b/packages/driver/test/cypress/integration/issues/573_spec.js similarity index 100% rename from packages/driver/test/cypress/integration/issues/573_spec.coffee rename to packages/driver/test/cypress/integration/issues/573_spec.js diff --git a/packages/driver/test/cypress/integration/issues/652_spec.coffee b/packages/driver/test/cypress/integration/issues/652_spec.js similarity index 100% rename from packages/driver/test/cypress/integration/issues/652_spec.coffee rename to packages/driver/test/cypress/integration/issues/652_spec.js From d51691c15c85d003c37dcc5d2d17b49d8d2dc884 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 1 Jan 2020 15:51:30 +0900 Subject: [PATCH 2/3] decaffeinate: Convert assertions.coffee and 6 other files to JS --- packages/driver/src/cy/assertions.js | 880 ++++++++++-------- packages/driver/src/cypress/chai_jquery.js | 441 +++++---- packages/driver/src/cypress/mocha.js | 349 +++---- .../cypress/integration/issues/510_spec.js | 14 +- .../cypress/integration/issues/565_spec.js | 20 +- .../cypress/integration/issues/573_spec.js | 91 +- .../cypress/integration/issues/652_spec.js | 32 +- 7 files changed, 986 insertions(+), 841 deletions(-) diff --git a/packages/driver/src/cy/assertions.js b/packages/driver/src/cy/assertions.js index a6c9099675d5..0880aa86333d 100644 --- a/packages/driver/src/cy/assertions.js +++ b/packages/driver/src/cy/assertions.js @@ -1,422 +1,494 @@ -_ = require("lodash") -Promise = require("bluebird") - -$dom = require("../dom") -$utils = require("../cypress/utils") - -## TODO -## bTagOpen + bTagClosed -## are duplicated in assertions.coffee -butRe = /,? but\b/ -bTagOpen = /\*\*/g -bTagClosed = /\*\*/g -stackTracesRe = / at .*\n/gm - -IS_DOM_TYPES = [$dom.isElement, $dom.isDocument, $dom.isWindow] - -invokeWith = (value) -> - return (fn) -> - fn(value) - -functionHadArguments = (current) -> - fn = current and current.get("args") and current.get("args")[0] - fn and _.isFunction(fn) and fn.length > 0 - -isAssertionType = (cmd) -> - cmd and cmd.is("assertion") - -isDomSubjectAndMatchesValue = (value, subject) -> - allElsAreTheSame = -> - els1 = $dom.getElements(value) - els2 = $dom.getElements(subject) - - ## no difference - _.difference(els1, els2).length is 0 - - ## iterate through each dom type until we - ## find the function for this particular value - if isDomTypeFn = _.find(IS_DOM_TYPES, invokeWith(value)) - ## then check that subject also matches this - ## and that all the els are the same - return isDomTypeFn(subject) and allElsAreTheSame() - -## Rules: -## 1. always remove value -## 2. if value is a jquery object set a subject -## 3. if actual is undefined or its not expected remove both actual + expected -parseValueActualAndExpected = (value, actual, expected) -> - obj = {actual: actual, expected: expected} - - if $dom.isJquery(value) - obj.subject = value - - if _.isUndefined(actual) or actual isnt expected - delete obj.actual - delete obj.expected - - obj - -create = (state, queue, retryFn) -> - getUpcomingAssertions = -> - current = state("current") - index = state("index") + 1 - - assertions = [] - - ## grab the rest of the queue'd commands - for cmd in queue.slice(index).get() - ## don't break on utilities, just skip over them - if cmd.is("utility") - continue - - ## grab all of the queued commands which are - ## assertions and match our current chainerId - if cmd.is("assertion") - assertions.push(cmd) - else - break - - assertions - - injectAssertionFns = (cmds) -> - _.map(cmds, injectAssertion) - - injectAssertion = (cmd) -> - return (subject) -> - ## set assertions to itself or empty array - if not cmd.get("assertions") - cmd.set("assertions", []) - - ## reset the assertion index back to 0 - ## so we can track assertions and merge - ## them up with existing ones - cmd.set("assertionIndex", 0) - - cmd.get("fn").originalFn.apply( - state("ctx"), - [subject].concat(cmd.get("args")) - ) - - finishAssertions = (assertions) -> - _.each assertions, (log) -> - log.snapshot() +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS103: Rewrite code to no longer use __guard__ + * DS104: Avoid inline assignments + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const _ = require("lodash"); +const Promise = require("bluebird"); + +const $dom = require("../dom"); +const $utils = require("../cypress/utils"); + +//# TODO +//# bTagOpen + bTagClosed +//# are duplicated in assertions.coffee +const butRe = /,? but\b/; +const bTagOpen = /\*\*/g; +const bTagClosed = /\*\*/g; +const stackTracesRe = / at .*\n/gm; + +const IS_DOM_TYPES = [$dom.isElement, $dom.isDocument, $dom.isWindow]; + +const invokeWith = value => fn => fn(value); + +const functionHadArguments = function(current) { + const fn = current && current.get("args") && current.get("args")[0]; + return fn && _.isFunction(fn) && (fn.length > 0); +}; + +const isAssertionType = cmd => cmd && cmd.is("assertion"); + +const isDomSubjectAndMatchesValue = function(value, subject) { + let isDomTypeFn; + const allElsAreTheSame = function() { + const els1 = $dom.getElements(value); + const els2 = $dom.getElements(subject); + + //# no difference + return _.difference(els1, els2).length === 0; + }; + + //# iterate through each dom type until we + //# find the function for this particular value + if (isDomTypeFn = _.find(IS_DOM_TYPES, invokeWith(value))) { + //# then check that subject also matches this + //# and that all the els are the same + return isDomTypeFn(subject) && allElsAreTheSame(); + } +}; - if e = log.get("_error") - log.error(e) - else - log.end() - - verifyUpcomingAssertions = (subject, options = {}, callbacks = {}) -> - cmds = getUpcomingAssertions() +//# Rules: +//# 1. always remove value +//# 2. if value is a jquery object set a subject +//# 3. if actual is undefined or its not expected remove both actual + expected +const parseValueActualAndExpected = function(value, actual, expected) { + const obj = {actual, expected}; - state("upcomingAssertions", cmds) + if ($dom.isJquery(value)) { + obj.subject = value; - ## we're applying the default assertion in the - ## case where there are no upcoming assertion commands - isDefaultAssertionErr = cmds.length is 0 - - options.assertions ?= [] + if (_.isUndefined(actual) || (actual !== expected)) { + delete obj.actual; + delete obj.expected; + } + } - _.defaults callbacks, { - ensureExistenceFor: "dom" + return obj; +}; + +const create = function(state, queue, retryFn) { + const getUpcomingAssertions = function() { + const current = state("current"); + const index = state("index") + 1; + + const assertions = []; + + //# grab the rest of the queue'd commands + for (let cmd of queue.slice(index).get()) { + //# don't break on utilities, just skip over them + if (cmd.is("utility")) { + continue; + } + + //# grab all of the queued commands which are + //# assertions and match our current chainerId + if (cmd.is("assertion")) { + assertions.push(cmd); + } else { + break; + } + } + + return assertions; + }; + + const injectAssertionFns = cmds => _.map(cmds, injectAssertion); + + var injectAssertion = cmd => (function(subject) { + //# set assertions to itself or empty array + if (!cmd.get("assertions")) { + cmd.set("assertions", []); + } + + //# reset the assertion index back to 0 + //# so we can track assertions and merge + //# them up with existing ones + cmd.set("assertionIndex", 0); + + return cmd.get("fn").originalFn.apply( + state("ctx"), + [subject].concat(cmd.get("args")) + ); + }); + + const finishAssertions = assertions => _.each(assertions, function(log) { + let e; + log.snapshot(); + + if ((e = log.get("_error"))) { + return log.error(e); + } else { + return log.end(); } + }); + + const verifyUpcomingAssertions = function(subject, options = {}, callbacks = {}) { + const cmds = getUpcomingAssertions(); + + state("upcomingAssertions", cmds); + + //# we're applying the default assertion in the + //# case where there are no upcoming assertion commands + const isDefaultAssertionErr = cmds.length === 0; + + if (options.assertions == null) { options.assertions = []; } - ensureExistence = -> - ## by default, ensure existence for dom subjects, - ## but not non-dom subjects - switch callbacks.ensureExistenceFor - when "dom" - $el = determineEl(options.$el, subject) - return if not $dom.isJquery($el) - - cy.ensureElExistence($el) - - when "subject" - cy.ensureExistence(subject) - - determineEl = ($el, subject) -> - ## prefer $el unless it is strickly undefined - if not _.isUndefined($el) then $el else subject - - onPassFn = => - if _.isFunction(callbacks.onPass) - callbacks.onPass.call(@, cmds, options.assertions) - else - subject - - onFailFn = (err) => - ## when we fail for whatever reason we need to - ## check to see if we would firstly fail if - ## we don't have an el in existence. what this - ## catches are assertions downstream about an - ## elements existence but the element never - ## exists in the first place. this will probably - ## ensure the error is about existence not about - ## the downstream assertion. - try - ensureExistence() - catch e2 - err = e2 - - options.error = err - - if err.retry is false - throw err - - onFail = callbacks.onFail - onRetry = callbacks.onRetry - - if not onFail and not onRetry - throw err - - ## if our onFail throws then capture it - ## and finish the assertions and then throw - ## it again - try - if _.isFunction(onFail) - ## pass in the err and the upcoming assertion commands - onFail.call(@, err, isDefaultAssertionErr, cmds) - catch e3 - finishAssertions(options.assertions) - throw e3 - - if _.isFunction(onRetry) - retryFn(onRetry, options) - - ## bail if we have no assertions and apply - ## the default assertions if applicable - if not cmds.length + _.defaults(callbacks, { + ensureExistenceFor: "dom" + }); + + const ensureExistence = function() { + //# by default, ensure existence for dom subjects, + //# but not non-dom subjects + switch (callbacks.ensureExistenceFor) { + case "dom": + var $el = determineEl(options.$el, subject); + if (!$dom.isJquery($el)) { return; } + + return cy.ensureElExistence($el); + + case "subject": + return cy.ensureExistence(subject); + } + }; + + var determineEl = function($el, subject) { + //# prefer $el unless it is strickly undefined + if (!_.isUndefined($el)) { return $el; } else { return subject; } + }; + + const onPassFn = () => { + if (_.isFunction(callbacks.onPass)) { + return callbacks.onPass.call(this, cmds, options.assertions); + } else { + return subject; + } + }; + + const onFailFn = err => { + //# when we fail for whatever reason we need to + //# check to see if we would firstly fail if + //# we don't have an el in existence. what this + //# catches are assertions downstream about an + //# elements existence but the element never + //# exists in the first place. this will probably + //# ensure the error is about existence not about + //# the downstream assertion. + try { + ensureExistence(); + } catch (e2) { + err = e2; + } + + options.error = err; + + if (err.retry === false) { + throw err; + } + + const { + onFail + } = callbacks; + const { + onRetry + } = callbacks; + + if (!onFail && !onRetry) { + throw err; + } + + //# if our onFail throws then capture it + //# and finish the assertions and then throw + //# it again + try { + if (_.isFunction(onFail)) { + //# pass in the err and the upcoming assertion commands + onFail.call(this, err, isDefaultAssertionErr, cmds); + } + } catch (e3) { + finishAssertions(options.assertions); + throw e3; + } + + if (_.isFunction(onRetry)) { + return retryFn(onRetry, options); + } + }; + + //# bail if we have no assertions and apply + //# the default assertions if applicable + if (!cmds.length) { return Promise .try(ensureExistence) .then(onPassFn) - .catch(onFailFn) - - i = 0 - - cmdHasFunctionArg = (cmd) -> - _.isFunction(cmd.get("args")[0]) - - overrideAssert = (args...) -> - do (cmd = cmds[i]) => - setCommandLog = (log) => - ## our next log may not be an assertion - ## due to page events so make sure we wait - ## until we see page events - return if log.get("name") isnt "assert" - - ## when we do immediately unbind this function - state("onBeforeLog", null) - - insertNewLog = (log) -> - cmd.log(log) - options.assertions.push(log) - - ## its possible a single 'should' will assert multiple - ## things such as the case with have.property. we can - ## detect when that is happening because cmd will be null. - ## if thats the case then just set cmd to be the previous - ## cmd and do not increase 'i' - ## this will prevent 2 logs from ever showing up but still - ## provide errors when the 1st assertion fails. - if not cmd - cmd = cmds[i - 1] - else - i += 1 - - ## if our command has a function argument - ## then we know it may contain multiple - ## assertions - if cmdHasFunctionArg(cmd) - index = cmd.get("assertionIndex") - assertions = cmd.get("assertions") - - incrementIndex = -> - ## always increase the assertionIndex - ## so our next assertion matches up - ## to the correct index - cmd.set("assertionIndex", index += 1) - - ## if we dont have an assertion at this - ## index then insert a new log - if not assertion = assertions[index] - assertions.push(log) - incrementIndex() - - return insertNewLog(log) - else - ## else just merge this log - ## into the previous assertion log - incrementIndex() - assertion.merge(log) - - ## dont output a new log - return false - - ## if we already have a log - ## then just update its attrs from - ## the new log - if l = cmd.getLastLog() - l.merge(log) - - ## and make sure we return false - ## which prevents a new log from - ## being added - return false - else - insertNewLog(log) - - state("onBeforeLog", setCommandLog) - - ## send verify=true as the last arg - assertFn.apply(@, args.concat(true)) - - fns = injectAssertionFns(cmds) - - subjects = [] - - ## iterate through each subject - ## and force the assertion to return - ## this value so it does not get - ## invoked again - setSubjectAndSkip = -> - for subject, i in subjects - cmd = cmds[i] - cmd.set("subject", subject) - cmd.skip() - - assertions = (memo, fn, i) => - ## HACK: bluebird .reduce will not call the callback - ## if given an undefined initial value, so in order to - ## support undefined subjects, we wrap the initial value - ## in an Array and unwrap it if index = 0 - if i is 0 - memo = memo[0] - fn(memo).then (subject) -> - subjects[i] = subject - - restore = -> - state("upcomingAssertions", []) - - ## no matter what we need to - ## restore the assert fn - state("overrideAssert", undefined) - - ## store this in case our test ends early - ## and we reset between tests - state("overrideAssert", overrideAssert) - - Promise + .catch(onFailFn); + } + + let i = 0; + + const cmdHasFunctionArg = cmd => _.isFunction(cmd.get("args")[0]); + + const overrideAssert = function(...args) { + ((cmd) => { + const setCommandLog = log => { + //# our next log may not be an assertion + //# due to page events so make sure we wait + //# until we see page events + let l; + if (log.get("name") !== "assert") { return; } + + //# when we do immediately unbind this function + state("onBeforeLog", null); + + const insertNewLog = function(log) { + cmd.log(log); + return options.assertions.push(log); + }; + + //# its possible a single 'should' will assert multiple + //# things such as the case with have.property. we can + //# detect when that is happening because cmd will be null. + //# if thats the case then just set cmd to be the previous + //# cmd and do not increase 'i' + //# this will prevent 2 logs from ever showing up but still + //# provide errors when the 1st assertion fails. + if (!cmd) { + cmd = cmds[i - 1]; + } else { + i += 1; + } + + //# if our command has a function argument + //# then we know it may contain multiple + //# assertions + if (cmdHasFunctionArg(cmd)) { + let assertion; + let index = cmd.get("assertionIndex"); + const assertions = cmd.get("assertions"); + + const incrementIndex = () => //# always increase the assertionIndex + //# so our next assertion matches up + //# to the correct index + cmd.set("assertionIndex", index += 1); + + //# if we dont have an assertion at this + //# index then insert a new log + if (!(assertion = assertions[index])) { + assertions.push(log); + incrementIndex(); + + return insertNewLog(log); + } else { + //# else just merge this log + //# into the previous assertion log + incrementIndex(); + assertion.merge(log); + + //# dont output a new log + return false; + } + } + + //# if we already have a log + //# then just update its attrs from + //# the new log + if (l = cmd.getLastLog()) { + l.merge(log); + + //# and make sure we return false + //# which prevents a new log from + //# being added + return false; + } else { + return insertNewLog(log); + } + }; + + return state("onBeforeLog", setCommandLog); + })(cmds[i]); + + //# send verify=true as the last arg + return assertFn.apply(this, args.concat(true)); + }; + + const fns = injectAssertionFns(cmds); + + const subjects = []; + + //# iterate through each subject + //# and force the assertion to return + //# this value so it does not get + //# invoked again + const setSubjectAndSkip = () => (() => { + const result = []; + for (i = 0; i < subjects.length; i++) { + subject = subjects[i]; + const cmd = cmds[i]; + cmd.set("subject", subject); + result.push(cmd.skip()); + } + return result; + })(); + + const assertions = (memo, fn, i) => { + //# HACK: bluebird .reduce will not call the callback + //# if given an undefined initial value, so in order to + //# support undefined subjects, we wrap the initial value + //# in an Array and unwrap it if index = 0 + if (i === 0) { + memo = memo[0]; + } + return fn(memo).then(subject => subjects[i] = subject); + }; + + const restore = function() { + state("upcomingAssertions", []); + + //# no matter what we need to + //# restore the assert fn + return state("overrideAssert", undefined); + }; + + //# store this in case our test ends early + //# and we reset between tests + state("overrideAssert", overrideAssert); + + return Promise .reduce(fns, assertions, [subject]) - .then -> - restore() - - setSubjectAndSkip() - - finishAssertions(options.assertions) - - onPassFn() - .catch (err) -> - restore() - - ## when we're told not to retry - if err.retry is false - ## finish the assertions - finishAssertions(options.assertions) - - ## and then push our command into this err - try - $utils.throwErr(err, { onFail: options._log }) - catch e - err = e - - throw err - .catch(onFailFn) - - assertFn = (passed, message, value, actual, expected, error, verifying = false) -> - ## slice off everything after a ', but' or ' but ' for passing assertions, because - ## otherwise it doesn't make sense: - ## "expected
to have a an attribute 'href', but it was 'href'" - if message and passed and butRe.test(message) - message = message.substring(0, message.search(butRe)) - - if value?.isSinonProxy - message = message.replace(stackTracesRe, "\n") - - obj = parseValueActualAndExpected(value, actual, expected) - - if $dom.isElement(value) - obj.$el = $dom.wrap(value) - - current = state("current") - - ## if we are simply verifying the upcoming - ## assertions then do not immediately end or snapshot - ## else do - if verifying - obj._error = error - else - obj.end = true - obj.snapshot = true - obj.error = error - - isChildLike = (subject, current) => - (value is subject) or - isDomSubjectAndMatchesValue(value, subject) or - ## if our current command is an assertion type - isAssertionType(current) or - ## are we currently verifying assertions? - state("upcomingAssertions")?.length > 0 or - ## did the function have arguments - functionHadArguments(current) - - _.extend obj, - name: "assert" - # end: true - # snapshot: true - message: message - passed: passed - selector: value?.selector - type: (current, subject) -> - ## if our current command has arguments assume - ## we are an assertion that's involving the current - ## subject or our value is the current subject - if isChildLike(subject, current) - "child" - else - "parent" - - consoleProps: => - obj = {Command: "assert"} - - _.extend obj, parseValueActualAndExpected(value, actual, expected) - - _.extend obj, - Message: message.replace(bTagOpen, "").replace(bTagClosed, "") - - ## think about completely gutting the whole object toString - ## which chai does by default, its so ugly and worthless - - if error - error.onFail = (err) -> - - Cypress.log(obj) - - return null - - assert = -> - ## if we've temporarily overriden assertions - ## then just bail early with this function - fn = state("overrideAssert") ? assertFn - fn.apply(@, arguments) + .then(function() { + restore(); + + setSubjectAndSkip(); + + finishAssertions(options.assertions); + + return onPassFn();}).catch(function(err) { + restore(); + + //# when we're told not to retry + if (err.retry === false) { + //# finish the assertions + finishAssertions(options.assertions); + + //# and then push our command into this err + try { + $utils.throwErr(err, { onFail: options._log }); + } catch (e) { + err = e; + } + } + + throw err;}).catch(onFailFn); + }; + + var assertFn = function(passed, message, value, actual, expected, error, verifying = false) { + //# slice off everything after a ', but' or ' but ' for passing assertions, because + //# otherwise it doesn't make sense: + //# "expected
to have a an attribute 'href', but it was 'href'" + if (message && passed && butRe.test(message)) { + message = message.substring(0, message.search(butRe)); + } + + if (value != null ? value.isSinonProxy : undefined) { + message = message.replace(stackTracesRe, "\n"); + } + + let obj = parseValueActualAndExpected(value, actual, expected); + + if ($dom.isElement(value)) { + obj.$el = $dom.wrap(value); + } + + const current = state("current"); + + //# if we are simply verifying the upcoming + //# assertions then do not immediately end or snapshot + //# else do + if (verifying) { + obj._error = error; + } else { + obj.end = true; + obj.snapshot = true; + obj.error = error; + } + + const isChildLike = (subject, current) => { + return (value === subject) || + isDomSubjectAndMatchesValue(value, subject) || + //# if our current command is an assertion type + isAssertionType(current) || + //# are we currently verifying assertions? + (__guard__(state("upcomingAssertions"), x => x.length) > 0) || + //# did the function have arguments + functionHadArguments(current); + }; + + _.extend(obj, { + name: "assert", + // end: true + // snapshot: true + message, + passed, + selector: (value != null ? value.selector : undefined), + type(current, subject) { + //# if our current command has arguments assume + //# we are an assertion that's involving the current + //# subject or our value is the current subject + if (isChildLike(subject, current)) { + return "child"; + } else { + return "parent"; + } + }, + + consoleProps: () => { + obj = {Command: "assert"}; + + _.extend(obj, parseValueActualAndExpected(value, actual, expected)); + + return _.extend(obj, + {Message: message.replace(bTagOpen, "").replace(bTagClosed, "")}); + } + } + ); + + //# think about completely gutting the whole object toString + //# which chai does by default, its so ugly and worthless + + if (error) { + error.onFail = function(err) {}; + } + + Cypress.log(obj); + + return null; + }; + + const assert = function() { + //# if we've temporarily overriden assertions + //# then just bail early with this function + let left; + const fn = (left = state("overrideAssert")) != null ? left : assertFn; + return fn.apply(this, arguments); + }; return { - finishAssertions + finishAssertions, - verifyUpcomingAssertions + verifyUpcomingAssertions, assert - } + }; +}; module.exports = { create -} +}; + +function __guard__(value, transform) { + return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; +} \ No newline at end of file diff --git a/packages/driver/src/cypress/chai_jquery.js b/packages/driver/src/cypress/chai_jquery.js index 5fcc3c70c576..9c9debeb4216 100644 --- a/packages/driver/src/cypress/chai_jquery.js +++ b/packages/driver/src/cypress/chai_jquery.js @@ -1,273 +1,300 @@ -_ = require("lodash") -$ = require("jquery") -$dom = require("../dom") - -selectors = { - visible: "visible" - hidden: "hidden" - selected: "selected" - checked: "checked" - enabled: "enabled" - disabled: "disabled" - focus: "focused" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const _ = require("lodash"); +const $ = require("jquery"); +const $dom = require("../dom"); + +const selectors = { + visible: "visible", + hidden: "hidden", + selected: "selected", + checked: "checked", + enabled: "enabled", + disabled: "disabled", + focus: "focused", focused: "focused" -} +}; -attrs = { - attr: "attribute" - css: "CSS property" +const attrs = { + attr: "attribute", + css: "CSS property", prop: "property" -} - -wrap = (ctx) -> - ## reset the obj under test - ## to be re-wrapped in our own - ## jquery, so we can control - ## the methods on it - $(ctx._obj) - -$chaiJquery = (chai, chaiUtils, callbacks = {}) -> - { inspect, flag } = chaiUtils - - assertDom = (ctx, method, args...) -> - if not $dom.isDom(ctx._obj) - try - ## always fail the assertion - ## if we aren't a DOM like object - ctx.assert(false, args...) - catch err - callbacks.onInvalid(method, ctx._obj) - - assert = (ctx, method, bool, args...) -> - assertDom(ctx, method, args...) - - try - # ## reset obj to wrapped - orig = ctx._obj - ctx._obj = wrap(ctx) - - if ctx._obj.length is 0 - ctx._obj = ctx._obj.selector - - ## apply the assertion - ret = ctx.assert(bool, args...) - ctx._obj = orig - return ret - catch err - ## send it up with the obj and whether it was negated - callbacks.onError(err, method, ctx._obj, flag(ctx, "negate")) - - assertPartial = (ctx, method, actual, expected, message, notMessage, args...) -> - if ctx.__flags.contains or ctx.__flags.includes +}; + +const wrap = ctx => //# reset the obj under test +//# to be re-wrapped in our own +//# jquery, so we can control +//# the methods on it +$(ctx._obj); + +const $chaiJquery = function(chai, chaiUtils, callbacks = {}) { + const { inspect, flag } = chaiUtils; + + const assertDom = function(ctx, method, ...args) { + if (!$dom.isDom(ctx._obj)) { + try { + //# always fail the assertion + //# if we aren't a DOM like object + return ctx.assert(false, ...args); + } catch (err) { + return callbacks.onInvalid(method, ctx._obj); + } + } + }; + + const assert = function(ctx, method, bool, ...args) { + assertDom(ctx, method, ...args); + + try { + // ## reset obj to wrapped + const orig = ctx._obj; + ctx._obj = wrap(ctx); + + if (ctx._obj.length === 0) { + ctx._obj = ctx._obj.selector; + } + + //# apply the assertion + const ret = ctx.assert(bool, ...args); + ctx._obj = orig; + return ret; + } catch (err) { + //# send it up with the obj and whether it was negated + return callbacks.onError(err, method, ctx._obj, flag(ctx, "negate")); + } + }; + + const assertPartial = function(ctx, method, actual, expected, message, notMessage, ...args) { + if (ctx.__flags.contains || ctx.__flags.includes) { return assert( - ctx - method + ctx, + method, _.includes(actual, expected), - 'expected #{this}'+ ' to contain ' + message - 'expected #{this}'+ ' not to contain ' + notMessage - args... - ) + "expected #{this} to contain " + message, + "expected #{this} not to contain " + notMessage, + ...args + ); + } return assert( - ctx - method - actual is expected - 'expected #{this}'+ ' to have ' + message - 'expected #{this}'+ ' not to have ' + notMessage - args... - ) - chai.Assertion.addMethod "data", -> - assertDom(@, "data") - - a = new chai.Assertion(wrap(@).data()) - - if flag(@, "negate") - a = a.not - - a.property.apply(a, arguments) - - chai.Assertion.addMethod "class", (className) -> - assert( - @, + ctx, + method, + actual === expected, + "expected #{this} to have " + message, + "expected #{this} not to have " + notMessage, + ...args + ); + }; + chai.Assertion.addMethod("data", function() { + assertDom(this, "data"); + + let a = new chai.Assertion(wrap(this).data()); + + if (flag(this, "negate")) { + a = a.not; + } + + return a.property.apply(a, arguments); + }); + + chai.Assertion.addMethod("class", function(className) { + return assert( + this, "class", - wrap(@).hasClass(className), + wrap(this).hasClass(className), 'expected #{this} to have class #{exp}', 'expected #{this} not to have class #{exp}', className - ) + ); + }); - chai.Assertion.addMethod "id", (id) -> - assert( - @, + chai.Assertion.addMethod("id", function(id) { + return assert( + this, "id", - wrap(@).prop("id") is id, + wrap(this).prop("id") === id, 'expected #{this} to have id #{exp}', 'expected #{this} not to have id #{exp}', id - ) + ); + }); - chai.Assertion.addMethod "html", (html) -> + chai.Assertion.addMethod("html", function(html) { assertDom( - @, + this, "html", 'expected #{this} to have HTML #{exp}', 'expected #{this} not to have HTML #{exp}', html - ) + ); - actual = wrap(@).html() + const actual = wrap(this).html(); - assertPartial( - @, + return assertPartial( + this, "html", - actual - html + actual, + html, 'HTML #{exp}, but the HTML was #{act}', 'HTML #{exp}', html, actual - ) + ); + }); - chai.Assertion.addMethod "text", (text) -> + chai.Assertion.addMethod("text", function(text) { assertDom( - @, + this, "text", 'expected #{this} to have text #{exp}', 'expected #{this} not to have text #{exp}', text - ) + ); - actual = wrap(@).text() + const actual = wrap(this).text(); - assertPartial( - @, + return assertPartial( + this, "text", - actual - text + actual, + text, 'text #{exp}, but the text was #{act}', 'text #{exp}', text, actual - ) + ); + }); - chai.Assertion.addMethod "value", (value) -> + chai.Assertion.addMethod("value", function(value) { assertDom( - @, + this, "value", 'expected #{this} to have value #{exp}', 'expected #{this} not to have value #{exp}', value - ) + ); - actual = wrap(@).val() + const actual = wrap(this).val(); - assertPartial( - @, + return assertPartial( + this, "value", - actual - value + actual, + value, 'value #{exp}, but the value was #{act}', 'value #{exp}', value, actual - ) + ); + }); - chai.Assertion.addMethod "descendants", (selector) -> - assert( - @, + chai.Assertion.addMethod("descendants", function(selector) { + return assert( + this, "descendants", - wrap(@).has(selector).length > 0, + wrap(this).has(selector).length > 0, 'expected #{this} to have descendants #{exp}', 'expected #{this} not to have descendants #{exp}', selector - ) - - chai.Assertion.overwriteProperty "empty", (_super) -> - return -> - if $dom.isDom(@_obj) - assert( - @, - "empty", - wrap(@).is(":empty"), - 'expected #{this} to be #{exp}', - 'expected #{this} not to be #{exp}', - "empty" - ) - else - _super.apply(@, arguments) - - chai.Assertion.overwriteMethod "match", (_super) -> - return (selector) -> - if $dom.isDom(@_obj) - assert( - @, - "match", - wrap(@).is(selector), - 'expected #{this} to match #{exp}', - 'expected #{this} not to match #{exp}', - selector - ) - else - _super.apply(@, arguments) - - _.each selectors, (selectorName, selector) -> - chai.Assertion.addProperty selector, -> - assert( - @, - selector, - wrap(@).is(":" + selector), + ); + }); + + chai.Assertion.overwriteProperty("empty", _super => (function() { + if ($dom.isDom(this._obj)) { + return assert( + this, + "empty", + wrap(this).is(":empty"), 'expected #{this} to be #{exp}', 'expected #{this} not to be #{exp}', - selectorName - ) + "empty" + ); + } else { + return _super.apply(this, arguments); + } + })); + + chai.Assertion.overwriteMethod("match", _super => (function(selector) { + if ($dom.isDom(this._obj)) { + return assert( + this, + "match", + wrap(this).is(selector), + 'expected #{this} to match #{exp}', + 'expected #{this} not to match #{exp}', + selector + ); + } else { + return _super.apply(this, arguments); + } + })); + + _.each(selectors, (selectorName, selector) => chai.Assertion.addProperty(selector, function() { + return assert( + this, + selector, + wrap(this).is(":" + selector), + 'expected #{this} to be #{exp}', + 'expected #{this} not to be #{exp}', + selectorName + ); + })); + + return _.each(attrs, (description, attr) => chai.Assertion.addMethod(attr, function(name, val) { + assertDom( + this, + attr, + 'expected #{this} to have ' + description + ' #{exp}', + 'expected #{this} not to have ' + description + ' #{exp}', + name + ); - _.each attrs, (description, attr) -> - chai.Assertion.addMethod attr, (name, val) -> - assertDom( - @, + const actual = wrap(this)[attr](name); + + //# when we only have 1 argument dont worry about val + if (arguments.length === 1) { + assert( + this, attr, + actual !== undefined, 'expected #{this} to have ' + description + ' #{exp}', 'expected #{this} not to have ' + description + ' #{exp}', name - ) - - actual = wrap(@)[attr](name) - - ## when we only have 1 argument dont worry about val - if arguments.length is 1 - assert( - @, - attr, - actual != undefined, - 'expected #{this} to have ' + description + ' #{exp}', - 'expected #{this} not to have ' + description + ' #{exp}', - name - ) - - ## change the subject - @_obj = actual - - else - ## if we don't have an attribute here at all we need to - ## have a different failure message - if _.isUndefined(actual) - message = "expected \#{this} to have #{description} #{inspect(name)}" - - negatedMessage = "expected \#{this} not to have #{description} #{inspect(name)}" - else - message = "expected \#{this} to have #{description} #{inspect(name)} with the value \#{exp}, but the value was \#{act}" - - negatedMessage = "expected \#{this} not to have #{description} #{inspect(name)} with the value \#{exp}, but the value was \#{act}" - - assert( - @, - attr, - actual? and actual is val, - message, - negatedMessage, - val, - actual - ) - - return @ - -module.exports = $chaiJquery + ); + + //# change the subject + this._obj = actual; + + } else { + //# if we don't have an attribute here at all we need to + //# have a different failure message + let message, negatedMessage; + if (_.isUndefined(actual)) { + message = `expected \#{this} to have ${description} ${inspect(name)}`; + + negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)}`; + } else { + message = `expected \#{this} to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}`; + + negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}`; + } + + assert( + this, + attr, + (actual != null) && (actual === val), + message, + negatedMessage, + val, + actual + ); + } + + return this; + })); +}; + +module.exports = $chaiJquery; diff --git a/packages/driver/src/cypress/mocha.js b/packages/driver/src/cypress/mocha.js index 21df770d7629..b763849b33fb 100644 --- a/packages/driver/src/cypress/mocha.js +++ b/packages/driver/src/cypress/mocha.js @@ -1,203 +1,228 @@ -_ = require("lodash") -$utils = require("./utils") - -## in the browser mocha is coming back -## as window -mocha = require("mocha") - -Mocha = mocha.Mocha ? mocha -Test = Mocha.Test -Runner = Mocha.Runner -Runnable = Mocha.Runnable - -runnerRun = Runner::run -runnerFail = Runner::fail -runnableRun = Runnable::run -runnableClearTimeout = Runnable::clearTimeout -runnableResetTimeout = Runnable::resetTimeout - -## don't let mocha polute the global namespace -delete window.mocha -delete window.Mocha - -ui = (specWindow, _mocha) -> - ## Override mocha.ui so that the pre-require event is emitted - ## with the iframe's `window` reference, rather than the parent's. - _mocha.ui = (name) -> - @_ui = Mocha.interfaces[name] - - if not @_ui - $utils.throwErrByPath("mocha.invalid_interface", { args: { name } }) - - @_ui = @_ui(@suite) - - ## this causes the mocha globals in the spec window to be defined - ## such as describe, it, before, beforeEach, etc - @suite.emit("pre-require", specWindow, null, @) - - return @ - - _mocha.ui("bdd") - -set = (specWindow, _mocha) -> - ## Mocha is usually defined in the spec when used normally - ## in the browser or node, so we add it as a global - ## for our users too - M = specWindow.Mocha = Mocha - m = specWindow.mocha = _mocha - - ## also attach the Mocha class - ## to the mocha instance for clarity - m.Mocha = M - - ## this needs to be part of the configuration of cypress.json - ## we can't just forcibly use bdd - ui(specWindow, _mocha) - -globals = (specWindow, reporter) -> - reporter ?= -> - - _mocha = new Mocha({ - reporter: reporter +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const _ = require("lodash"); +const $utils = require("./utils"); + +//# in the browser mocha is coming back +//# as window +const mocha = require("mocha"); + +const Mocha = mocha.Mocha != null ? mocha.Mocha : mocha; +const { + Test +} = Mocha; +const { + Runner +} = Mocha; +const { + Runnable +} = Mocha; + +const runnerRun = Runner.prototype.run; +const runnerFail = Runner.prototype.fail; +const runnableRun = Runnable.prototype.run; +const runnableClearTimeout = Runnable.prototype.clearTimeout; +const runnableResetTimeout = Runnable.prototype.resetTimeout; + +//# don't let mocha polute the global namespace +delete window.mocha; +delete window.Mocha; + +const ui = function(specWindow, _mocha) { + //# Override mocha.ui so that the pre-require event is emitted + //# with the iframe's `window` reference, rather than the parent's. + _mocha.ui = function(name) { + this._ui = Mocha.interfaces[name]; + + if (!this._ui) { + $utils.throwErrByPath("mocha.invalid_interface", { args: { name } }); + } + + this._ui = this._ui(this.suite); + + //# this causes the mocha globals in the spec window to be defined + //# such as describe, it, before, beforeEach, etc + this.suite.emit("pre-require", specWindow, null, this); + + return this; + }; + + return _mocha.ui("bdd"); +}; + +const set = function(specWindow, _mocha) { + //# Mocha is usually defined in the spec when used normally + //# in the browser or node, so we add it as a global + //# for our users too + const M = (specWindow.Mocha = Mocha); + const m = (specWindow.mocha = _mocha); + + //# also attach the Mocha class + //# to the mocha instance for clarity + m.Mocha = M; + + //# this needs to be part of the configuration of cypress.json + //# we can't just forcibly use bdd + return ui(specWindow, _mocha); +}; + +const globals = function(specWindow, reporter) { + if (reporter == null) { reporter = function() {}; } + + const _mocha = new Mocha({ + reporter, enableTimeouts: false - }) + }); - ## set mocha props on the specWindow - set(specWindow, _mocha) + //# set mocha props on the specWindow + set(specWindow, _mocha); - ## return the newly created mocha instance - return _mocha + //# return the newly created mocha instance + return _mocha; +}; -getRunner = (_mocha) -> - Runner::run = -> - ## reset our runner#run function - ## so the next time we call it - ## its normal again! - restoreRunnerRun() +const getRunner = function(_mocha) { + Runner.prototype.run = function() { + //# reset our runner#run function + //# so the next time we call it + //# its normal again! + restoreRunnerRun(); - ## return the runner instance - return @ + //# return the runner instance + return this; + }; - _mocha.run() + return _mocha.run(); +}; -restoreRunnableClearTimeout = -> - Runnable::clearTimeout = runnableClearTimeout +const restoreRunnableClearTimeout = () => Runnable.prototype.clearTimeout = runnableClearTimeout; -restoreRunnableResetTimeout = -> - Runnable::resetTimeout = runnableResetTimeout +const restoreRunnableResetTimeout = () => Runnable.prototype.resetTimeout = runnableResetTimeout; -restoreRunnerRun = -> - Runner::run = runnerRun +var restoreRunnerRun = () => Runner.prototype.run = runnerRun; -restoreRunnerFail = -> - Runner::fail = runnerFail +const restoreRunnerFail = () => Runner.prototype.fail = runnerFail; -restoreRunnableRun = -> - Runnable::run = runnableRun +const restoreRunnableRun = () => Runnable.prototype.run = runnableRun; -patchRunnerFail = -> - ## matching the current Runner.prototype.fail except - ## changing the logic for determing whether this is a valid err - Runner::fail = (runnable, err) -> - ## if this isnt a correct error object then just bail - ## and call the original function - if Object.prototype.toString.call(err) isnt "[object Error]" - return runnerFail.call(@, runnable, err) +const patchRunnerFail = () => //# matching the current Runner.prototype.fail except +//# changing the logic for determing whether this is a valid err +Runner.prototype.fail = function(runnable, err) { + //# if this isnt a correct error object then just bail + //# and call the original function + if (Object.prototype.toString.call(err) !== "[object Error]") { + return runnerFail.call(this, runnable, err); + } - ## else replicate the normal mocha functionality - ++@failures + //# else replicate the normal mocha functionality + ++this.failures; - runnable.state = "failed" + runnable.state = "failed"; - @emit("fail", runnable, err) + return this.emit("fail", runnable, err); +}; -patchRunnableRun = (Cypress) -> - Runnable::run = (args...) -> - runnable = @ +const patchRunnableRun = Cypress => Runnable.prototype.run = function(...args) { + const runnable = this; - Cypress.action("mocha:runnable:run", runnableRun, runnable, args) + return Cypress.action("mocha:runnable:run", runnableRun, runnable, args); +}; -patchRunnableClearTimeout = -> - Runnable::clearTimeout = -> - ## call the original - runnableClearTimeout.apply(@, arguments) +const patchRunnableClearTimeout = () => Runnable.prototype.clearTimeout = function() { + //# call the original + runnableClearTimeout.apply(this, arguments); - ## nuke the timer property - ## for testing purposes - @timer = null + //# nuke the timer property + //# for testing purposes + return this.timer = null; +}; -patchRunnableResetTimeout = -> - Runnable::resetTimeout = -> - runnable = @ +const patchRunnableResetTimeout = () => Runnable.prototype.resetTimeout = function() { + const runnable = this; - ms = @timeout() or 1e9 + const ms = this.timeout() || 1e9; - @clearTimeout() + this.clearTimeout(); - getErrPath = -> - ## we've yield an explicit done callback - if runnable.async - "mocha.async_timed_out" - else - ## TODO: improve this error message. It's not that - ## a command necessarily timed out - in fact this is - ## a mocha timeout, and a command likely *didn't* - ## time out correctly, so we received this message instead. - "mocha.timed_out" + const getErrPath = function() { + //# we've yield an explicit done callback + if (runnable.async) { + return "mocha.async_timed_out"; + } else { + //# TODO: improve this error message. It's not that + //# a command necessarily timed out - in fact this is + //# a mocha timeout, and a command likely *didn't* + //# time out correctly, so we received this message instead. + return "mocha.timed_out"; + } + }; - @timer = setTimeout -> - errMessage = $utils.errMessageByPath(getErrPath(), { ms }) - runnable.callback new Error(errMessage) - runnable.timedOut = true - , ms + return this.timer = setTimeout(function() { + const errMessage = $utils.errMessageByPath(getErrPath(), { ms }); + runnable.callback(new Error(errMessage)); + return runnable.timedOut = true; + } + , ms); +}; -restore = -> - restoreRunnerRun() - restoreRunnerFail() - restoreRunnableRun() - restoreRunnableClearTimeout() - restoreRunnableResetTimeout() +const restore = function() { + restoreRunnerRun(); + restoreRunnerFail(); + restoreRunnableRun(); + restoreRunnableClearTimeout(); + return restoreRunnableResetTimeout(); +}; -override = (Cypress) -> - patchRunnerFail() - patchRunnableRun(Cypress) - patchRunnableClearTimeout() - patchRunnableResetTimeout() +const override = function(Cypress) { + patchRunnerFail(); + patchRunnableRun(Cypress); + patchRunnableClearTimeout(); + return patchRunnableResetTimeout(); +}; -create = (specWindow, Cypress, reporter) -> - restore() +const create = function(specWindow, Cypress, reporter) { + restore(); - override(Cypress) + override(Cypress); - ## generate the mocha + Mocha globals - ## on the specWindow, and get the new - ## _mocha instance - _mocha = globals(specWindow, reporter) + //# generate the mocha + Mocha globals + //# on the specWindow, and get the new + //# _mocha instance + const _mocha = globals(specWindow, reporter); - _runner = getRunner(_mocha) + const _runner = getRunner(_mocha); return { - _mocha + _mocha, - createRootTest: (title, fn) -> - r = new Test(title, fn) - _runner.suite.addTest(r) - r + createRootTest(title, fn) { + const r = new Test(title, fn); + _runner.suite.addTest(r); + return r; + }, - getRunner: -> - _runner + getRunner() { + return _runner; + }, - getRootSuite: -> - _mocha.suite + getRootSuite() { + return _mocha.suite; + }, - options: (runner) -> - runner.options(_mocha.options) - } + options(runner) { + return runner.options(_mocha.options); + } + }; +}; module.exports = { - restore + restore, - globals + globals, create -} +}; diff --git a/packages/driver/test/cypress/integration/issues/510_spec.js b/packages/driver/test/cypress/integration/issues/510_spec.js index 46185a4e5c79..4d76f88d5ea4 100644 --- a/packages/driver/test/cypress/integration/issues/510_spec.js +++ b/packages/driver/test/cypress/integration/issues/510_spec.js @@ -1,7 +1,11 @@ -before -> - cy - .visit("http://localhost:3500/fixtures/jquery.html") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +before(() => cy + .visit("http://localhost:3500/fixtures/jquery.html")); -it "XHR should be available", -> +it("XHR should be available", function() {}); -it "XHR should be available2", -> +it("XHR should be available2", function() {}); diff --git a/packages/driver/test/cypress/integration/issues/565_spec.js b/packages/driver/test/cypress/integration/issues/565_spec.js index aad0ad374c91..a748991cd81a 100644 --- a/packages/driver/test/cypress/integration/issues/565_spec.js +++ b/packages/driver/test/cypress/integration/issues/565_spec.js @@ -1,9 +1,13 @@ -## https://github.com/cypress-io/cypress/issues/565 -describe "issue 565", -> - before -> - cy - .viewport(400, 400) - .visit("/fixtures/issue-565.html") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +//# https://github.com/cypress-io/cypress/issues/565 +describe("issue 565", function() { + before(() => cy + .viewport(400, 400) + .visit("/fixtures/issue-565.html")); - it "can click the first tr", -> - cy.get("td:first").click() + return it("can click the first tr", () => cy.get("td:first").click()); +}); diff --git a/packages/driver/test/cypress/integration/issues/573_spec.js b/packages/driver/test/cypress/integration/issues/573_spec.js index 6a3399977fa1..0b481ae6e727 100644 --- a/packages/driver/test/cypress/integration/issues/573_spec.js +++ b/packages/driver/test/cypress/integration/issues/573_spec.js @@ -1,49 +1,56 @@ -run = -> - cy.window() - .then { timeout: 60000 }, (win) -> - new Cypress.Promise (resolve) -> - i = win.document.createElement("iframe") - i.onload = resolve - i.src = "/basic_auth" - win.document.body.appendChild(i) - .get("iframe").should ($iframe) -> - expect($iframe.contents().text()).to.include("basic auth worked") - .window().then { timeout: 60000 }, (win) -> - new Cypress.Promise (resolve, reject) -> - xhr = new win.XMLHttpRequest() - xhr.open("GET", "/basic_auth") - xhr.onload = -> - try - expect(@responseText).to.include("basic auth worked") - resolve(win) - catch err - reject(err) - xhr.send() - .then { timeout: 60000 }, (win) -> - new Cypress.Promise (resolve, reject) -> - ## ensure other origins do not have auth headers attached - xhr = new win.XMLHttpRequest() - xhr.open("GET", "http://localhost:3501/basic_auth") - xhr.onload = -> - try - expect(@status).to.eq(401) - resolve(win) - catch err - reject(err) - xhr.send() +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const run = () => cy.window() +.then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve) { + const i = win.document.createElement("iframe"); + i.onload = resolve; + i.src = "/basic_auth"; + return win.document.body.appendChild(i); +})).get("iframe").should($iframe => expect($iframe.contents().text()).to.include("basic auth worked")).window().then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve, reject) { + const xhr = new win.XMLHttpRequest(); + xhr.open("GET", "/basic_auth"); + xhr.onload = function() { + try { + expect(this.responseText).to.include("basic auth worked"); + return resolve(win); + } catch (err) { + return reject(err); + } + }; + return xhr.send(); +})).then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve, reject) { + //# ensure other origins do not have auth headers attached + const xhr = new win.XMLHttpRequest(); + xhr.open("GET", "http://localhost:3501/basic_auth"); + xhr.onload = function() { + try { + expect(this.status).to.eq(401); + return resolve(win); + } catch (err) { + return reject(err); + } + }; + return xhr.send(); +})); -# cy.visit("http://admin:admin@the-internet.herokuapp.com/basic_auth") +// cy.visit("http://admin:admin@the-internet.herokuapp.com/basic_auth") -describe "basic auth", -> - it "can visit with username/pw in url", -> - cy.visit("http://cypress:password123@localhost:3500/basic_auth") - run() +describe("basic auth", function() { + it("can visit with username/pw in url", function() { + cy.visit("http://cypress:password123@localhost:3500/basic_auth"); + return run(); + }); - it "can visit with auth options", -> + return it("can visit with auth options", function() { cy.visit("http://localhost:3500/basic_auth", { auth: { - username: "cypress" + username: "cypress", password: "password123" } - }) - run() + }); + return run(); + }); +}); diff --git a/packages/driver/test/cypress/integration/issues/652_spec.js b/packages/driver/test/cypress/integration/issues/652_spec.js index 64b506695604..e290c23eea43 100644 --- a/packages/driver/test/cypress/integration/issues/652_spec.js +++ b/packages/driver/test/cypress/integration/issues/652_spec.js @@ -1,17 +1,23 @@ -## https://github.com/cypress-io/cypress/issues/652 -describe "issue 652", -> - before -> - cy.visit("/fixtures/issue-652.html") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +//# https://github.com/cypress-io/cypress/issues/652 +describe("issue 652", function() { + before(() => cy.visit("/fixtures/issue-652.html")); - it 'should visit all the hashes', -> - # cy.wait(0) - cy.visit('/fixtures/issue-652.html#one') - # cy.wait(0) - cy.visit('/fixtures/issue-652.html#two') - # cy.wait(0) - cy.visit('/fixtures/issue-652.html#three') + return it('should visit all the hashes', function() { + // cy.wait(0) + cy.visit('/fixtures/issue-652.html#one'); + // cy.wait(0) + cy.visit('/fixtures/issue-652.html#two'); + // cy.wait(0) + cy.visit('/fixtures/issue-652.html#three'); - cy.get('#visited') + return cy.get('#visited') .should('contain', 'one') .should('contain', 'two') - .should('contain', 'three') + .should('contain', 'three'); + }); +}); From a5877ce45a7bea37857cd6abdaf05bea0b8e829c Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Wed, 1 Jan 2020 15:52:06 +0900 Subject: [PATCH 3/3] decaffeinate: Run post-processing cleanups on assertions.coffee and 6 other files --- packages/driver/src/cy/assertions.js | 733 +++++++++--------- packages/driver/src/cypress/chai_jquery.js | 373 ++++----- packages/driver/src/cypress/mocha.js | 347 +++++---- .../cypress/integration/issues/510_spec.js | 14 +- .../cypress/integration/issues/565_spec.js | 21 +- .../cypress/integration/issues/573_spec.js | 120 +-- .../cypress/integration/issues/652_spec.js | 33 +- 7 files changed, 841 insertions(+), 800 deletions(-) diff --git a/packages/driver/src/cy/assertions.js b/packages/driver/src/cy/assertions.js index 0880aa86333d..0e5a613d02c4 100644 --- a/packages/driver/src/cy/assertions.js +++ b/packages/driver/src/cy/assertions.js @@ -1,494 +1,511 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS103: Rewrite code to no longer use __guard__ - * DS104: Avoid inline assignments - * DS205: Consider reworking code to avoid use of IIFEs - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const _ = require("lodash"); -const Promise = require("bluebird"); - -const $dom = require("../dom"); -const $utils = require("../cypress/utils"); - -//# TODO -//# bTagOpen + bTagClosed -//# are duplicated in assertions.coffee -const butRe = /,? but\b/; -const bTagOpen = /\*\*/g; -const bTagClosed = /\*\*/g; -const stackTracesRe = / at .*\n/gm; - -const IS_DOM_TYPES = [$dom.isElement, $dom.isDocument, $dom.isWindow]; - -const invokeWith = value => fn => fn(value); - -const functionHadArguments = function(current) { - const fn = current && current.get("args") && current.get("args")[0]; - return fn && _.isFunction(fn) && (fn.length > 0); -}; - -const isAssertionType = cmd => cmd && cmd.is("assertion"); - -const isDomSubjectAndMatchesValue = function(value, subject) { - let isDomTypeFn; - const allElsAreTheSame = function() { - const els1 = $dom.getElements(value); - const els2 = $dom.getElements(subject); - - //# no difference - return _.difference(els1, els2).length === 0; - }; - - //# iterate through each dom type until we - //# find the function for this particular value - if (isDomTypeFn = _.find(IS_DOM_TYPES, invokeWith(value))) { - //# then check that subject also matches this - //# and that all the els are the same - return isDomTypeFn(subject) && allElsAreTheSame(); +/* global cy Cypress */ +const _ = require('lodash') +const Promise = require('bluebird') + +const $dom = require('../dom') +const $utils = require('../cypress/utils') + +// TODO +// bTagOpen + bTagClosed +// are duplicated in assertions.coffee +const butRe = /,? but\b/ +const bTagOpen = /\*\*/g +const bTagClosed = /\*\*/g +const stackTracesRe = / at .*\n/gm + +const IS_DOM_TYPES = [$dom.isElement, $dom.isDocument, $dom.isWindow] + +const invokeWith = (value) => { + return (fn) => { + return fn(value) } -}; +} -//# Rules: -//# 1. always remove value -//# 2. if value is a jquery object set a subject -//# 3. if actual is undefined or its not expected remove both actual + expected -const parseValueActualAndExpected = function(value, actual, expected) { - const obj = {actual, expected}; +const functionHadArguments = (current) => { + const fn = current && current.get('args') && current.get('args')[0] + + return fn && _.isFunction(fn) && (fn.length > 0) +} + +const isAssertionType = (cmd) => { + return cmd && cmd.is('assertion') +} + +const isDomSubjectAndMatchesValue = (value, subject) => { + const allElsAreTheSame = () => { + const els1 = $dom.getElements(value) + const els2 = $dom.getElements(subject) + + // no difference + return _.difference(els1, els2).length === 0 + } + + // iterate through each dom type until we + // find the function for this particular value + const isDomTypeFn = _.find(IS_DOM_TYPES, invokeWith(value)) + + if (isDomTypeFn) { + // then check that subject also matches this + // and that all the els are the same + return isDomTypeFn(subject) && allElsAreTheSame() + } +} + +// Rules: +// 1. always remove value +// 2. if value is a jquery object set a subject +// 3. if actual is undefined or its not expected remove both actual + expected +const parseValueActualAndExpected = (value, actual, expected) => { + const obj = { actual, expected } if ($dom.isJquery(value)) { - obj.subject = value; + obj.subject = value if (_.isUndefined(actual) || (actual !== expected)) { - delete obj.actual; - delete obj.expected; + delete obj.actual + delete obj.expected } } - return obj; -}; + return obj +} -const create = function(state, queue, retryFn) { - const getUpcomingAssertions = function() { - const current = state("current"); - const index = state("index") + 1; +const create = function (state, queue, retryFn) { + const getUpcomingAssertions = () => { + const index = state('index') + 1 - const assertions = []; + const assertions = [] - //# grab the rest of the queue'd commands + // grab the rest of the queue'd commands for (let cmd of queue.slice(index).get()) { - //# don't break on utilities, just skip over them - if (cmd.is("utility")) { - continue; + // don't break on utilities, just skip over them + if (cmd.is('utility')) { + continue } - //# grab all of the queued commands which are - //# assertions and match our current chainerId - if (cmd.is("assertion")) { - assertions.push(cmd); + // grab all of the queued commands which are + // assertions and match our current chainerId + if (cmd.is('assertion')) { + assertions.push(cmd) } else { - break; + break } } - return assertions; - }; + return assertions + } + + const injectAssertionFns = (cmds) => { + return _.map(cmds, injectAssertion) + } - const injectAssertionFns = cmds => _.map(cmds, injectAssertion); + const injectAssertion = (cmd) => { + return ((subject) => { + // set assertions to itself or empty array + if (!cmd.get('assertions')) { + cmd.set('assertions', []) + } - var injectAssertion = cmd => (function(subject) { - //# set assertions to itself or empty array - if (!cmd.get("assertions")) { - cmd.set("assertions", []); - } + // reset the assertion index back to 0 + // so we can track assertions and merge + // them up with existing ones + cmd.set('assertionIndex', 0) + + return cmd.get('fn').originalFn.apply( + state('ctx'), + [subject].concat(cmd.get('args')) + ) + }) + } - //# reset the assertion index back to 0 - //# so we can track assertions and merge - //# them up with existing ones - cmd.set("assertionIndex", 0); + const finishAssertions = (assertions) => { + return _.each(assertions, (log) => { + log.snapshot() - return cmd.get("fn").originalFn.apply( - state("ctx"), - [subject].concat(cmd.get("args")) - ); - }); + const e = log.get('_error') - const finishAssertions = assertions => _.each(assertions, function(log) { - let e; - log.snapshot(); + if (e) { + return log.error(e) + } - if ((e = log.get("_error"))) { - return log.error(e); - } else { - return log.end(); - } - }); + return log.end() + }) + } - const verifyUpcomingAssertions = function(subject, options = {}, callbacks = {}) { - const cmds = getUpcomingAssertions(); + const verifyUpcomingAssertions = function (subject, options = {}, callbacks = {}) { + const cmds = getUpcomingAssertions() - state("upcomingAssertions", cmds); + state('upcomingAssertions', cmds) - //# we're applying the default assertion in the - //# case where there are no upcoming assertion commands - const isDefaultAssertionErr = cmds.length === 0; + // we're applying the default assertion in the + // case where there are no upcoming assertion commands + const isDefaultAssertionErr = cmds.length === 0 - if (options.assertions == null) { options.assertions = []; } + if (options.assertions == null) { + options.assertions = [] + } _.defaults(callbacks, { - ensureExistenceFor: "dom" - }); + ensureExistenceFor: 'dom', + }) - const ensureExistence = function() { - //# by default, ensure existence for dom subjects, - //# but not non-dom subjects + const ensureExistence = () => { + // by default, ensure existence for dom subjects, + // but not non-dom subjects switch (callbacks.ensureExistenceFor) { - case "dom": - var $el = determineEl(options.$el, subject); - if (!$dom.isJquery($el)) { return; } + case 'dom': { + const $el = determineEl(options.$el, subject) + + if (!$dom.isJquery($el)) { + return + } + + return cy.ensureElExistence($el) + } + case 'subject': + return cy.ensureExistence(subject) - return cy.ensureElExistence($el); + default: + return + } + } - case "subject": - return cy.ensureExistence(subject); + const determineEl = ($el, subject) => { + // prefer $el unless it is strickly undefined + if (!_.isUndefined($el)) { + return $el } - }; - var determineEl = function($el, subject) { - //# prefer $el unless it is strickly undefined - if (!_.isUndefined($el)) { return $el; } else { return subject; } - }; + return subject + } const onPassFn = () => { if (_.isFunction(callbacks.onPass)) { - return callbacks.onPass.call(this, cmds, options.assertions); - } else { - return subject; + return callbacks.onPass.call(this, cmds, options.assertions) } - }; - - const onFailFn = err => { - //# when we fail for whatever reason we need to - //# check to see if we would firstly fail if - //# we don't have an el in existence. what this - //# catches are assertions downstream about an - //# elements existence but the element never - //# exists in the first place. this will probably - //# ensure the error is about existence not about - //# the downstream assertion. + + return subject + } + + const onFailFn = (err) => { + // when we fail for whatever reason we need to + // check to see if we would firstly fail if + // we don't have an el in existence. what this + // catches are assertions downstream about an + // elements existence but the element never + // exists in the first place. this will probably + // ensure the error is about existence not about + // the downstream assertion. try { - ensureExistence(); + ensureExistence() } catch (e2) { - err = e2; + err = e2 } - options.error = err; + options.error = err if (err.retry === false) { - throw err; + throw err } - const { - onFail - } = callbacks; - const { - onRetry - } = callbacks; + const { onFail, onRetry } = callbacks if (!onFail && !onRetry) { - throw err; + throw err } - //# if our onFail throws then capture it - //# and finish the assertions and then throw - //# it again + // if our onFail throws then capture it + // and finish the assertions and then throw + // it again try { if (_.isFunction(onFail)) { - //# pass in the err and the upcoming assertion commands - onFail.call(this, err, isDefaultAssertionErr, cmds); + // pass in the err and the upcoming assertion commands + onFail.call(this, err, isDefaultAssertionErr, cmds) } } catch (e3) { - finishAssertions(options.assertions); - throw e3; + finishAssertions(options.assertions) + throw e3 } if (_.isFunction(onRetry)) { - return retryFn(onRetry, options); + return retryFn(onRetry, options) } - }; + } - //# bail if we have no assertions and apply - //# the default assertions if applicable + // bail if we have no assertions and apply + // the default assertions if applicable if (!cmds.length) { return Promise - .try(ensureExistence) - .then(onPassFn) - .catch(onFailFn); + .try(ensureExistence) + .then(onPassFn) + .catch(onFailFn) } - let i = 0; - - const cmdHasFunctionArg = cmd => _.isFunction(cmd.get("args")[0]); - - const overrideAssert = function(...args) { - ((cmd) => { - const setCommandLog = log => { - //# our next log may not be an assertion - //# due to page events so make sure we wait - //# until we see page events - let l; - if (log.get("name") !== "assert") { return; } - - //# when we do immediately unbind this function - state("onBeforeLog", null); - - const insertNewLog = function(log) { - cmd.log(log); - return options.assertions.push(log); - }; - - //# its possible a single 'should' will assert multiple - //# things such as the case with have.property. we can - //# detect when that is happening because cmd will be null. - //# if thats the case then just set cmd to be the previous - //# cmd and do not increase 'i' - //# this will prevent 2 logs from ever showing up but still - //# provide errors when the 1st assertion fails. - if (!cmd) { - cmd = cmds[i - 1]; - } else { - i += 1; - } + let i = 0 + + const cmdHasFunctionArg = (cmd) => { + return _.isFunction(cmd.get('args')[0]) + } + + const overrideAssert = function (...args) { + let cmd = cmds[i] + const setCommandLog = (log) => { + // our next log may not be an assertion + // due to page events so make sure we wait + // until we see page events + if (log.get('name') !== 'assert') { + return + } + + // when we do immediately unbind this function + state('onBeforeLog', null) + + const insertNewLog = (log) => { + cmd.log(log) - //# if our command has a function argument - //# then we know it may contain multiple - //# assertions - if (cmdHasFunctionArg(cmd)) { - let assertion; - let index = cmd.get("assertionIndex"); - const assertions = cmd.get("assertions"); - - const incrementIndex = () => //# always increase the assertionIndex - //# so our next assertion matches up - //# to the correct index - cmd.set("assertionIndex", index += 1); - - //# if we dont have an assertion at this - //# index then insert a new log - if (!(assertion = assertions[index])) { - assertions.push(log); - incrementIndex(); - - return insertNewLog(log); - } else { - //# else just merge this log - //# into the previous assertion log - incrementIndex(); - assertion.merge(log); - - //# dont output a new log - return false; - } + return options.assertions.push(log) + } + + // its possible a single 'should' will assert multiple + // things such as the case with have.property. we can + // detect when that is happening because cmd will be null. + // if thats the case then just set cmd to be the previous + // cmd and do not increase 'i' + // this will prevent 2 logs from ever showing up but still + // provide errors when the 1st assertion fails. + if (!cmd) { + cmd = cmds[i - 1] + } else { + i += 1 + } + + // if our command has a function argument + // then we know it may contain multiple + // assertions + if (cmdHasFunctionArg(cmd)) { + let index = cmd.get('assertionIndex') + const assertions = cmd.get('assertions') + + // always increase the assertionIndex + // so our next assertion matches up + // to the correct index + const incrementIndex = () => { + return cmd.set('assertionIndex', index += 1) } - //# if we already have a log - //# then just update its attrs from - //# the new log - if (l = cmd.getLastLog()) { - l.merge(log); - - //# and make sure we return false - //# which prevents a new log from - //# being added - return false; - } else { - return insertNewLog(log); + // if we dont have an assertion at this + // index then insert a new log + const assertion = assertions[index] + + if (!assertion) { + assertions.push(log) + incrementIndex() + + return insertNewLog(log) } - }; - - return state("onBeforeLog", setCommandLog); - })(cmds[i]); - - //# send verify=true as the last arg - return assertFn.apply(this, args.concat(true)); - }; - - const fns = injectAssertionFns(cmds); - - const subjects = []; - - //# iterate through each subject - //# and force the assertion to return - //# this value so it does not get - //# invoked again - const setSubjectAndSkip = () => (() => { - const result = []; - for (i = 0; i < subjects.length; i++) { - subject = subjects[i]; - const cmd = cmds[i]; - cmd.set("subject", subject); - result.push(cmd.skip()); + + // else just merge this log + // into the previous assertion log + incrementIndex() + assertion.merge(log) + + // dont output a new log + return false + } + + // if we already have a log + // then just update its attrs from + // the new log + const l = cmd.getLastLog() + + if (l) { + l.merge(log) + + // and make sure we return false + // which prevents a new log from + // being added + return false + } + + return insertNewLog(log) } - return result; - })(); + + state('onBeforeLog', setCommandLog) + + // send verify=true as the last arg + return assertFn.apply(this, args.concat(true)) + } + + const fns = injectAssertionFns(cmds) + + const subjects = [] + + // iterate through each subject + // and force the assertion to return + // this value so it does not get + // invoked again + const setSubjectAndSkip = () => { + subjects.forEach((subject, i) => { + const cmd = cmds[i] + + cmd.set('subject', subject) + cmd.skip() + }) + + return cmds + } const assertions = (memo, fn, i) => { - //# HACK: bluebird .reduce will not call the callback - //# if given an undefined initial value, so in order to - //# support undefined subjects, we wrap the initial value - //# in an Array and unwrap it if index = 0 + // HACK: bluebird .reduce will not call the callback + // if given an undefined initial value, so in order to + // support undefined subjects, we wrap the initial value + // in an Array and unwrap it if index = 0 if (i === 0) { - memo = memo[0]; + memo = memo[0] } - return fn(memo).then(subject => subjects[i] = subject); - }; - const restore = function() { - state("upcomingAssertions", []); + return fn(memo).then((subject) => { + return subjects[i] = subject + }) + } + + const restore = () => { + state('upcomingAssertions', []) - //# no matter what we need to - //# restore the assert fn - return state("overrideAssert", undefined); - }; + // no matter what we need to + // restore the assert fn + return state('overrideAssert', undefined) + } - //# store this in case our test ends early - //# and we reset between tests - state("overrideAssert", overrideAssert); + // store this in case our test ends early + // and we reset between tests + state('overrideAssert', overrideAssert) return Promise .reduce(fns, assertions, [subject]) - .then(function() { - restore(); + .then(() => { + restore() - setSubjectAndSkip(); + setSubjectAndSkip() - finishAssertions(options.assertions); + finishAssertions(options.assertions) - return onPassFn();}).catch(function(err) { - restore(); + return onPassFn() + }) + .catch((err) => { + restore() - //# when we're told not to retry + // when we're told not to retry if (err.retry === false) { - //# finish the assertions - finishAssertions(options.assertions); + // finish the assertions + finishAssertions(options.assertions) - //# and then push our command into this err + // and then push our command into this err try { - $utils.throwErr(err, { onFail: options._log }); + $utils.throwErr(err, { onFail: options._log }) } catch (e) { - err = e; + err = e } } - throw err;}).catch(onFailFn); - }; + throw err + }) + .catch(onFailFn) + } - var assertFn = function(passed, message, value, actual, expected, error, verifying = false) { - //# slice off everything after a ', but' or ' but ' for passing assertions, because - //# otherwise it doesn't make sense: - //# "expected
to have a an attribute 'href', but it was 'href'" + const assertFn = (passed, message, value, actual, expected, error, verifying = false) => { + // slice off everything after a ', but' or ' but ' for passing assertions, because + // otherwise it doesn't make sense: + // "expected
to have a an attribute 'href', but it was 'href'" if (message && passed && butRe.test(message)) { - message = message.substring(0, message.search(butRe)); + message = message.substring(0, message.search(butRe)) } - if (value != null ? value.isSinonProxy : undefined) { - message = message.replace(stackTracesRe, "\n"); + if (value && value.isSinonProxy) { + message = message.replace(stackTracesRe, '\n') } - let obj = parseValueActualAndExpected(value, actual, expected); + let obj = parseValueActualAndExpected(value, actual, expected) if ($dom.isElement(value)) { - obj.$el = $dom.wrap(value); + obj.$el = $dom.wrap(value) } - const current = state("current"); - - //# if we are simply verifying the upcoming - //# assertions then do not immediately end or snapshot - //# else do + // if we are simply verifying the upcoming + // assertions then do not immediately end or snapshot + // else do if (verifying) { - obj._error = error; + obj._error = error } else { - obj.end = true; - obj.snapshot = true; - obj.error = error; + obj.end = true + obj.snapshot = true + obj.error = error } const isChildLike = (subject, current) => { return (value === subject) || isDomSubjectAndMatchesValue(value, subject) || - //# if our current command is an assertion type - isAssertionType(current) || - //# are we currently verifying assertions? - (__guard__(state("upcomingAssertions"), x => x.length) > 0) || - //# did the function have arguments - functionHadArguments(current); - }; + // if our current command is an assertion type + isAssertionType(current) || + // are we currently verifying assertions? + (state('upcomingAssertions') && state('upcomingAssertions').length > 0) || + // did the function have arguments + functionHadArguments(current) + } _.extend(obj, { - name: "assert", + name: 'assert', // end: true // snapshot: true message, passed, - selector: (value != null ? value.selector : undefined), - type(current, subject) { - //# if our current command has arguments assume - //# we are an assertion that's involving the current - //# subject or our value is the current subject - if (isChildLike(subject, current)) { - return "child"; - } else { - return "parent"; - } + selector: value ? value.selector : undefined, + type (current, subject) { + // if our current command has arguments assume + // we are an assertion that's involving the current + // subject or our value is the current subject + return isChildLike(subject, current) ? 'child' : 'parent' }, consoleProps: () => { - obj = {Command: "assert"}; + obj = { Command: 'assert' } - _.extend(obj, parseValueActualAndExpected(value, actual, expected)); + _.extend(obj, parseValueActualAndExpected(value, actual, expected)) return _.extend(obj, - {Message: message.replace(bTagOpen, "").replace(bTagClosed, "")}); - } - } - ); + { Message: message.replace(bTagOpen, '').replace(bTagClosed, '') }) + }, + }) - //# think about completely gutting the whole object toString - //# which chai does by default, its so ugly and worthless + // think about completely gutting the whole object toString + // which chai does by default, its so ugly and worthless if (error) { - error.onFail = function(err) {}; + error.onFail = (err) => { } } - Cypress.log(obj); + Cypress.log(obj) - return null; - }; + return null + } + + const assert = function (...args) { + // if we've temporarily overriden assertions + // then just bail early with this function + const fn = state('overrideAssert') || assertFn - const assert = function() { - //# if we've temporarily overriden assertions - //# then just bail early with this function - let left; - const fn = (left = state("overrideAssert")) != null ? left : assertFn; - return fn.apply(this, arguments); - }; + return fn.apply(this, args) + } return { finishAssertions, verifyUpcomingAssertions, - assert - }; -}; + assert, + } +} module.exports = { - create -}; - -function __guard__(value, transform) { - return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; -} \ No newline at end of file + create, +} diff --git a/packages/driver/src/cypress/chai_jquery.js b/packages/driver/src/cypress/chai_jquery.js index 9c9debeb4216..62f391816fc8 100644 --- a/packages/driver/src/cypress/chai_jquery.js +++ b/packages/driver/src/cypress/chai_jquery.js @@ -1,300 +1,309 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const _ = require("lodash"); -const $ = require("jquery"); -const $dom = require("../dom"); +const _ = require('lodash') +const $ = require('jquery') +const $dom = require('../dom') const selectors = { - visible: "visible", - hidden: "hidden", - selected: "selected", - checked: "checked", - enabled: "enabled", - disabled: "disabled", - focus: "focused", - focused: "focused" -}; + visible: 'visible', + hidden: 'hidden', + selected: 'selected', + checked: 'checked', + enabled: 'enabled', + disabled: 'disabled', + focus: 'focused', + focused: 'focused', +} const attrs = { - attr: "attribute", - css: "CSS property", - prop: "property" -}; + attr: 'attribute', + css: 'CSS property', + prop: 'property', +} -const wrap = ctx => //# reset the obj under test -//# to be re-wrapped in our own -//# jquery, so we can control -//# the methods on it -$(ctx._obj); +// reset the obj under test +// to be re-wrapped in our own +// jquery, so we can control +// the methods on it +const wrap = (ctx) => $(ctx._obj) -const $chaiJquery = function(chai, chaiUtils, callbacks = {}) { - const { inspect, flag } = chaiUtils; +const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { + const { inspect, flag } = chaiUtils - const assertDom = function(ctx, method, ...args) { + const assertDom = (ctx, method, ...args) => { if (!$dom.isDom(ctx._obj)) { try { - //# always fail the assertion - //# if we aren't a DOM like object - return ctx.assert(false, ...args); + // always fail the assertion + // if we aren't a DOM like object + return ctx.assert(false, ...args) } catch (err) { - return callbacks.onInvalid(method, ctx._obj); + return callbacks.onInvalid(method, ctx._obj) } } - }; + } - const assert = function(ctx, method, bool, ...args) { - assertDom(ctx, method, ...args); + const assert = (ctx, method, bool, ...args) => { + assertDom(ctx, method, ...args) try { - // ## reset obj to wrapped - const orig = ctx._obj; - ctx._obj = wrap(ctx); + // reset obj to wrapped + const orig = ctx._obj + + ctx._obj = wrap(ctx) if (ctx._obj.length === 0) { - ctx._obj = ctx._obj.selector; + ctx._obj = ctx._obj.selector } - //# apply the assertion - const ret = ctx.assert(bool, ...args); - ctx._obj = orig; - return ret; + // apply the assertion + const ret = ctx.assert(bool, ...args) + + ctx._obj = orig + + return ret } catch (err) { - //# send it up with the obj and whether it was negated - return callbacks.onError(err, method, ctx._obj, flag(ctx, "negate")); + // send it up with the obj and whether it was negated + return callbacks.onError(err, method, ctx._obj, flag(ctx, 'negate')) } - }; + } - const assertPartial = function(ctx, method, actual, expected, message, notMessage, ...args) { + const assertPartial = (ctx, method, actual, expected, message, notMessage, ...args) => { if (ctx.__flags.contains || ctx.__flags.includes) { return assert( ctx, method, _.includes(actual, expected), - "expected #{this} to contain " + message, - "expected #{this} not to contain " + notMessage, + `expected #{this} to contain ${message}`, + `expected #{this} not to contain ${notMessage}`, ...args - ); + ) } + return assert( ctx, method, actual === expected, - "expected #{this} to have " + message, - "expected #{this} not to have " + notMessage, + `expected #{this} to have ${message}`, + `expected #{this} not to have ${notMessage}`, ...args - ); - }; - chai.Assertion.addMethod("data", function() { - assertDom(this, "data"); + ) + } - let a = new chai.Assertion(wrap(this).data()); + chai.Assertion.addMethod('data', function (...args) { + assertDom(this, 'data') - if (flag(this, "negate")) { - a = a.not; + let a = new chai.Assertion(wrap(this).data()) + + if (flag(this, 'negate')) { + a = a.not } - return a.property.apply(a, arguments); - }); + return a.property.apply(a, args) + }) - chai.Assertion.addMethod("class", function(className) { + chai.Assertion.addMethod('class', function (className) { return assert( this, - "class", + 'class', wrap(this).hasClass(className), 'expected #{this} to have class #{exp}', 'expected #{this} not to have class #{exp}', className - ); - }); + ) + }) - chai.Assertion.addMethod("id", function(id) { + chai.Assertion.addMethod('id', function (id) { return assert( this, - "id", - wrap(this).prop("id") === id, + 'id', + wrap(this).prop('id') === id, 'expected #{this} to have id #{exp}', 'expected #{this} not to have id #{exp}', id - ); - }); + ) + }) - chai.Assertion.addMethod("html", function(html) { + chai.Assertion.addMethod('html', function (html) { assertDom( this, - "html", + 'html', 'expected #{this} to have HTML #{exp}', 'expected #{this} not to have HTML #{exp}', html - ); + ) - const actual = wrap(this).html(); + const actual = wrap(this).html() return assertPartial( this, - "html", + 'html', actual, html, 'HTML #{exp}, but the HTML was #{act}', 'HTML #{exp}', html, actual - ); - }); + ) + }) - chai.Assertion.addMethod("text", function(text) { + chai.Assertion.addMethod('text', function (text) { assertDom( this, - "text", + 'text', 'expected #{this} to have text #{exp}', 'expected #{this} not to have text #{exp}', text - ); + ) - const actual = wrap(this).text(); + const actual = wrap(this).text() return assertPartial( this, - "text", + 'text', actual, text, 'text #{exp}, but the text was #{act}', 'text #{exp}', text, actual - ); - }); + ) + }) - chai.Assertion.addMethod("value", function(value) { + chai.Assertion.addMethod('value', function (value) { assertDom( this, - "value", + 'value', 'expected #{this} to have value #{exp}', 'expected #{this} not to have value #{exp}', value - ); + ) - const actual = wrap(this).val(); + const actual = wrap(this).val() return assertPartial( this, - "value", + 'value', actual, value, 'value #{exp}, but the value was #{act}', 'value #{exp}', value, actual - ); - }); + ) + }) - chai.Assertion.addMethod("descendants", function(selector) { + chai.Assertion.addMethod('descendants', function (selector) { return assert( this, - "descendants", + 'descendants', wrap(this).has(selector).length > 0, 'expected #{this} to have descendants #{exp}', 'expected #{this} not to have descendants #{exp}', selector - ); - }); + ) + }) + + chai.Assertion.overwriteProperty('empty', (_super) => { + return (function (...args) { + if ($dom.isDom(this._obj)) { + return assert( + this, + 'empty', + wrap(this).is(':empty'), + 'expected #{this} to be #{exp}', + 'expected #{this} not to be #{exp}', + 'empty' + ) + } + + return _super.apply(this, args) + }) + }) + + chai.Assertion.overwriteMethod('match', (_super) => { + return (function (...args) { + const selector = args[0] + + if ($dom.isDom(this._obj)) { + return assert( + this, + 'match', + wrap(this).is(selector), + 'expected #{this} to match #{exp}', + 'expected #{this} not to match #{exp}', + selector + ) + } - chai.Assertion.overwriteProperty("empty", _super => (function() { - if ($dom.isDom(this._obj)) { + return _super.apply(this, args) + }) + }) + + _.each(selectors, (selectorName, selector) => { + return chai.Assertion.addProperty(selector, function () { return assert( this, - "empty", - wrap(this).is(":empty"), + selector, + wrap(this).is(`:${selector}`), 'expected #{this} to be #{exp}', 'expected #{this} not to be #{exp}', - "empty" - ); - } else { - return _super.apply(this, arguments); - } - })); - - chai.Assertion.overwriteMethod("match", _super => (function(selector) { - if ($dom.isDom(this._obj)) { - return assert( - this, - "match", - wrap(this).is(selector), - 'expected #{this} to match #{exp}', - 'expected #{this} not to match #{exp}', - selector - ); - } else { - return _super.apply(this, arguments); - } - })); - - _.each(selectors, (selectorName, selector) => chai.Assertion.addProperty(selector, function() { - return assert( - this, - selector, - wrap(this).is(":" + selector), - 'expected #{this} to be #{exp}', - 'expected #{this} not to be #{exp}', - selectorName - ); - })); - - return _.each(attrs, (description, attr) => chai.Assertion.addMethod(attr, function(name, val) { - assertDom( - this, - attr, - 'expected #{this} to have ' + description + ' #{exp}', - 'expected #{this} not to have ' + description + ' #{exp}', - name - ); - - const actual = wrap(this)[attr](name); - - //# when we only have 1 argument dont worry about val - if (arguments.length === 1) { - assert( + selectorName + ) + }) + }) + + _.each(attrs, (description, attr) => { + return chai.Assertion.addMethod(attr, function (name, val) { + assertDom( this, attr, - actual !== undefined, - 'expected #{this} to have ' + description + ' #{exp}', - 'expected #{this} not to have ' + description + ' #{exp}', + `expected #{this} to have ${description} #{exp}`, + `expected #{this} not to have ${description} #{exp}`, name - ); - - //# change the subject - this._obj = actual; - - } else { - //# if we don't have an attribute here at all we need to - //# have a different failure message - let message, negatedMessage; - if (_.isUndefined(actual)) { - message = `expected \#{this} to have ${description} ${inspect(name)}`; - - negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)}`; + ) + + const actual = wrap(this)[attr](name) + + // when we only have 1 argument dont worry about val + if (arguments.length === 1) { + assert( + this, + attr, + actual !== undefined, + `expected #{this} to have ${description} #{exp}`, + `expected #{this} not to have ${description} #{exp}`, + name + ) + + // change the subject + this._obj = actual } else { - message = `expected \#{this} to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}`; - - negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}`; + // if we don't have an attribute here at all we need to + // have a different failure message + let message; let negatedMessage + + if (_.isUndefined(actual)) { + message = `expected \#{this} to have ${description} ${inspect(name)}` + + negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)}` + } else { + message = `expected \#{this} to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}` + + negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}` + } + + assert( + this, + attr, + (actual != null) && (actual === val), + message, + negatedMessage, + val, + actual + ) } - assert( - this, - attr, - (actual != null) && (actual === val), - message, - negatedMessage, - val, - actual - ); - } - - return this; - })); -}; + return this + }) + }) +} -module.exports = $chaiJquery; +module.exports = $chaiJquery diff --git a/packages/driver/src/cypress/mocha.js b/packages/driver/src/cypress/mocha.js index b763849b33fb..d183a85c3a91 100644 --- a/packages/driver/src/cypress/mocha.js +++ b/packages/driver/src/cypress/mocha.js @@ -1,228 +1,233 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const _ = require("lodash"); -const $utils = require("./utils"); - -//# in the browser mocha is coming back -//# as window -const mocha = require("mocha"); - -const Mocha = mocha.Mocha != null ? mocha.Mocha : mocha; -const { - Test -} = Mocha; -const { - Runner -} = Mocha; -const { - Runnable -} = Mocha; - -const runnerRun = Runner.prototype.run; -const runnerFail = Runner.prototype.fail; -const runnableRun = Runnable.prototype.run; -const runnableClearTimeout = Runnable.prototype.clearTimeout; -const runnableResetTimeout = Runnable.prototype.resetTimeout; - -//# don't let mocha polute the global namespace -delete window.mocha; -delete window.Mocha; - -const ui = function(specWindow, _mocha) { - //# Override mocha.ui so that the pre-require event is emitted - //# with the iframe's `window` reference, rather than the parent's. - _mocha.ui = function(name) { - this._ui = Mocha.interfaces[name]; +const $utils = require('./utils') - if (!this._ui) { - $utils.throwErrByPath("mocha.invalid_interface", { args: { name } }); - } +// in the browser mocha is coming back +// as window +const mocha = require('mocha') - this._ui = this._ui(this.suite); +const Mocha = mocha.Mocha != null ? mocha.Mocha : mocha +const { Test, Runner, Runnable } = Mocha - //# this causes the mocha globals in the spec window to be defined - //# such as describe, it, before, beforeEach, etc - this.suite.emit("pre-require", specWindow, null, this); +const runnerRun = Runner.prototype.run +const runnerFail = Runner.prototype.fail +const runnableRun = Runnable.prototype.run +const runnableClearTimeout = Runnable.prototype.clearTimeout +const runnableResetTimeout = Runnable.prototype.resetTimeout - return this; - }; +// don't let mocha polute the global namespace +delete window.mocha +delete window.Mocha - return _mocha.ui("bdd"); -}; +const ui = (specWindow, _mocha) => { + // Override mocha.ui so that the pre-require event is emitted + // with the iframe's `window` reference, rather than the parent's. + _mocha.ui = function (name) { + this._ui = Mocha.interfaces[name] -const set = function(specWindow, _mocha) { - //# Mocha is usually defined in the spec when used normally - //# in the browser or node, so we add it as a global - //# for our users too - const M = (specWindow.Mocha = Mocha); - const m = (specWindow.mocha = _mocha); + if (!this._ui) { + $utils.throwErrByPath('mocha.invalid_interface', { args: { name } }) + } - //# also attach the Mocha class - //# to the mocha instance for clarity - m.Mocha = M; + this._ui = this._ui(this.suite) - //# this needs to be part of the configuration of cypress.json - //# we can't just forcibly use bdd - return ui(specWindow, _mocha); -}; + // this causes the mocha globals in the spec window to be defined + // such as describe, it, before, beforeEach, etc + this.suite.emit('pre-require', specWindow, null, this) -const globals = function(specWindow, reporter) { - if (reporter == null) { reporter = function() {}; } + return this + } - const _mocha = new Mocha({ - reporter, - enableTimeouts: false - }); + return _mocha.ui('bdd') +} - //# set mocha props on the specWindow - set(specWindow, _mocha); +const set = (specWindow, _mocha) => { + // Mocha is usually defined in the spec when used normally + // in the browser or node, so we add it as a global + // for our users too + const M = (specWindow.Mocha = Mocha) + const m = (specWindow.mocha = _mocha) - //# return the newly created mocha instance - return _mocha; -}; + // also attach the Mocha class + // to the mocha instance for clarity + m.Mocha = M -const getRunner = function(_mocha) { - Runner.prototype.run = function() { - //# reset our runner#run function - //# so the next time we call it - //# its normal again! - restoreRunnerRun(); + // this needs to be part of the configuration of cypress.json + // we can't just forcibly use bdd + return ui(specWindow, _mocha) +} - //# return the runner instance - return this; - }; +const globals = (specWindow, reporter) => { + if (reporter == null) { + reporter = () => {} + } - return _mocha.run(); -}; + const _mocha = new Mocha({ + reporter, + enableTimeouts: false, + }) -const restoreRunnableClearTimeout = () => Runnable.prototype.clearTimeout = runnableClearTimeout; + // set mocha props on the specWindow + set(specWindow, _mocha) -const restoreRunnableResetTimeout = () => Runnable.prototype.resetTimeout = runnableResetTimeout; + // return the newly created mocha instance + return _mocha +} -var restoreRunnerRun = () => Runner.prototype.run = runnerRun; +const getRunner = function (_mocha) { + Runner.prototype.run = function () { + // reset our runner#run function + // so the next time we call it + // its normal again! + restoreRunnerRun() -const restoreRunnerFail = () => Runner.prototype.fail = runnerFail; + // return the runner instance + return this + } -const restoreRunnableRun = () => Runnable.prototype.run = runnableRun; + return _mocha.run() +} + +const restoreRunnableClearTimeout = () => { + Runnable.prototype.clearTimeout = runnableClearTimeout +} + +const restoreRunnableResetTimeout = () => { + Runnable.prototype.resetTimeout = runnableResetTimeout +} + +const restoreRunnerRun = () => { + Runner.prototype.run = runnerRun +} + +const restoreRunnerFail = () => { + Runner.prototype.fail = runnerFail +} + +const restoreRunnableRun = () => { + Runnable.prototype.run = runnableRun +} + +// matching the current Runner.prototype.fail except +// changing the logic for determing whether this is a valid err +const patchRunnerFail = () => { + Runner.prototype.fail = function (runnable, err) { + // if this isnt a correct error object then just bail + // and call the original function + if (Object.prototype.toString.call(err) !== '[object Error]') { + return runnerFail.call(this, runnable, err) + } -const patchRunnerFail = () => //# matching the current Runner.prototype.fail except -//# changing the logic for determing whether this is a valid err -Runner.prototype.fail = function(runnable, err) { - //# if this isnt a correct error object then just bail - //# and call the original function - if (Object.prototype.toString.call(err) !== "[object Error]") { - return runnerFail.call(this, runnable, err); - } + // else replicate the normal mocha functionality + ++this.failures - //# else replicate the normal mocha functionality - ++this.failures; + runnable.state = 'failed' - runnable.state = "failed"; + this.emit('fail', runnable, err) + } +} - return this.emit("fail", runnable, err); -}; +const patchRunnableRun = (Cypress) => { + Runnable.prototype.run = function (...args) { + const runnable = this -const patchRunnableRun = Cypress => Runnable.prototype.run = function(...args) { - const runnable = this; + Cypress.action('mocha:runnable:run', runnableRun, runnable, args) + } +} - return Cypress.action("mocha:runnable:run", runnableRun, runnable, args); -}; +const patchRunnableClearTimeout = () => { + Runnable.prototype.clearTimeout = function (...args) { + // call the original + runnableClearTimeout.apply(this, args) -const patchRunnableClearTimeout = () => Runnable.prototype.clearTimeout = function() { - //# call the original - runnableClearTimeout.apply(this, arguments); + this.timer = null + } +} - //# nuke the timer property - //# for testing purposes - return this.timer = null; -}; +const patchRunnableResetTimeout = () => { + Runnable.prototype.resetTimeout = function () { + const runnable = this -const patchRunnableResetTimeout = () => Runnable.prototype.resetTimeout = function() { - const runnable = this; + const ms = this.timeout() || 1e9 - const ms = this.timeout() || 1e9; + this.clearTimeout() - this.clearTimeout(); + const getErrPath = function () { + // we've yield an explicit done callback + if (runnable.async) { + return 'mocha.async_timed_out' + } - const getErrPath = function() { - //# we've yield an explicit done callback - if (runnable.async) { - return "mocha.async_timed_out"; - } else { - //# TODO: improve this error message. It's not that - //# a command necessarily timed out - in fact this is - //# a mocha timeout, and a command likely *didn't* - //# time out correctly, so we received this message instead. - return "mocha.timed_out"; + // TODO: improve this error message. It's not that + // a command necessarily timed out - in fact this is + // a mocha timeout, and a command likely *didn't* + // time out correctly, so we received this message instead. + return 'mocha.timed_out' } - }; - return this.timer = setTimeout(function() { - const errMessage = $utils.errMessageByPath(getErrPath(), { ms }); - runnable.callback(new Error(errMessage)); - return runnable.timedOut = true; + this.timer = setTimeout(() => { + const errMessage = $utils.errMessageByPath(getErrPath(), { ms }) + + runnable.callback(new Error(errMessage)) + runnable.timedOut = true + }, ms) } - , ms); -}; +} -const restore = function() { - restoreRunnerRun(); - restoreRunnerFail(); - restoreRunnableRun(); - restoreRunnableClearTimeout(); - return restoreRunnableResetTimeout(); -}; +const restore = () => { + restoreRunnerRun() + restoreRunnerFail() + restoreRunnableRun() + restoreRunnableClearTimeout() + restoreRunnableResetTimeout() +} -const override = function(Cypress) { - patchRunnerFail(); - patchRunnableRun(Cypress); - patchRunnableClearTimeout(); - return patchRunnableResetTimeout(); -}; +const override = (Cypress) => { + patchRunnerFail() + patchRunnableRun(Cypress) + patchRunnableClearTimeout() + patchRunnableResetTimeout() +} -const create = function(specWindow, Cypress, reporter) { - restore(); +const create = (specWindow, Cypress, reporter) => { + restore() - override(Cypress); + override(Cypress) - //# generate the mocha + Mocha globals - //# on the specWindow, and get the new - //# _mocha instance - const _mocha = globals(specWindow, reporter); + // generate the mocha + Mocha globals + // on the specWindow, and get the new + // _mocha instance + const _mocha = globals(specWindow, reporter) - const _runner = getRunner(_mocha); + const _runner = getRunner(_mocha) return { _mocha, - createRootTest(title, fn) { - const r = new Test(title, fn); - _runner.suite.addTest(r); - return r; + createRootTest (title, fn) { + const r = new Test(title, fn) + + _runner.suite.addTest(r) + + return r }, - getRunner() { - return _runner; + getRunner () { + return _runner }, - getRootSuite() { - return _mocha.suite; + getRootSuite () { + return _mocha.suite }, - options(runner) { - return runner.options(_mocha.options); - } - }; -}; + options (runner) { + return runner.options(_mocha.options) + }, + } +} module.exports = { restore, globals, - create -}; + create, +} diff --git a/packages/driver/test/cypress/integration/issues/510_spec.js b/packages/driver/test/cypress/integration/issues/510_spec.js index 4d76f88d5ea4..181e0a656b95 100644 --- a/packages/driver/test/cypress/integration/issues/510_spec.js +++ b/packages/driver/test/cypress/integration/issues/510_spec.js @@ -1,11 +1,7 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -before(() => cy - .visit("http://localhost:3500/fixtures/jquery.html")); +before(() => { + cy.visit('http://localhost:3500/fixtures/jquery.html') +}) -it("XHR should be available", function() {}); +it('XHR should be available', () => {}) -it("XHR should be available2", function() {}); +it('XHR should be available2', () => {}) diff --git a/packages/driver/test/cypress/integration/issues/565_spec.js b/packages/driver/test/cypress/integration/issues/565_spec.js index a748991cd81a..35c90e203f05 100644 --- a/packages/driver/test/cypress/integration/issues/565_spec.js +++ b/packages/driver/test/cypress/integration/issues/565_spec.js @@ -1,13 +1,12 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -//# https://github.com/cypress-io/cypress/issues/565 -describe("issue 565", function() { - before(() => cy +// https://github.com/cypress-io/cypress/issues/565 +describe('issue 565', () => { + before(() => { + cy .viewport(400, 400) - .visit("/fixtures/issue-565.html")); + .visit('/fixtures/issue-565.html') + }) - return it("can click the first tr", () => cy.get("td:first").click()); -}); + it('can click the first tr', () => { + cy.get('td:first').click() + }) +}) diff --git a/packages/driver/test/cypress/integration/issues/573_spec.js b/packages/driver/test/cypress/integration/issues/573_spec.js index 0b481ae6e727..7b1c159f6acf 100644 --- a/packages/driver/test/cypress/integration/issues/573_spec.js +++ b/packages/driver/test/cypress/integration/issues/573_spec.js @@ -1,56 +1,74 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const run = () => cy.window() -.then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve) { - const i = win.document.createElement("iframe"); - i.onload = resolve; - i.src = "/basic_auth"; - return win.document.body.appendChild(i); -})).get("iframe").should($iframe => expect($iframe.contents().text()).to.include("basic auth worked")).window().then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve, reject) { - const xhr = new win.XMLHttpRequest(); - xhr.open("GET", "/basic_auth"); - xhr.onload = function() { - try { - expect(this.responseText).to.include("basic auth worked"); - return resolve(win); - } catch (err) { - return reject(err); - } - }; - return xhr.send(); -})).then({ timeout: 60000 }, win => new Cypress.Promise(function(resolve, reject) { - //# ensure other origins do not have auth headers attached - const xhr = new win.XMLHttpRequest(); - xhr.open("GET", "http://localhost:3501/basic_auth"); - xhr.onload = function() { - try { - expect(this.status).to.eq(401); - return resolve(win); - } catch (err) { - return reject(err); - } - }; - return xhr.send(); -})); +const run = () => { + cy.window() + .then({ timeout: 60000 }, (win) => { + return new Cypress.Promise((resolve) => { + const i = win.document.createElement('iframe') + + i.onload = resolve + i.src = '/basic_auth' + + return win.document.body.appendChild(i) + }) + }) + .get('iframe').should(($iframe) => { + expect($iframe.contents().text()).to.include('basic auth worked') + }) + .window().then({ timeout: 60000 }, (win) => { + return new Cypress.Promise(((resolve, reject) => { + const xhr = new win.XMLHttpRequest() + + xhr.open('GET', '/basic_auth') + xhr.onload = function () { + try { + expect(this.responseText).to.include('basic auth worked') + + return resolve(win) + } catch (err) { + return reject(err) + } + } + + return xhr.send() + })) + }) + .then({ timeout: 60000 }, (win) => { + return new Cypress.Promise(((resolve, reject) => { + // ensure other origins do not have auth headers attached + const xhr = new win.XMLHttpRequest() + + xhr.open('GET', 'http://localhost:3501/basic_auth') + xhr.onload = function () { + try { + expect(this.status).to.eq(401) + + return resolve(win) + } catch (err) { + return reject(err) + } + } + + return xhr.send() + })) + }) +} // cy.visit("http://admin:admin@the-internet.herokuapp.com/basic_auth") -describe("basic auth", function() { - it("can visit with username/pw in url", function() { - cy.visit("http://cypress:password123@localhost:3500/basic_auth"); - return run(); - }); +describe('basic auth', () => { + it('can visit with username/pw in url', () => { + cy.visit('http://cypress:password123@localhost:3500/basic_auth') - return it("can visit with auth options", function() { - cy.visit("http://localhost:3500/basic_auth", { + run() + }) + + it('can visit with auth options', () => { + cy.visit('http://localhost:3500/basic_auth', { auth: { - username: "cypress", - password: "password123" - } - }); - return run(); - }); -}); + username: 'cypress', + password: 'password123', + }, + }) + + run() + }) +}) diff --git a/packages/driver/test/cypress/integration/issues/652_spec.js b/packages/driver/test/cypress/integration/issues/652_spec.js index e290c23eea43..548bd17506db 100644 --- a/packages/driver/test/cypress/integration/issues/652_spec.js +++ b/packages/driver/test/cypress/integration/issues/652_spec.js @@ -1,23 +1,20 @@ -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -//# https://github.com/cypress-io/cypress/issues/652 -describe("issue 652", function() { - before(() => cy.visit("/fixtures/issue-652.html")); +// https://github.com/cypress-io/cypress/issues/652 +describe('issue 652', () => { + before(() => { + cy.visit('/fixtures/issue-652.html') + }) - return it('should visit all the hashes', function() { + it('should visit all the hashes', () => { // cy.wait(0) - cy.visit('/fixtures/issue-652.html#one'); + cy.visit('/fixtures/issue-652.html#one') // cy.wait(0) - cy.visit('/fixtures/issue-652.html#two'); + cy.visit('/fixtures/issue-652.html#two') // cy.wait(0) - cy.visit('/fixtures/issue-652.html#three'); + cy.visit('/fixtures/issue-652.html#three') - return cy.get('#visited') - .should('contain', 'one') - .should('contain', 'two') - .should('contain', 'three'); - }); -}); + cy.get('#visited') + .should('contain', 'one') + .should('contain', 'two') + .should('contain', 'three') + }) +})