fix(build): Use Angular's testability API to wait for end of e2e tests

Closes #3911
This commit is contained in:
Marc Laval 2015-08-27 17:44:59 +02:00
parent 00a4b2e28f
commit 33593cf8a2
19 changed files with 102 additions and 41 deletions

View File

@ -63,6 +63,10 @@ class PublicTestability implements _JsObjectProxyable {
this._testability = testability;
}
bool isStable() {
return this._testability.isStable();
}
whenStable(Function callback) {
return this._testability.whenStable(callback);
}
@ -75,7 +79,8 @@ class PublicTestability implements _JsObjectProxyable {
return _jsify({
'findBindings': (bindingString, [exactMatch, allowNonElementNodes]) =>
findBindings(bindingString, exactMatch, allowNonElementNodes),
'whenStable': (callback) => whenStable(() => callback.apply([])),
'isStable': () => isStable(),
'whenStable': (callback) => whenStable(() => callback.apply([]))
})..['_dart_'] = this;
}
}

View File

@ -11,6 +11,8 @@ class PublicTestability {
constructor(testability: Testability) { this._testability = testability; }
isStable(): boolean { return this._testability.isStable(); }
whenStable(callback: Function) { this._testability.whenStable(callback); }
findBindings(using: any, binding: string, exactMatch: boolean): any[] {

View File

@ -42,8 +42,10 @@ export class Testability {
return this._pendingCount;
}
isStable(): boolean { return this._pendingCount == 0 && !this._isAngularEventPending; }
_runCallbacksIfReady(): void {
if (this._pendingCount != 0 || this._isAngularEventPending) {
if (!this.isStable()) {
return; // Not ready
}

View File

@ -24,7 +24,9 @@ export function runBenchmark(config) {
});
}
var url = encodeURI(config.url + '?' + urlParams.join('&'));
return browser.get(url).then(function() {
var getter = config.waitForAngular2 !== false ? browser.get(url) :
browser.driver.get(browser.baseUrl + url);
return getter.then(function() {
return global['benchpressRunner'].sample({
id: config.id,
execute: config.work,

View File

@ -15,7 +15,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -28,7 +29,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -41,7 +43,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -54,7 +57,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -67,7 +71,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -80,7 +85,8 @@ describe('ng2 change detection benchmark', function() {
{name: 'numberOfChecks', value: 900000},
{name: 'iterations', value: 20, scale: 'linear'}
],
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'}
microMetrics: {'detectChangesAvg': 'avg time to detect changes (ms)'},
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -12,7 +12,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#getByToken'],
id: 'ng2.di.getByToken',
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for injection (in ms)'}
microMetrics: {'injectAvg': 'avg time for injection (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -22,7 +23,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#getByKey'],
id: 'ng2.di.getByKey',
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for injection (in ms)'}
microMetrics: {'injectAvg': 'avg time for injection (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -32,7 +34,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#getChild'],
id: 'ng2.di.getChild',
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for getChild (in ms)'}
microMetrics: {'injectAvg': 'avg time for getChild (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -42,7 +45,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#instantiate'],
id: 'ng2.di.instantiate',
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for instantiate (in ms)'}
microMetrics: {'injectAvg': 'avg time for instantiate (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -56,7 +60,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#createVariety'],
id: 'ng2.di.createVariety',
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for createVariety (in ms)'}
microMetrics: {'injectAvg': 'avg time for createVariety (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -69,7 +74,8 @@ describe('ng2 di benchmark', function() {
buttons: ['#createVarietyResolved'],
id: 'ng2.di.createVarietyResolved',
params: [{name: 'iterations', value: 10000, scale: 'linear'}],
microMetrics: {'injectAvg': 'avg time for createVarietyResolved (in ms)'}
microMetrics: {'injectAvg': 'avg time for createVarietyResolved (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -12,7 +12,8 @@ describe('ng2 element injector benchmark', function() {
buttons: ['#instantiate'],
id: 'ng2.elementInjector.instantiate',
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'}
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});
@ -22,7 +23,8 @@ describe('ng2 element injector benchmark', function() {
buttons: ['#hydrate'],
id: 'ng2.elementInjector.hydrate',
params: [{name: 'iterations', value: 20000, scale: 'linear'}],
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'}
microMetrics: {'instantiateAvg': 'avg time for injection (in ms)'},
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -11,7 +11,8 @@ describe('ng2 selector benchmark', function() {
url: URL,
buttons: ['#parse'],
id: 'ng2.selector.parse',
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
params: [{name: 'selectors', value: 10000, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});
@ -20,7 +21,8 @@ describe('ng2 selector benchmark', function() {
url: URL,
buttons: ['#addSelectable'],
id: 'ng2.selector.addSelectable',
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
params: [{name: 'selectors', value: 10000, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});
@ -29,7 +31,8 @@ describe('ng2 selector benchmark', function() {
url: URL,
buttons: ['#match'],
id: 'ng2.selector.match',
params: [{name: 'selectors', value: 10000, scale: 'linear'}]
params: [{name: 'selectors', value: 10000, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -11,7 +11,8 @@ describe('ng1.x compiler benchmark', function() {
url: URL,
buttons: ['#compileWithBindings'],
id: 'ng1.compile.withBindings',
params: [{name: 'elements', value: 150, scale: 'linear'}]
params: [{name: 'elements', value: 150, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});
@ -20,7 +21,8 @@ describe('ng1.x compiler benchmark', function() {
url: URL,
buttons: ['#compileNoBindings'],
id: 'ng1.compile.noBindings',
params: [{name: 'elements', value: 150, scale: 'linear'}]
params: [{name: 'elements', value: 150, scale: 'linear'}],
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -17,7 +17,8 @@ describe('ng1.x largetable benchmark', function() {
{name: 'columns', value: 100, scale: 'sqrt'},
{name: 'rows', value: 20, scale: 'sqrt'},
{name: 'benchmarkType', value: benchmarkType}
]
],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -24,7 +24,8 @@ describe('ng-dart1.x naive infinite scroll benchmark', function() {
{name: 'appSize', value: appSize},
{name: 'iterationCount', value: 20, scale: 'linear'},
{name: 'scrollIncrement', value: 40}
]
],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -11,7 +11,8 @@ describe('polymer tree benchmark', function() {
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'polymer.tree',
params: [{name: 'depth', value: 9, scale: 'log2'}]
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -11,7 +11,8 @@ describe('react tree benchmark', function() {
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'react.tree.create',
params: [{name: 'depth', value: 9, scale: 'log2'}]
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});
@ -20,7 +21,8 @@ describe('react tree benchmark', function() {
url: URL,
buttons: ['#createDom'],
id: 'react.tree.update',
params: [{name: 'depth', value: 9, scale: 'log2'}]
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -7,9 +7,13 @@ describe('ng1.x tree benchmark', function() {
afterEach(verifyNoBrowserErrors);
it('should log the stats', function(done) {
runClickBenchmark(
{url: URL, buttons: ['#destroyDom', '#createDom'], id: 'ng1.static.tree', params: []})
.then(done, done.fail);
runClickBenchmark({
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'ng1.static.tree',
params: [],
waitForAngular2: false
}).then(done, done.fail);
});
});

View File

@ -11,7 +11,8 @@ describe('ng1.x tree benchmark', function() {
url: URL,
buttons: ['#destroyDom', '#createDom'],
id: 'ng1.tree',
params: [{name: 'depth', value: 9, scale: 'log2'}]
params: [{name: 'depth', value: 9, scale: 'log2'}],
waitForAngular2: false
}).then(done, done.fail);
});

View File

@ -4,17 +4,19 @@ import {Promise} from 'angular2/src/core/facade/async';
describe('WebWorkers Kitchen Sink', function() {
afterEach(verifyNoBrowserErrors);
var selector = "hello-app .greeting";
var URL = "examples/src/web_workers/kitchen_sink/index.html";
var URL = browser.baseUrl + "examples/src/web_workers/kitchen_sink/index.html";
it('should greet', () => {
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
browser.wait(protractor.until.elementLocated(by.css(selector)), 15000);
expect(element.all(by.css(selector)).first().getText()).toEqual("hello world!");
});
it('should change greeting', () => {
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
browser.wait(protractor.until.elementLocated(by.css(selector)), 15000);
element(by.css("hello-app .changeButton")).click();
@ -24,7 +26,8 @@ describe('WebWorkers Kitchen Sink', function() {
});
it("should display correct key names", () => {
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
browser.wait(protractor.until.elementLocated(by.css(".sample-area")), 15000);
var area = element.all(by.css(".sample-area")).first();

View File

@ -1,21 +1,23 @@
import {verifyNoBrowserErrors} from "angular2/src/test_lib/e2e_util";
import {PromiseWrapper} from "angular2/src/core/facade/async";
var URL = "examples/src/web_workers/message_broker/index.html";
var URL = browser.baseUrl + 'examples/src/web_workers/message_broker/index.html';
describe("MessageBroker", function() {
afterEach(verifyNoBrowserErrors);
it("should bootstrap", () => {
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
waitForBootstrap();
expect(element(by.css("app h1")).getText()).toEqual("WebWorker MessageBroker Test");
});
it("should echo messages", () => {
const VALUE = "Hi There";
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
waitForBootstrap();
var input = element.all(by.css("#echo_input")).first();

View File

@ -4,10 +4,11 @@ import {Promise} from 'angular2/src/core/facade/async';
describe('WebWorkers Todo', function() {
afterEach(verifyNoBrowserErrors);
var URL = "examples/src/web_workers/todo/index.html";
var URL = browser.baseUrl + "examples/src/web_workers/todo/index.html";
it('should bootstrap', () => {
browser.get(URL);
// This test can't wait for Angular 2 as Testability is not available when using WebWorker
browser.driver.get(URL);
waitForBootstrap();
expect(element(by.css("#todoapp header")).getText()).toEqual("todos");

View File

@ -188,11 +188,26 @@ var config = exports.config = {
// and the sleeps in all tests.
function patchProtractorWait(browser) {
browser.ignoreSynchronization = true;
// Benchmarks never need to wait for Angular 2 to be ready
var _get = browser.get;
var sleepInterval = process.env.TRAVIS || process.env.JENKINS_URL ? 14000 : 8000;
browser.get = function() {
var result = _get.apply(this, arguments);
browser.driver.wait(protractor.until.elementLocated(By.js('var cs = document.body.children; var isLoading = false; for (var i = 0; i < cs.length; i++) {if (cs[i].textContent.indexOf("Loading...") > -1) isLoading = true; } return !isLoading ? document.body.children : null')), sleepInterval);
browser.driver.wait(protractor.until.elementLocated(By.js(function() {
var isLoading = true;
if (window.getAllAngularTestabilities) {
var testabilities = window.getAllAngularTestabilities();
if (testabilities && testabilities.length > 0) {
isLoading = false;
testabilities.forEach(function(testability) {
if (!testability.isStable()) {
isLoading = true;
}
});
}
}
return !isLoading ? document.body.children : null;
})), sleepInterval);
return result;
}
}