Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit c5d37c2

Browse files
committed
feat(lib): add useAllAngularAppRoots option
This allows waiting for all angular applications on the page, for angular2 apps only.
1 parent f246880 commit c5d37c2

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

lib/clientsidescripts.js

+29-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ function wrapWithHelpers(fun) {
3838

3939
/**
4040
* Wait until Angular has finished rendering and has
41-
* no outstanding $http calls before continuing.
41+
* no outstanding $http calls before continuing. The specific Angular app
42+
* is determined by the rootSelector.
4243
*
4344
* Asynchronous.
4445
*
@@ -72,6 +73,32 @@ functions.waitForAngular = function(rootSelector, callback) {
7273
}
7374
};
7475

76+
/**
77+
* Wait until all Angular2 applications on the page have become stable.
78+
*
79+
* Asynchronous.
80+
*
81+
* @param {function(string)} callback callback. If a failure occurs, it will
82+
* be passed as a parameter.
83+
*/
84+
functions.waitForAllAngular2 = function(callback) {
85+
try {
86+
var testabilities = window.getAllAngularTestabilities();
87+
var count = testabilities.length;
88+
var decrement = function() {
89+
count--;
90+
if (count === 0) {
91+
callback();
92+
}
93+
};
94+
testabilities.forEach(function(testability) {
95+
testability.whenStable(decrement);
96+
});
97+
} catch (err) {
98+
callback(err.message);
99+
}
100+
};
101+
75102
/**
76103
* Find a list of elements in the page by their angular binding.
77104
*
@@ -558,9 +585,8 @@ functions.findByCssContainingText = function(cssSelector, searchText, using) {
558585
* Asynchronous.
559586
*
560587
* @param {number} attempts Number of times to retry.
561-
* @param {function} asyncCallback callback
588+
* @param {function({version: ?number, message: ?string})} asyncCallback callback
562589
*
563-
* @return {{version: ?number, message: ?string}}
564590
*/
565591
functions.testForAngular = function(attempts, asyncCallback) {
566592
var callback = function(args) {

lib/protractor.js

+26-4
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,18 @@ Protractor.prototype.getProcessedConfig = null;
257257
*/
258258
Protractor.prototype.forkNewDriverInstance = null;
259259

260+
261+
/**
262+
* Instead of using a single root element, search through all angular apps
263+
* available on the page when finding elements or waiting for stability.
264+
* Only compatible with Angular2.
265+
*/
266+
Protractor.prototype.useAllAngular2AppRoots = function() {
267+
// The empty string is an invalid css selector, so we use it to easily
268+
// signal to scripts to not find a root element.
269+
this.rootEl = '';
270+
};
271+
260272
/**
261273
* The same as {@code webdriver.WebDriver.prototype.executeScript},
262274
* but with a customized description for debugging.
@@ -325,10 +337,20 @@ Protractor.prototype.waitForAngular = function(opt_description) {
325337
}, 'Ignore Synchronization Protractor.waitForAngular()');
326338
}
327339

328-
return this.executeAsyncScript_(
329-
clientSideScripts.waitForAngular,
330-
'Protractor.waitForAngular()' + description,
331-
this.rootEl).
340+
function runWaitForAngularScript() {
341+
if (self.rootEl) {
342+
return self.executeAsyncScript_(
343+
clientSideScripts.waitForAngular,
344+
'Protractor.waitForAngular()' + description,
345+
self.rootEl);
346+
} else {
347+
return self.executeAsyncScript_(
348+
clientSideScripts.waitForAllAngular2,
349+
'Protractor.waitForAngular()' + description);
350+
}
351+
}
352+
353+
return runWaitForAngularScript().
332354
then(function(browserErr) {
333355
if (browserErr) {
334356
throw 'Error while waiting for Protractor to ' +

lib/runner.js

+3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ Runner.prototype.createBrowser = function(plugins) {
197197
if (config.debuggerServerPort) {
198198
browser_.debuggerServerPort_ = config.debuggerServerPort;
199199
}
200+
if (config.useAllAngular2AppRoots) {
201+
browser_.useAllAngular2AppRoots();
202+
}
200203
var self = this;
201204

202205

spec/angular2Conf.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var env = require('./environment.js');
66
// As Angular2 is in rapid development, the test application that ships with
77
// the Protractor repository does not yet contain an Angular2 section. This
88
// configuration assumes that you are serving the examples from the
9-
// angular/angular repository at localhost:8000.
9+
// angular/angular repository at localhost:8000.
1010
// See https://github.com/angular/angular/blob/master/DEVELOPER.md for
1111
// setup instructions.
1212
//
@@ -25,5 +25,13 @@ exports.config = {
2525

2626
baseUrl: 'http://localhost:8000',
2727

28-
rootElement: 'async-app'
28+
// Special option for Angular2, to test against all Angular2 applications
29+
// on the page. This means that Protractor will wait for every app to be
30+
// stable before each action, and search within all apps when finding
31+
// elements.
32+
useAllAngular2AppRoots: true
33+
34+
// Alternatively, you could specify one root element application, to test
35+
// against only that one:
36+
// rootElement: 'async-app'
2937
};

0 commit comments

Comments
 (0)