1
+ import { BPClient } from 'blocking-proxy' ;
1
2
import { ActionSequence , By , Capabilities , Command as WdCommand , FileDetector , ICommandName , Options , promise as wdpromise , Session , TargetLocator , TouchSequence , until , WebDriver , WebElement } from 'selenium-webdriver' ;
2
3
import * as url from 'url' ;
3
4
@@ -141,6 +142,12 @@ export class ProtractorBrowser extends Webdriver {
141
142
*/
142
143
driver : WebDriver ;
143
144
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
+
144
151
/**
145
152
* Helper function for finding elements.
146
153
*
@@ -186,9 +193,26 @@ export class ProtractorBrowser extends Webdriver {
186
193
* tests to become flaky. This should be used only when necessary, such as
187
194
* when a page continuously polls an API using $timeout.
188
195
*
196
+ * This property is deprecated - please use waitForAngularEnabled instead.
197
+ *
198
+ * @deprecated
189
199
* @type {boolean }
190
200
*/
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 ;
192
216
193
217
/**
194
218
* Timeout in milliseconds to wait for pages to load when calling `get`.
@@ -272,7 +296,7 @@ export class ProtractorBrowser extends Webdriver {
272
296
273
297
constructor (
274
298
webdriverInstance : WebDriver , opt_baseUrl ?: string , opt_rootElement ?: string ,
275
- opt_untrackOutstandingTimeouts ?: boolean ) {
299
+ opt_untrackOutstandingTimeouts ?: boolean , opt_blockingProxyUrl ?: string ) {
276
300
super ( ) ;
277
301
// These functions should delegate to the webdriver instance, but should
278
302
// wait for Angular to sync up before performing the action. This does not
@@ -291,6 +315,10 @@ export class ProtractorBrowser extends Webdriver {
291
315
} ) ;
292
316
293
317
this . driver = webdriverInstance ;
318
+ if ( opt_blockingProxyUrl ) {
319
+ logger . info ( 'Starting BP client for ' + opt_blockingProxyUrl ) ;
320
+ this . bpClient = new BPClient ( opt_blockingProxyUrl ) ;
321
+ }
294
322
this . element = buildElementHelper ( this ) ;
295
323
this . $ = build$ ( this . element , By ) ;
296
324
this . $$ = build$$ ( this . element , By ) ;
@@ -325,6 +353,22 @@ export class ProtractorBrowser extends Webdriver {
325
353
this . ExpectedConditions = new ProtractorExpectedConditions ( this ) ;
326
354
}
327
355
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
+
328
372
/**
329
373
* Get the processed configuration object that is currently being run. This
330
374
* will contain the specs and capabilities properties of the current runner
@@ -445,7 +489,7 @@ export class ProtractorBrowser extends Webdriver {
445
489
}
446
490
447
491
let runWaitForAngularScript : ( ) => wdpromise . Promise < any > = ( ) => {
448
- if ( this . plugins_ . skipAngularStability ( ) ) {
492
+ if ( this . plugins_ . skipAngularStability ( ) || this . bpClient ) {
449
493
return wdpromise . fulfilled ( ) ;
450
494
} else if ( this . rootEl ) {
451
495
return this . executeAsyncScript_ (
@@ -668,6 +712,12 @@ export class ProtractorBrowser extends Webdriver {
668
712
return 'Protractor.get(' + destination + ') - ' + str ;
669
713
} ;
670
714
715
+ if ( this . bpClient ) {
716
+ this . driver . controlFlow ( ) . execute ( ( ) => {
717
+ return this . bpClient . setSynchronization ( false ) ;
718
+ } ) ;
719
+ }
720
+
671
721
if ( this . ignoreSynchronization ) {
672
722
this . driver . get ( destination ) ;
673
723
return this . driver . controlFlow ( ) . execute ( ( ) => this . plugins_ . onPageLoad ( ) ) . then ( ( ) => { } ) ;
@@ -768,6 +818,12 @@ export class ProtractorBrowser extends Webdriver {
768
818
}
769
819
}
770
820
821
+ if ( this . bpClient ) {
822
+ this . driver . controlFlow ( ) . execute ( ( ) => {
823
+ return this . bpClient . setSynchronization ( ! this . internalIgnoreSynchronization ) ;
824
+ } ) ;
825
+ }
826
+
771
827
this . driver . controlFlow ( ) . execute ( ( ) => {
772
828
return this . plugins_ . onPageStable ( ) . then ( ( ) => {
773
829
deferred . fulfill ( ) ;
0 commit comments