问题
I try to execute some Protractor tests on a web application that consists of both Angular and non-angular components. My code looks like so:
describe("Test Name", function() {
it("Test case", function() {
// first execute steps on a non-Angular component
browser.waitForAngularEnabled(false);
// some test steps
// then execute tests on an Angular component, which opens in a new browser tab
browser.waitForAngularEnabled(true);
// some more test steps
});
});
The problem is that after the above test is run, the browser launches and immedietaly closes with the following 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 https://github.com/angular/protractor/issues/2643 for details"
When I remove browser.waitForAngularEnabled(true);
from the code, the steps for the non-Angular component are executed successfully, then the Angular component of the application is opened in the new browser tab, nothing happens for 10 seconds (no steps are executed) and the browser closes with the following error:
Failed: Wait timed out after 10007ms
回答1:
You should probably account for asynchronous code and wait for promises to resolve. Also, add Jasmine's done parameter to the test function to let selenium know when the test is finished.
Another thing that might cause this is activating waitForAngularEnabled
before you're actually in an angular page. I suggest you prefix that call with a call to check that something on the page already got loaded so you know angular is ready to be hooked by protractor before waiting for angular activities.
It's important to note that protractor waits for the next action after waitForAngularEnabled(true)
to trigger the check, relying on that might make the problem unclear if sometime later someone changes the code.
describe("Test Name", function() {
it("Test case", function(done) {
// first execute steps on a non-Angular component
browser.waitForAngularEnabled(false)
.then(() => /* step1 */)
.then(() => /* step2 */)
// ...
// 👇 this one is very important to make sure
// we're in an angular page 👇
.then(() => ensurePageTitleIsVisible())
.then(() => browser.waitForAngularEnabled(true))
.then(() => done())
.catch((err) => done.fail(err));
});
});
function ensurePageTitleIsVisible() {
return browser.wait(ExpectedConditions.visibilityOf(PAGE_TITLE_SELECTOR), jasmine.DEFAULT_TIMEOUT_INTERVAL, 'Title does not exist after timeout');
}
This might give you a better error message as well.
and of course, you can do the same with async \ await syntax.
describe("Test Name", function() {
it("Test case", function(done) {
try {
// first execute steps on a non-Angular component
await browser.waitForAngularEnabled(false)
await step1();
await step2();
// ...
await browser.waitForAngularEnabled(true);
done();
} catch(err) {
done.fail(err);
}
});
});
Basically, your problem happens because you continue with the test steps before the browser.waitForAngularEnabled
function actually finishes.
回答2:
use browser.ignoreSynchronization = true;
when interacting with non angular ui since it makes protractor not to wait for Angular promises
and browser.ignoreSynchronization = false;
followed by browser.waitForAngular();
when interacting with angular ui
来源:https://stackoverflow.com/questions/56166437/failed-error-while-waiting-for-protractor-to-sync-with-the-page-while-executi