Non-angular page opened after a click

alecxe picture alecxe · Feb 14, 2015 · Viewed 7.9k times · Source

I'm trying to implement the following test scenario:

  • perform a click on a logo on the page
  • assert there is a new browser window opened (tab in Chrome) and check the current URL

The problem is that the page opened in a new browser window is a non-angular page while the main page I'm performing the click in is an angular page.

Here is my first attempt:

it("should show logo", function () {
    var logo = scope.page.logo;
    expect(logo.isDisplayed()).toEqual(true);

    // opens a new page on click
    logo.click().then(function () {
        browser.getAllWindowHandles().then(function (handles) {
            browser.switchTo().window(handles[1]).then(function () {
                expect(browser.getCurrentUrl()).toEqual('http://myurl.com/');
            });

            // switch back to the main window
            browser.switchTo().window(handles[0]);
        });
    });
});

which fails with:

Error: Error while waiting for Protractor to sync with the page: "angular could not be found on the window"

which is understandable.

My second attempt was to play around with ignoreSynchronization boolean flag:

browser.ignoreSynchronization = true;
logo.click().then(function () {
    browser.getAllWindowHandles().then(function (handles) {
        browser.switchTo().window(handles[1]).then(function () {
            expect(browser.getCurrentUrl()).toEqual('http://myurl.com/');
        });

        // switch back to the main window
        browser.switchTo().window(handles[0]);
    });

This actually makes this particular test pass without any errors, but it affects every test executed after this one, because browser is a global object and is shared between tests - protractor no longer syncs with angular on a page which results into all sorts of errors.

How should I implement the test?


As a workaround, I can change the restartBrowserBetweenTests setting to true and change ignoreSynchronization value without any problems - but it slows down the tests dramatically.

Answer

hankduan picture hankduan · Feb 14, 2015

You can set ignoreSynchronization to be false once your verification is done. However, note that ignoreSynchronization is synchronous while everything else (click/get/etc) is asynchronous, so you need to be careful with that. Probably the safest way is to set it to true in beforeEach and false in afterEach, and just test that single logo click in that test.