1+ import { BPClient } from 'blocking-proxy' ;
12import { ActionSequence , By , Capabilities , Command as WdCommand , FileDetector , ICommandName , Options , promise as wdpromise , Session , TargetLocator , TouchSequence , until , WebDriver , WebElement } from 'selenium-webdriver' ;
23import * as url from 'url' ;
34
@@ -141,6 +142,12 @@ export class ProtractorBrowser extends Webdriver {
141142 */
142143 driver : WebDriver ;
143144
145+ /**
146+ * The client used to control the BlockingProxy. If unset, BlockingProxy is
147+ * not being used and Protractor will handle client-side synchronization.
148+ */
149+ bpClient : BPClient ;
150+
144151 /**
145152 * Helper function for finding elements.
146153 *
@@ -186,9 +193,26 @@ export class ProtractorBrowser extends Webdriver {
186193 * tests to become flaky. This should be used only when necessary, such as
187194 * when a page continuously polls an API using $timeout.
188195 *
196+ * This property is deprecated - please use waitForAngularEnabled instead.
197+ *
198+ * @deprecated
189199 * @type {boolean }
190200 */
191- ignoreSynchronization : boolean ;
201+ set ignoreSynchronization ( value ) {
202+ this . driver . controlFlow ( ) . execute ( ( ) => {
203+ if ( this . bpClient ) {
204+ logger . debug ( 'Setting waitForAngular' + value ) ;
205+ this . bpClient . setSynchronization ( ! value ) ;
206+ }
207+ } , `Set proxy synchronization to ${ value } ` ) ;
208+ this . internalIgnoreSynchronization = value ;
209+ }
210+
211+ get ignoreSynchronization ( ) {
212+ return this . internalIgnoreSynchronization ;
213+ }
214+
215+ internalIgnoreSynchronization : boolean ;
192216
193217 /**
194218 * Timeout in milliseconds to wait for pages to load when calling `get`.
@@ -272,7 +296,7 @@ export class ProtractorBrowser extends Webdriver {
272296
273297 constructor (
274298 webdriverInstance : WebDriver , opt_baseUrl ?: string , opt_rootElement ?: string ,
275- opt_untrackOutstandingTimeouts ?: boolean ) {
299+ opt_untrackOutstandingTimeouts ?: boolean , opt_blockingProxyUrl ?: string ) {
276300 super ( ) ;
277301 // These functions should delegate to the webdriver instance, but should
278302 // wait for Angular to sync up before performing the action. This does not
@@ -291,6 +315,10 @@ export class ProtractorBrowser extends Webdriver {
291315 } ) ;
292316
293317 this . driver = webdriverInstance ;
318+ if ( opt_blockingProxyUrl ) {
319+ logger . info ( 'Starting BP client for ' + opt_blockingProxyUrl ) ;
320+ this . bpClient = new BPClient ( opt_blockingProxyUrl ) ;
321+ }
294322 this . element = buildElementHelper ( this ) ;
295323 this . $ = build$ ( this . element , By ) ;
296324 this . $$ = build$$ ( this . element , By ) ;
@@ -325,6 +353,22 @@ export class ProtractorBrowser extends Webdriver {
325353 this . ExpectedConditions = new ProtractorExpectedConditions ( this ) ;
326354 }
327355
356+ /**
357+ * If set to false, Protractor will not wait for Angular $http and $timeout
358+ * tasks to complete before interacting with the browser. This can cause
359+ * flaky tests, but should be used if, for instance, your app continuously
360+ * polls an API with $timeout.
361+ *
362+ * Call waitForAngularEnabled() without passing a value to read the current
363+ * state without changing it.
364+ */
365+ waitForAngularEnabled ( enabled : boolean = null ) : boolean {
366+ if ( enabled != null ) {
367+ this . ignoreSynchronization = ! enabled ;
368+ }
369+ return ! this . ignoreSynchronization ;
370+ }
371+
328372 /**
329373 * Get the processed configuration object that is currently being run. This
330374 * will contain the specs and capabilities properties of the current runner
@@ -445,7 +489,7 @@ export class ProtractorBrowser extends Webdriver {
445489 }
446490
447491 let runWaitForAngularScript : ( ) => wdpromise . Promise < any > = ( ) => {
448- if ( this . plugins_ . skipAngularStability ( ) ) {
492+ if ( this . plugins_ . skipAngularStability ( ) || this . bpClient ) {
449493 return wdpromise . fulfilled ( ) ;
450494 } else if ( this . rootEl ) {
451495 return this . executeAsyncScript_ (
@@ -668,6 +712,12 @@ export class ProtractorBrowser extends Webdriver {
668712 return 'Protractor.get(' + destination + ') - ' + str ;
669713 } ;
670714
715+ if ( this . bpClient ) {
716+ this . driver . controlFlow ( ) . execute ( ( ) => {
717+ return this . bpClient . setSynchronization ( false ) ;
718+ } ) ;
719+ }
720+
671721 if ( this . ignoreSynchronization ) {
672722 this . driver . get ( destination ) ;
673723 return this . driver . controlFlow ( ) . execute ( ( ) => this . plugins_ . onPageLoad ( ) ) . then ( ( ) => { } ) ;
@@ -768,6 +818,12 @@ export class ProtractorBrowser extends Webdriver {
768818 }
769819 }
770820
821+ if ( this . bpClient ) {
822+ this . driver . controlFlow ( ) . execute ( ( ) => {
823+ return this . bpClient . setSynchronization ( ! this . internalIgnoreSynchronization ) ;
824+ } ) ;
825+ }
826+
771827 this . driver . controlFlow ( ) . execute ( ( ) => {
772828 return this . plugins_ . onPageStable ( ) . then ( ( ) => {
773829 deferred . fulfill ( ) ;
0 commit comments