单击后打开的非 angular 页面

Non-angular page opened after a click

我正在尝试实现以下测试场景:

问题是在新浏览器中打开的页面window是一个非angular页面,而我正在执行点击进入 angular 页面

这是我的第一次尝试:

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]);
        });
    });
});

失败:

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

这是可以理解的。

我的第二次尝试是使用 ignoreSynchronization 布尔标志:

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]);
    });

这实际上使这个特定的测试没有任何错误地通过了,但是它影响了在此之后执行的每个测试,因为 browser 是一个全局对象并且在测试之间共享 - 量角器不再与 [=49 同步=] 在导致各种错误的页面上。

我应该如何实施测试?


作为解决方法,我可以将 restartBrowserBetweenTests setting 更改为 true 并更改 ignoreSynchronization 值而不会出现任何问题 - 但它会显着降低测试速度。

验证完成后,您可以将 ignoreSynchronization 设置为 false。但是,请注意 ignoreSynchronization 是同步的,而其他所有内容 (click/get/etc) 都是异步的,因此您需要小心。可能最安全的方法是在 beforeEach 中将其设置为 true,在 afterEach 中将其设置为 false,然后只测试该测试中的单个徽标点击。

另一个解决方案:我使用 sleep 因为 getWindowHandles 是 仅返回一个 window 名称(parent/angular window)。让我知道是否有 是更好的方法。

this.validateProductPageInfo = function (productTitle) {
    browser.sleep(5000);
    browser.getAllWindowHandles().then(function (handles) {
        if (handles.length === 2) {
            browser.switchTo().window(handles[1]).then(function () {
                var prodTitle = by.xpath('//h1[@id="fw-pagetitle"]');
                browser.driver.findElement(prodTitle).getText().then(function (text) {
                    expect(text).toBe(productTitle);
                });
            });
            browser.switchTo().window(handles[0]);
        } else {
            console.log("Error in switching to non angular window");
        }
    });
};