Bug report
- Node Version:
7.4.0
- Protractor Version:
5.1.2
- Angular Version:
4.2.2
- Browser(s):
Chrome
- Operating System and Version
macOS 10.12
- Your protractor configuration file
// Protractor configuration file,
// see link for more information https://github.com/angular/protractor/blob/master/lib/config.ts
const {SpecReporter} = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 120000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome',
chromeOptions: {
'args': ['--js-flags=--expose-gc'],
'perfLoggingPrefs': {
'traceCategories': 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
}
},
loggingPrefs: {
performance: 'ALL',
browser: 'ALL'
}
},
directConnect: true,
baseUrl: 'http://localhost:4224/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
showTiming: true,
defaultTimeoutInterval: 120000,
print: () => {}
},
// Option for Angular to test against Angular 2+ applications on the page.
// Protractor will wait for the app to be stable before each action, and search within all apps when finding elements.
rootElement: 'infarm-app',
onPrepare: () => {
// Add jasmine spec reporter
jasmine.getEnv()
.addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
// Include jasmine expect
require('jasmine-expect');
// Transpile all TS to JS
require('ts-node')
.register({
project: 'e2e/tsconfig.e2e.json'
});
}
};
// home.po.ts
import {browser} from 'protractor';
export class HomePage {
navigateTo(): any {
return browser.get('/');
}
}
// login.po.ts
import {browser, by, element} from 'protractor';
export class LoginPage {
username = element(by.css('input[name="username"]'));
password = element(by.css('input[name="password"]'));
submit = element(by.buttonText('Login'));
login(username: string, password: string): void {
this.username.sendKeys(username);
this.password.sendKeys(password);
this.submit.click();
}
navigateTo(): any {
return browser.get('/#/login');
}
}
import {browser} from 'protractor';
import {HomePage} from './home.po';
import {LoginPage} from './login.po';
// https://github.com/angular/protractor/blob/master/docs/timeouts.md#how-to-disable-waiting-for-angular
describe('Dashboard', () => {
beforeEach(() => {
const homePage = new HomePage();
homePage.navigateTo();
});
describe('Authentication', () => {
it('should redirect to /login when trying to access the dashboard without being authenticated', () => {
// const homePage = new HomePage();
// await homePage.navigateTo();
const url = browser.getCurrentUrl();
expect(url)
.toEndWith('/#/login');
});
it('should fail to login if not provided the proper credentials', () => {
const loginPage = new LoginPage();
loginPage.login('rolandjitsu@gmail.com', 'test');
const url = browser.getCurrentUrl();
expect(url)
.toEndWith('/#/login');
});
it('should login if provided the proper credentials', () => {
// browser.ignoreSynchronization = true;
const loginPage = new LoginPage();
loginPage.login('rolandjitsu@gmail.com', 'ActualPass');
// await browser.sleep(10000);
const url = browser.getCurrentUrl();
expect(url)
.toEndWith('/#/');
});
});
});
- Output from running the test
Spec started
Dashboard
Authentication
✓ should redirect to /login when trying to access the dashboard without being authenticated
✗ should fail to login if not provided the proper credentials
- Failed: Error while waiting for Protractor to sync with the page: true
at runWaitForAngularScript.then (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/protractor/lib/browser.ts:653:19)
at ManagedPromise.invokeCallback_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:13
66:14)
at TaskQueue.execute_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2970:14)
at TaskQueue.executeNext_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2953:27)
at asyncRun (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2813:27)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:676:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: Run it("should fail to login if not provided the proper credentials") in control flow
at Object.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/jasminewd2/index.js:94:19)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/jasminewd2/index.js:64:48
at ControlFlow.emit (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/events.js:62:21)
at ControlFlow.shutdown_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2565:10)
at shutdownTask_.MicroTask (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2490:53)
at MicroTask.asyncRun (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2619:9)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:676:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From asynchronous test:
Error
at Suite.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:22:3)
at Suite.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:13:2)
at Object.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:7:1)
at Module._compile (module.js:571:32)
at Module.m._compile (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/ts-node/src/index.ts:382:23)
at Module._extensions..js (module.js:580:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/ts-node/src
/index.ts:385:12)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
✗ should login if provided the proper credentials
- Failed: Error while waiting for Protractor to sync with the page: true
at runWaitForAngularScript.then (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/protractor/lib/browser.ts:653:19)
at ManagedPromise.invokeCallback_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:13
66:14)
at TaskQueue.execute_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2970:14)
at TaskQueue.executeNext_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2953:27)
at asyncRun (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2813:27)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:676:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: Run it("should login if provided the proper credentials") in control flow
at Object.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/jasminewd2/index.js:94:19)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/jasminewd2/index.js:64:48
at ControlFlow.emit (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/events.js:62:21)
at ControlFlow.shutdown_ (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2565:10)
at shutdownTask_.MicroTask (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2490:53)
at MicroTask.asyncRun (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:2619:9)
at /Users/rolandjitsu/Projects/infarm/dashboard/node_modules/selenium-webdriver/lib/promise.js:676:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From asynchronous test:
Error
at Suite.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:30:3)
at Suite.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:13:2)
at Object.<anonymous> (/Users/rolandjitsu/Projects/infarm/dashboard/e2e/app.e2e-spec.ts:7:1)
at Module._compile (module.js:571:32)
at Module.m._compile (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/ts-node/src/index.ts:382:23)
at Module._extensions..js (module.js:580:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/rolandjitsu/Projects/infarm/dashboard/node_modules/ts-node/src
/index.ts:385:12)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
- Steps to reproduce the bug
I’m using Angular CLI
ng test
to run the tests. When the user lands on the page they get redirected to #/login
if not authenticated, then if they fill wrong credentials they stay on the same page, otherwise they get redirected to /#/
.
I tried to use browser.ignoreSynchronization = true;
and browser.sleep()
on the last test, which looks like it worked, but the second test still failed.
Also note that the interactions with the browser actually work, but the tests fail anyway.
- The URL you are running your tests against (if relevant)
I have the same issue and after investigating, I think I found the bug : if you configure Protractor with
useAllAngular2AppRoots: true
, there is no issue. But If you userootElement: 'my-app'
instead the bug appears.By looking at the code, it seems that when using
rootElement
the callback here is called withtrue
which is then interpreted as an error here. IfuseAllAngular2AppRoots
is used, the callback is called here with no parameter hence no error.I have a similar setup (login page that redirects to to another route in the Angular 4 app), that exhibits the same issue consistently when run inside of docker with chrome. Works on mac mostly but has intermittent failures. The error I get is:
Error: Error while waiting for Protractor to sync with the page: “window.angular is undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor’s bootstrapping. See http://git.io/v4gXM for details”
Which is incorrect since both my login page and the post login page are routes within the same angular 4 application. My tests are using async/await with selenium promise manager disabled.
This makes protractor basically unusable for my app, since all the functionality lies behind the login page.
I’m facing a similar issue error : "Failed: Error while waiting for Protractor to sync with the page: “both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor’s bootstrapping. See http://git.io/v4gXM for details”
I’m trying to get the url and other elements from object reportory.js and page.js… not sure why it will throw the above error. can some one help me ??
@rolandjitsu - I raised a separate issue #4543 as I didn’t see yours at first.
The problem is at clientsidescripts.js#L181 because
testability.whenStable(callback)
sometimes passestrue
to the callback method, which is then interpreted as an error.If your Angular code under test doesn’t have any pending tasks, then the zone is considered stable and
testability.whenStable(callback)
passesfalse
to the callback method immediately. This works fine.But if there are any pending tasks - http.get or setTimeout or similar - then the zone is considered unstable;
testability.whenStable(callback)
passestrue
to the callback method once the zone becomes stable.I issued pull request #4544 to fix this.
@viewstack - Your problem is different, my PR won’t fix that.
@Groggy spot on! Using that config seems to work indeed. I’ve also noticed that it happens when I try to get the browser url after a redirect happened in the app:
@wswebcreation I wouldn’t say that.
The behaviour of
rootElement: 'my-app'
anduseAllAngular2AppRoots: true
should be the same in this instance, meaning the error we see shouldn’t occur just with one, but not the other.