Skip to content

Commit a9905ac

Browse files
committed
setRunnable
1 parent fc3a696 commit a9905ac

File tree

1 file changed

+137
-138
lines changed
  • packages/driver/src/cypress

1 file changed

+137
-138
lines changed

packages/driver/src/cypress/cy.ts

Lines changed: 137 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,143 @@ class $Cy implements ITimeouts, IStability, IAssertions, IRetries, IJQuery, ILoc
808808
}
809809
}
810810

811+
setRunnable (runnable, hookId) {
812+
// when we're setting a new runnable
813+
// prepare to run again!
814+
this.queue.reset()
815+
816+
// reset the promise again
817+
this.state('promise', undefined)
818+
819+
this.state('hookId', hookId)
820+
821+
this.state('runnable', runnable)
822+
823+
this.state('test', $utils.getTestFromRunnable(runnable))
824+
825+
this.state('ctx', runnable.ctx)
826+
827+
const { fn } = runnable
828+
829+
const restore = () => {
830+
return runnable.fn = fn
831+
}
832+
833+
const cy = this
834+
835+
runnable.fn = function () {
836+
restore()
837+
838+
const timeout = cy.config('defaultCommandTimeout')
839+
840+
// control timeouts on runnables ourselves
841+
if (_.isFinite(timeout)) {
842+
cy.timeout(timeout)
843+
}
844+
845+
// store the current length of our queue
846+
// before we invoke the runnable.fn
847+
const currentLength = cy.queue.length
848+
849+
try {
850+
// if we have a fn.length that means we
851+
// are accepting a done callback and need
852+
// to change the semantics around how we
853+
// attach the run queue
854+
let done
855+
856+
if (fn.length) {
857+
const originalDone = arguments[0]
858+
859+
arguments[0] = (done = function (err) {
860+
// TODO: handle no longer error when ended early
861+
cy.doneEarly()
862+
863+
originalDone(err)
864+
865+
// return null else we there are situations
866+
// where returning a regular bluebird promise
867+
// results in a warning about promise being created
868+
// in a handler but not returned
869+
return null
870+
})
871+
872+
// store this done property
873+
// for async tests
874+
cy.state('done', done)
875+
}
876+
877+
let ret = __stackReplacementMarker(fn, this, arguments)
878+
879+
// if we returned a value from fn
880+
// and enqueued some new commands
881+
// and the value isn't currently cy
882+
// or a promise
883+
if (ret &&
884+
cy.queue.length > currentLength &&
885+
!cy.isCy(ret) &&
886+
!$utils.isPromiseLike(ret)) {
887+
// TODO: clean this up in the utility function
888+
// to conditionally stringify functions
889+
ret = _.isFunction(ret)
890+
? ret.toString()
891+
: $utils.stringify(ret)
892+
893+
$errUtils.throwErrByPath('miscellaneous.returned_value_and_commands', {
894+
args: { returned: ret },
895+
})
896+
}
897+
898+
// if we attached a done callback
899+
// and returned a promise then we
900+
// need to automatically bind to
901+
// .catch() and return done(err)
902+
// TODO: this has gone away in mocha 3.x.x
903+
// due to overspecifying a resolution.
904+
// in those cases we need to remove
905+
// returning a promise
906+
if (fn.length && ret && ret.catch) {
907+
ret = ret.catch(done)
908+
}
909+
910+
// if we returned a promise like object
911+
if (!cy.isCy(ret) && $utils.isPromiseLike(ret)) {
912+
// indicate we've returned a custom promise
913+
cy.state('returnedCustomPromise', true)
914+
915+
// this means we instantiated a promise
916+
// and we've already invoked multiple
917+
// commands and should warn
918+
if (cy.queue.length > currentLength) {
919+
cy.warnMixingPromisesAndCommands()
920+
}
921+
922+
return ret
923+
}
924+
925+
// if we're cy or we've enqueued commands
926+
if (cy.isCy(ret) || cy.queue.length > currentLength) {
927+
if (fn.length) {
928+
// if user has passed done callback don't return anything
929+
// so we don't get an 'overspecified' error from mocha
930+
return
931+
}
932+
933+
// otherwise, return the 'queue promise', so mocha awaits it
934+
return cy.state('promise')
935+
}
936+
937+
// else just return ret
938+
return ret
939+
} catch (err) {
940+
// if runnable.fn threw synchronously, then it didnt fail from
941+
// a cypress command, but we should still teardown and handle
942+
// the error
943+
return cy.fail(err)
944+
}
945+
}
946+
}
947+
811948
// private
812949
wrapNativeMethods (contentWindow) {
813950
try {
@@ -1081,144 +1218,6 @@ export default {
10811218
create (specWindow, Cypress, Cookies, state, config, log) {
10821219
let cy = new $Cy(specWindow, Cypress, Cookies, state, config)
10831220

1084-
_.extend(cy, {
1085-
setRunnable (runnable, hookId) {
1086-
// when we're setting a new runnable
1087-
// prepare to run again!
1088-
cy.queue.reset()
1089-
1090-
// reset the promise again
1091-
state('promise', undefined)
1092-
1093-
state('hookId', hookId)
1094-
1095-
state('runnable', runnable)
1096-
1097-
state('test', $utils.getTestFromRunnable(runnable))
1098-
1099-
state('ctx', runnable.ctx)
1100-
1101-
const { fn } = runnable
1102-
1103-
const restore = () => {
1104-
return runnable.fn = fn
1105-
}
1106-
1107-
runnable.fn = function () {
1108-
restore()
1109-
1110-
const timeout = config('defaultCommandTimeout')
1111-
1112-
// control timeouts on runnables ourselves
1113-
if (_.isFinite(timeout)) {
1114-
cy.timeout(timeout)
1115-
}
1116-
1117-
// store the current length of our queue
1118-
// before we invoke the runnable.fn
1119-
const currentLength = cy.queue.length
1120-
1121-
try {
1122-
// if we have a fn.length that means we
1123-
// are accepting a done callback and need
1124-
// to change the semantics around how we
1125-
// attach the run queue
1126-
let done
1127-
1128-
if (fn.length) {
1129-
const originalDone = arguments[0]
1130-
1131-
arguments[0] = (done = function (err) {
1132-
// TODO: handle no longer error when ended early
1133-
cy.doneEarly()
1134-
1135-
originalDone(err)
1136-
1137-
// return null else we there are situations
1138-
// where returning a regular bluebird promise
1139-
// results in a warning about promise being created
1140-
// in a handler but not returned
1141-
return null
1142-
})
1143-
1144-
// store this done property
1145-
// for async tests
1146-
state('done', done)
1147-
}
1148-
1149-
let ret = __stackReplacementMarker(fn, this, arguments)
1150-
1151-
// if we returned a value from fn
1152-
// and enqueued some new commands
1153-
// and the value isn't currently cy
1154-
// or a promise
1155-
if (ret &&
1156-
(cy.queue.length > currentLength) &&
1157-
(!cy.isCy(ret)) &&
1158-
(!$utils.isPromiseLike(ret))) {
1159-
// TODO: clean this up in the utility function
1160-
// to conditionally stringify functions
1161-
ret = _.isFunction(ret) ?
1162-
ret.toString()
1163-
:
1164-
$utils.stringify(ret)
1165-
1166-
$errUtils.throwErrByPath('miscellaneous.returned_value_and_commands', {
1167-
args: { returned: ret },
1168-
})
1169-
}
1170-
1171-
// if we attached a done callback
1172-
// and returned a promise then we
1173-
// need to automatically bind to
1174-
// .catch() and return done(err)
1175-
// TODO: this has gone away in mocha 3.x.x
1176-
// due to overspecifying a resolution.
1177-
// in those cases we need to remove
1178-
// returning a promise
1179-
if (fn.length && ret && ret.catch) {
1180-
ret = ret.catch(done)
1181-
}
1182-
1183-
// if we returned a promise like object
1184-
if ((!cy.isCy(ret)) && $utils.isPromiseLike(ret)) {
1185-
// indicate we've returned a custom promise
1186-
state('returnedCustomPromise', true)
1187-
1188-
// this means we instantiated a promise
1189-
// and we've already invoked multiple
1190-
// commands and should warn
1191-
if (cy.queue.length > currentLength) {
1192-
cy.warnMixingPromisesAndCommands()
1193-
}
1194-
1195-
return ret
1196-
}
1197-
1198-
// if we're cy or we've enqueued commands
1199-
if (cy.isCy(ret) || (cy.queue.length > currentLength)) {
1200-
if (fn.length) {
1201-
// if user has passed done callback don't return anything
1202-
// so we don't get an 'overspecified' error from mocha
1203-
return
1204-
}
1205-
1206-
// otherwise, return the 'queue promise', so mocha awaits it
1207-
return state('promise')
1208-
}
1209-
1210-
// else just return ret
1211-
return ret
1212-
} catch (err) {
1213-
// if runnable.fn threw synchronously, then it didnt fail from
1214-
// a cypress command, but we should still teardown and handle
1215-
// the error
1216-
return cy.fail(err)
1217-
}
1218-
}
1219-
},
1220-
})
1221-
12221221
setTopOnError(Cypress, cy)
12231222

12241223
// make cy global in the specWindow

0 commit comments

Comments
 (0)