单击后打开的非 angular 页面
Non-angular page opened after a click
我正在尝试实现以下测试场景:
- 单击页面上的徽标
- 断言有一个新的浏览器 window 打开(Chrome 中的选项卡)并检查当前 URL
问题是在新浏览器中打开的页面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");
}
});
};
我正在尝试实现以下测试场景:
- 单击页面上的徽标
- 断言有一个新的浏览器 window 打开(Chrome 中的选项卡)并检查当前 URL
问题是在新浏览器中打开的页面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");
}
});
};