@@ -221,6 +221,7 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
221221
222222 private testConfigOverride : TestConfigOverride
223223 private commandFns : Record < string , Function > = { }
224+ private selectorFns : Record < string , Function > = { }
224225
225226 constructor ( specWindow : SpecWindow , Cypress : ICypress , Cookies : ICookies , state : StateFunc , config : ICypress [ 'config' ] ) {
226227 super ( )
@@ -244,7 +245,6 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
244245 this . stop = this . stop . bind ( this )
245246 this . reset = this . reset . bind ( this )
246247 this . addCommandSync = this . addCommandSync . bind ( this )
247- this . addChainer = this . addChainer . bind ( this )
248248 this . addCommand = this . addCommand . bind ( this )
249249 this . now = this . now . bind ( this )
250250 this . replayCommandsFrom = this . replayCommandsFrom . bind ( this )
@@ -675,9 +675,21 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
675675 }
676676 }
677677
678- addChainer ( name , fn ) {
679- // add this function to our chainer class
680- return $Chainer . add ( name , fn )
678+ runQueue ( ) {
679+ cy . queue . run ( )
680+ . then ( ( ) => {
681+ const onQueueEnd = cy . state ( 'onQueueEnd' )
682+
683+ if ( onQueueEnd ) {
684+ onQueueEnd ( )
685+ }
686+ } )
687+ . catch ( ( ) => {
688+ // errors from the queue are propagated to cy.fail by the queue itself
689+ // and can be safely ignored here. omitting this catch causes
690+ // unhandled rejections to be logged because Bluebird sees a promise
691+ // chain with no catch handler
692+ } )
681693 }
682694
683695 addCommand ( { name, fn, type, prevSubject } ) {
@@ -711,17 +723,45 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
711723 }
712724 }
713725
714- cy [ name ] = function ( ...args ) {
715- const userInvocationStack = $stackUtils . captureUserInvocationStack ( cy . specWindow . Error )
726+ const callback = ( chainer , userInvocationStack , args ) => {
727+ const { firstCall, chainerId } = chainer
728+
729+ // dont enqueue / inject any new commands if
730+ // onInjectCommand returns false
731+ const onInjectCommand = cy . state ( 'onInjectCommand' )
732+ const injected = _ . isFunction ( onInjectCommand )
733+
734+ if ( injected ) {
735+ if ( onInjectCommand . call ( cy , name , ...args ) === false ) {
736+ return
737+ }
738+ }
739+
740+ cy . enqueue ( {
741+ name,
742+ args,
743+ type,
744+ chainerId,
745+ userInvocationStack,
746+ injected,
747+ fn : wrap ( firstCall ) ,
748+ } )
716749
750+ chainer . firstCall = false
751+ }
752+
753+ $Chainer . add ( name , callback )
754+
755+ cy [ name ] = function ( ...args ) {
717756 cy . ensureRunnable ( name )
718757
719758 // this is the first call on cypress
720759 // so create a new chainer instance
721- const chain = $Chainer . create ( name , userInvocationStack , cy . specWindow , args )
760+ const chainer = new $Chainer ( cy . specWindow )
722761
723- // store the chain so we can access it later
724- cy . state ( 'chain' , chain )
762+ const userInvocationStack = $stackUtils . captureUserInvocationStack ( cy . specWindow . Error )
763+
764+ callback ( chainer , userInvocationStack , args )
725765
726766 // if we are in the middle of a command
727767 // and its return value is a promise
@@ -753,51 +793,11 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
753793 cy . warnMixingPromisesAndCommands ( )
754794 }
755795
756- cy . queue . run ( )
757- . then ( ( ) => {
758- const onQueueEnd = cy . state ( 'onQueueEnd' )
759-
760- if ( onQueueEnd ) {
761- onQueueEnd ( )
762- }
763- } )
764- . catch ( ( ) => {
765- // errors from the queue are propagated to cy.fail by the queue itself
766- // and can be safely ignored here. omitting this catch causes
767- // unhandled rejections to be logged because Bluebird sees a promise
768- // chain with no catch handler
769- } )
796+ cy . runQueue ( )
770797 }
771798
772- return chain
799+ return chainer
773800 }
774-
775- return this . addChainer ( name , ( chainer , userInvocationStack , args ) => {
776- const { firstCall, chainerId } = chainer
777-
778- // dont enqueue / inject any new commands if
779- // onInjectCommand returns false
780- const onInjectCommand = cy . state ( 'onInjectCommand' )
781- const injected = _ . isFunction ( onInjectCommand )
782-
783- if ( injected ) {
784- if ( onInjectCommand . call ( cy , name , ...args ) === false ) {
785- return
786- }
787- }
788-
789- cy . enqueue ( {
790- name,
791- args,
792- type,
793- chainerId,
794- userInvocationStack,
795- injected,
796- fn : wrap ( firstCall ) ,
797- } )
798-
799- return true
800- } )
801801 }
802802
803803 now ( name , ...args ) {
0 commit comments