From 0be0d03abb4eb9ced1a0c071dd05394d67f67800 Mon Sep 17 00:00:00 2001 From: Michael Giambalvo Date: Fri, 20 Jan 2017 17:44:02 -0800 Subject: [PATCH 1/3] Wrap reading rootEl in the control flow. --- lib/bpRunner.ts | 3 +-- lib/browser.ts | 49 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/bpRunner.ts b/lib/bpRunner.ts index bfab4514c..27a6289b9 100644 --- a/lib/bpRunner.ts +++ b/lib/bpRunner.ts @@ -19,8 +19,7 @@ export class BlockingProxyRunner { this.checkSupportedConfig(); let args = [ - '--fork', '--seleniumAddress', this.config.seleniumAddress, '--rootElement', - this.config.rootElement + '--fork', '--seleniumAddress', this.config.seleniumAddress, ]; this.bpProcess = fork(BP_PATH, args, {silent: true}); logger.info('Starting BlockingProxy with args: ' + args.toString()); diff --git a/lib/browser.ts b/lib/browser.ts index 174272ae2..0d4c2a946 100644 --- a/lib/browser.ts +++ b/lib/browser.ts @@ -189,9 +189,39 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { * 'body' but if your ng-app is on a subsection of the page it may be * a subelement. * + * This property is deprecated - please use setAngularAppRoot() instead. + * + * @deprecated * @type {string} */ - rootEl: string; + set rootEl(value: string) { + this.driver.controlFlow().execute(() => { + if (this.bpClient) { + this.bpClient.setWaitParams(value); + } + this.internalRootEl = value; + }, `Set angular root selector to ${value}`); + } + + get rootEl() { + return this.internalRootEl; + } + + private internalRootEl: string; + + /** + * Set the css selector for an element on which to find Angular. This is usually + * 'body' but if your ng-app is on a subsection of the page it may be + * a subelement. + * + * The change will be made within WebDriver's control flow, so that commands after + * this method is called use the new app root. + * + * @param {string} The new selector. + */ + setAngularAppRoot(value: string) { + this.rootEl = value; + } /** * If true, Protractor will not attempt to synchronize with the page before @@ -209,7 +239,7 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { this.driver.controlFlow().execute(() => { if (this.bpClient) { logger.debug('Setting waitForAngular' + value); - this.bpClient.setSynchronization(!value); + this.bpClient.setWaitEnabled(!value); } }, `Set proxy synchronization to ${value}`); this.internalIgnoreSynchronization = value; @@ -219,7 +249,7 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { return this.internalIgnoreSynchronization; } - internalIgnoreSynchronization: boolean; + private internalIgnoreSynchronization: boolean; /** * Timeout in milliseconds to wait for pages to load when calling `get`. @@ -524,9 +554,12 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { if (this.plugins_.skipAngularStability() || this.bpClient) { return wdpromise.fulfilled(); } else { - return this.executeAsyncScript_( - clientSideScripts.waitForAngular, 'Protractor.waitForAngular()' + description, - this.rootEl); + // Need to wrap this so that we read rootEl in the control flow, not synchronously. + return this.driver.controlFlow().execute(() => { + return this.executeAsyncScript_( + clientSideScripts.waitForAngular, 'Protractor.waitForAngular()' + description, + this.rootEl); + }); } }; @@ -748,7 +781,7 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { if (this.bpClient) { this.driver.controlFlow().execute(() => { - return this.bpClient.setSynchronization(false); + return this.bpClient.setWaitEnabled(false); }); } @@ -856,7 +889,7 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { if (this.bpClient) { this.driver.controlFlow().execute(() => { - return this.bpClient.setSynchronization(!this.internalIgnoreSynchronization); + return this.bpClient.setWaitEnabled(!this.internalIgnoreSynchronization); }); } From 3e937f2fee7a2a7ef22de3671a867d73ebde6d85 Mon Sep 17 00:00:00 2001 From: Michael Giambalvo Date: Sat, 21 Jan 2017 12:41:36 -0800 Subject: [PATCH 2/3] Update to BlockingProxy 0.0.3, which allows changing rootSelector. This will fail until 0.0.3 is published. --- lib/bpRunner.ts | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/bpRunner.ts b/lib/bpRunner.ts index 27a6289b9..d0b68ccd7 100644 --- a/lib/bpRunner.ts +++ b/lib/bpRunner.ts @@ -19,7 +19,9 @@ export class BlockingProxyRunner { this.checkSupportedConfig(); let args = [ - '--fork', '--seleniumAddress', this.config.seleniumAddress, + '--fork', + '--seleniumAddress', + this.config.seleniumAddress, ]; this.bpProcess = fork(BP_PATH, args, {silent: true}); logger.info('Starting BlockingProxy with args: ' + args.toString()); diff --git a/package.json b/package.json index 3aad3ca5b..f98761abf 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@types/node": "^6.0.46", "@types/q": "^0.0.32", "@types/selenium-webdriver": "~2.53.39", - "blocking-proxy": "0.0.2", + "blocking-proxy": "0.0.3", "chalk": "^1.1.3", "glob": "^7.0.3", "jasmine": "2.4.1", From 7837aeecd30ea60839e0c370ddb2c9dc3d787e99 Mon Sep 17 00:00:00 2001 From: Michael Giambalvo Date: Thu, 26 Jan 2017 12:20:24 -0800 Subject: [PATCH 3/3] Make angularAppRoot() return a promise. --- lib/browser.ts | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/browser.ts b/lib/browser.ts index 0d4c2a946..55065f537 100644 --- a/lib/browser.ts +++ b/lib/browser.ts @@ -189,18 +189,13 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { * 'body' but if your ng-app is on a subsection of the page it may be * a subelement. * - * This property is deprecated - please use setAngularAppRoot() instead. + * This property is deprecated - please use angularAppRoot() instead. * * @deprecated * @type {string} */ set rootEl(value: string) { - this.driver.controlFlow().execute(() => { - if (this.bpClient) { - this.bpClient.setWaitParams(value); - } - this.internalRootEl = value; - }, `Set angular root selector to ${value}`); + this.angularAppRoot(value); } get rootEl() { @@ -215,12 +210,22 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { * a subelement. * * The change will be made within WebDriver's control flow, so that commands after - * this method is called use the new app root. + * this method is called use the new app root. Pass nothing to get a promise that + * resolves to the value of the selector. * * @param {string} The new selector. + * @returns A promise that resolves with the value of the selector. */ - setAngularAppRoot(value: string) { - this.rootEl = value; + angularAppRoot(value: string = null): wdpromise.Promise { + return this.driver.controlFlow().execute(() => { + if (value != null) { + if (this.bpClient) { + return this.bpClient.setWaitParams(value).then(() => this.internalRootEl); + } + this.internalRootEl = value; + return this.internalRootEl; + } + }, `Set angular root selector to ${value}`); } /** @@ -239,7 +244,7 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { this.driver.controlFlow().execute(() => { if (this.bpClient) { logger.debug('Setting waitForAngular' + value); - this.bpClient.setWaitEnabled(!value); + return this.bpClient.setWaitEnabled(!value); } }, `Set proxy synchronization to ${value}`); this.internalIgnoreSynchronization = value; @@ -555,10 +560,10 @@ export class ProtractorBrowser extends AbstractExtendedWebDriver { return wdpromise.fulfilled(); } else { // Need to wrap this so that we read rootEl in the control flow, not synchronously. - return this.driver.controlFlow().execute(() => { + return this.angularAppRoot().then((rootEl: string) => { return this.executeAsyncScript_( clientSideScripts.waitForAngular, 'Protractor.waitForAngular()' + description, - this.rootEl); + rootEl); }); } };