@@ -193,24 +193,18 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
193193 * this method is called use the new app root. Pass nothing to get a promise that
194194 * resolves to the value of the selector.
195195 *
196- * @param {string|webdriver.promise.Promise<string> } value The new selector.
196+ * @param {string|webdriver.promise.Promise<string> } valuePromise The new selector.
197197 * @returns A promise that resolves with the value of the selector.
198198 */
199- angularAppRoot ( value : string | wdpromise . Promise < string > = null ) : wdpromise . Promise < string > {
200- return this . driver . controlFlow ( ) . execute ( ( ) => {
201- if ( value != null ) {
202- return wdpromise . when ( value ) . then ( ( value : string ) => {
203- this . internalRootEl = value ;
204- if ( this . bpClient ) {
205- const bpCommandPromise = this . bpClient . setWaitParams ( value ) ;
206- // Convert to webdriver promise as best as possible
207- return wdpromise . when ( bpCommandPromise as any ) . then ( ( ) => this . internalRootEl ) ;
208- }
209- return this . internalRootEl ;
210- } ) ;
199+ async angularAppRoot ( valuePromise : string | wdpromise . Promise < string > = null ) : Promise < string > {
200+ if ( valuePromise != null ) {
201+ const value = await valuePromise ;
202+ this . internalRootEl = value ;
203+ if ( this . bpClient ) {
204+ await this . bpClient . setWaitParams ( value ) ;
211205 }
212- return wdpromise . when ( this . internalRootEl ) ;
213- } , `Set angular root selector to ${ value } ` ) ;
206+ }
207+ return this . internalRootEl ;
214208 }
215209
216210 /**
@@ -417,23 +411,17 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
417411 * Call waitForAngularEnabled() without passing a value to read the current
418412 * state without changing it.
419413 */
420- waitForAngularEnabled ( enabled : boolean | wdpromise . Promise < boolean > = null ) :
421- wdpromise . Promise < boolean > {
422- if ( enabled != null ) {
423- const ret = this . driver . controlFlow ( ) . execute ( ( ) => {
424- return wdpromise . when ( enabled ) . then ( ( enabled : boolean ) => {
425- if ( this . bpClient ) {
426- logger . debug ( 'Setting waitForAngular' + ! enabled ) ;
427- const bpCommandPromise = this . bpClient . setWaitEnabled ( enabled ) ;
428- // Convert to webdriver promise as best as possible
429- return wdpromise . when ( bpCommandPromise as any ) . then ( ( ) => enabled ) ;
430- }
431- } ) ;
432- } , `Set proxy synchronization enabled to ${ enabled } ` ) ;
414+ async waitForAngularEnabled ( enabledPromise : boolean | wdpromise . Promise < boolean > = null ) :
415+ Promise < boolean > {
416+ if ( enabledPromise != null ) {
417+ const enabled = await enabledPromise ;
418+ if ( this . bpClient ) {
419+ logger . debug ( 'Setting waitForAngular' + ! enabled ) ;
420+ await this . bpClient . setWaitEnabled ( enabled ) ;
421+ }
433422 this . internalIgnoreSynchronization = ! enabled ;
434- return ret ;
435423 }
436- return wdpromise . when ( ! this . ignoreSynchronization ) ;
424+ return ! this . ignoreSynchronization ;
437425 }
438426
439427 /**
@@ -602,15 +590,15 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
602590 * @template T
603591 */
604592 private executeAsyncScript_ ( script : string | Function , description : string , ...scriptArgs : any [ ] ) :
605- wdpromise . Promise < any > {
593+ Promise < any > {
606594 if ( typeof script === 'function' ) {
607595 script = 'return (' + script + ').apply(null, arguments);' ;
608596 }
609597 return this . driver . schedule (
610- new Command ( CommandName . EXECUTE_ASYNC_SCRIPT )
611- . setParameter ( 'script' , script )
612- . setParameter ( 'args' , scriptArgs ) ,
613- description ) ;
598+ new Command ( CommandName . EXECUTE_ASYNC_SCRIPT )
599+ . setParameter ( 'script' , script )
600+ . setParameter ( 'args' , scriptArgs ) ,
601+ description ) as Promise < any > ;
614602 }
615603
616604 /**
@@ -624,116 +612,90 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
624612 * @returns {!webdriver.promise.Promise } A promise that will resolve to the
625613 * scripts return value.
626614 */
627- waitForAngular ( opt_description ?: string ) : wdpromise . Promise < any > {
615+ async waitForAngular ( opt_description ?: string ) : Promise < any > {
628616 let description = opt_description ? ' - ' + opt_description : '' ;
629617 if ( this . ignoreSynchronization ) {
630- return this . driver . controlFlow ( ) . execute ( ( ) => {
631- return true ;
632- } , 'Ignore Synchronization Protractor.waitForAngular()' ) ;
618+ return true ;
633619 }
634620
635- let runWaitForAngularScript : ( ) => wdpromise . Promise < any > = ( ) => {
621+ let runWaitForAngularScript = async ( ) : Promise < any > => {
636622 if ( this . plugins_ . skipAngularStability ( ) || this . bpClient ) {
637- return this . driver . controlFlow ( ) . execute ( ( ) => {
638- return wdpromise . when ( null ) ;
639- } , 'bpClient or plugin stability override' ) ;
623+ return null ;
640624 } else {
641- // Need to wrap this so that we read rootEl in the control flow, not synchronously.
642- return this . angularAppRoot ( ) . then ( ( rootEl : string ) => {
643- return this . executeAsyncScript_ (
644- clientSideScripts . waitForAngular , 'Protractor.waitForAngular()' + description ,
645- rootEl ) ;
646- } ) ;
625+ let rootEl = await this . angularAppRoot ( ) ;
626+ return this . executeAsyncScript_ (
627+ clientSideScripts . waitForAngular , `Protractor.waitForAngular() ${ description } ` , rootEl ) ;
647628 }
648629 } ;
649630
650- return runWaitForAngularScript ( )
651- . then ( ( browserErr : Function ) => {
652- if ( browserErr ) {
653- throw new Error (
654- 'Error while waiting for Protractor to ' +
655- 'sync with the page: ' + JSON . stringify ( browserErr ) ) ;
631+ try {
632+ let browserErr = await runWaitForAngularScript ( ) ;
633+ if ( browserErr ) {
634+ throw new Error (
635+ 'Error while waiting for Protractor to ' +
636+ 'sync with the page: ' + JSON . stringify ( browserErr ) ) ;
637+ }
638+ await this . plugins_ . waitForPromise ( this ) ;
639+
640+ await this . driver . wait ( async ( ) => {
641+ let results = await this . plugins_ . waitForCondition ( this ) ;
642+ return results . reduce ( ( x , y ) => x && y , true ) ;
643+ } , this . allScriptsTimeout , 'Plugins.waitForCondition()' ) ;
644+ } catch ( err ) {
645+ let timeout : RegExpExecArray ;
646+ if ( / a s y n c h r o n o u s s c r i p t t i m e o u t / . test ( err . message ) ) {
647+ // Timeout on Chrome
648+ timeout = / - ? [ \d \. ] * \ s e c o n d s / . exec ( err . message ) ;
649+ } else if ( / T i m e d o u t w a i t i n g f o r a s y n c s c r i p t / . test ( err . message ) ) {
650+ // Timeout on Firefox
651+ timeout = / - ? [ \d \. ] * m s / . exec ( err . message ) ;
652+ } else if ( / T i m e d o u t w a i t i n g f o r a n a s y n c h r o n o u s s c r i p t / . test ( err . message ) ) {
653+ // Timeout on Safari
654+ timeout = / - ? [ \d \. ] * \ m s / . exec ( err . message ) ;
655+ }
656+ if ( timeout ) {
657+ let errMsg = `Timed out waiting for asynchronous Angular tasks to finish after ` +
658+ `${ timeout } . This may be because the current page is not an Angular ` +
659+ `application. Please see the FAQ for more details: ` +
660+ `https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular` ;
661+ if ( description . indexOf ( ' - Locator: ' ) == 0 ) {
662+ errMsg += '\nWhile waiting for element with locator' + description ;
663+ }
664+ let pendingTimeoutsPromise : wdpromise . Promise < any > ;
665+ if ( this . trackOutstandingTimeouts_ ) {
666+ pendingTimeoutsPromise = this . executeScriptWithDescription (
667+ 'return window.NG_PENDING_TIMEOUTS' ,
668+ 'Protractor.waitForAngular() - getting pending timeouts' + description ) ;
669+ } else {
670+ pendingTimeoutsPromise = wdpromise . when ( { } ) ;
671+ }
672+ let pendingHttpsPromise = this . executeScriptWithDescription (
673+ clientSideScripts . getPendingHttpRequests ,
674+ 'Protractor.waitForAngular() - getting pending https' + description ,
675+ this . internalRootEl ) ;
676+
677+ let arr = await Promise . all ( [ pendingTimeoutsPromise , pendingHttpsPromise ] ) ;
678+
679+ let pendingTimeouts = arr [ 0 ] || [ ] ;
680+ let pendingHttps = arr [ 1 ] || [ ] ;
681+
682+ let key : string , pendingTasks : string [ ] = [ ] ;
683+ for ( key in pendingTimeouts ) {
684+ if ( pendingTimeouts . hasOwnProperty ( key ) ) {
685+ pendingTasks . push ( ' - $timeout: ' + pendingTimeouts [ key ] ) ;
656686 }
657- } )
658- . then (
659- ( ) => {
660- return this . driver . controlFlow ( )
661- . execute (
662- ( ) => {
663- return this . plugins_ . waitForPromise ( this ) ;
664- } ,
665- 'Plugins.waitForPromise()' )
666- . then ( ( ) => {
667- return this . driver . wait ( ( ) => {
668- return this . plugins_ . waitForCondition ( this ) . then ( ( results : boolean [ ] ) => {
669- return results . reduce ( ( x , y ) => x && y , true ) ;
670- } ) ;
671- } , this . allScriptsTimeout , 'Plugins.waitForCondition()' ) ;
672- } ) ;
673- } ,
674- ( err : Error ) => {
675- let timeout : RegExpExecArray ;
676- if ( / a s y n c h r o n o u s s c r i p t t i m e o u t / . test ( err . message ) ) {
677- // Timeout on Chrome
678- timeout = / - ? [ \d \. ] * \ s e c o n d s / . exec ( err . message ) ;
679- } else if ( / T i m e d o u t w a i t i n g f o r a s y n c s c r i p t / . test ( err . message ) ) {
680- // Timeout on Firefox
681- timeout = / - ? [ \d \. ] * m s / . exec ( err . message ) ;
682- } else if ( / T i m e d o u t w a i t i n g f o r a n a s y n c h r o n o u s s c r i p t / . test ( err . message ) ) {
683- // Timeout on Safari
684- timeout = / - ? [ \d \. ] * \ m s / . exec ( err . message ) ;
685- }
686- if ( timeout ) {
687- let errMsg = `Timed out waiting for asynchronous Angular tasks to finish after ` +
688- `${ timeout } . This may be because the current page is not an Angular ` +
689- `application. Please see the FAQ for more details: ` +
690- `https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular` ;
691- if ( description . indexOf ( ' - Locator: ' ) == 0 ) {
692- errMsg += '\nWhile waiting for element with locator' + description ;
693- }
694- let pendingTimeoutsPromise : wdpromise . Promise < any > ;
695- if ( this . trackOutstandingTimeouts_ ) {
696- pendingTimeoutsPromise = this . executeScriptWithDescription (
697- 'return window.NG_PENDING_TIMEOUTS' ,
698- 'Protractor.waitForAngular() - getting pending timeouts' + description ) ;
699- } else {
700- pendingTimeoutsPromise = wdpromise . when ( { } ) ;
701- }
702- let pendingHttpsPromise = this . executeScriptWithDescription (
703- clientSideScripts . getPendingHttpRequests ,
704- 'Protractor.waitForAngular() - getting pending https' + description ,
705- this . internalRootEl ) ;
706-
707- return wdpromise . all ( [ pendingTimeoutsPromise , pendingHttpsPromise ] )
708- . then (
709- ( arr : any [ ] ) => {
710- let pendingTimeouts = arr [ 0 ] || [ ] ;
711- let pendingHttps = arr [ 1 ] || [ ] ;
712-
713- let key : string , pendingTasks : string [ ] = [ ] ;
714- for ( key in pendingTimeouts ) {
715- if ( pendingTimeouts . hasOwnProperty ( key ) ) {
716- pendingTasks . push ( ' - $timeout: ' + pendingTimeouts [ key ] ) ;
717- }
718- }
719- for ( key in pendingHttps ) {
720- pendingTasks . push ( ' - $http: ' + pendingHttps [ key ] . url ) ;
721- }
722- if ( pendingTasks . length ) {
723- errMsg += '. \nThe following tasks were pending:\n' ;
724- errMsg += pendingTasks . join ( '\n' ) ;
725- }
726- err . message = errMsg ;
727- throw err ;
728- } ,
729- ( ) => {
730- err . message = errMsg ;
731- throw err ;
732- } ) ;
733- } else {
734- throw err ;
735- }
736- } ) ;
687+ }
688+ for ( key in pendingHttps ) {
689+ pendingTasks . push ( ' - $http: ' + pendingHttps [ key ] . url ) ;
690+ }
691+ if ( pendingTasks . length ) {
692+ errMsg += '. \nThe following tasks were pending:\n' ;
693+ errMsg += pendingTasks . join ( '\n' ) ;
694+ }
695+ err . message = errMsg ;
696+ }
697+ throw err ;
698+ }
737699 }
738700
739701 /**
@@ -978,16 +940,14 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver {
978940 . then ( ( ) => {
979941 // Reset bpClient sync
980942 if ( this . bpClient ) {
981- return this . driver . controlFlow ( ) . execute ( ( ) => {
982- return this . bpClient . setWaitEnabled ( ! this . internalIgnoreSynchronization ) ;
983- } ) ;
943+ return this . bpClient . setWaitEnabled ( ! this . internalIgnoreSynchronization ) ;
984944 }
985945 } )
986946 . then ( ( ) => {
987947 // Run Plugins
988- return this . driver . controlFlow ( ) . execute ( ( ) => {
948+ if ( ! this . ignoreSynchronization ) {
989949 return this . plugins_ . onPageStable ( this ) ;
990- } ) ;
950+ }
991951 } )
992952 . then ( ( ) => null ) ;
993953 }
0 commit comments