问题就这么简单。在 Cypress 中,如何访问运行测试时打开的新窗口。
重新创建的步骤:
- 运行测试。进行一些操作后,会弹出新窗口(该网址本质上是动态的)。
- 填写新窗口中的字段,然后单击几个按钮。
- 在新窗口中完成所需操作后,关闭新窗口并返回主窗口。
- 在主窗口继续执行。
兴趣点:重点应该是
main window -> new window -> main window
我读过一些与使用
iframe
和 confirmation box
相关的内容,但这里没有这些。涉及访问一个全新的窗口。就像 Selenium 中的 Window Handlers
一样。不幸的是找不到任何相关内容。
有意不支持通过 Cypress 访问新窗口。
但是,现在可以通过多种方式在 Cypress 中测试此功能。您可以将测试分成单独的部分,并且仍然有信心您的应用程序已被覆盖。
编写一个测试来检查在应用程序中执行操作时,是否使用
来侦听window.open
事件来调用cy.spy()
window.open
事件。
cy.visit('http://localhost:3000', {
onBeforeLoad(win) {
cy.stub(win, 'open')
}
})
// Do the action in your app like cy.get('.open-window-btn').click()
cy.window().its('open').should('be.called')
cy.visit('http://localhost:3000/new-window')
// Do the actions you want to test in the new window
可以在here找到完整的测试示例。
// Get window object
cy.window().then((win) => {
// Replace window.open(url, target)-function with our own arrow function
cy.stub(win, 'open', url =>
{
// change window location to be same as the popup url
win.location.href = Cypress.config().baseUrl + url;
}).as("popup") // alias it with popup, so we can wait refer it with @popup
})
// Click button which triggers javascript's window.open() call
cy.get("#buttonWhichOpensPopupWithDynamicUrl").click()
// Make sure that it triggered window.open function call
cy.get("@popup").should("be.called")
// Now we can continue integration testing for the new "popup tab" inside the same tab
有更好的方法吗?
// We can remove the offending attribute - target='_blank'
// that would normally open content in a new tab.
cy.get('#users').invoke('removeAttr', 'target').click()
// after clicking the <a> we are now navigated to the
// new page and we can assert that the url is correct
cy.url().should('include', 'users.html')
let newUrl = '';
cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen').callsFake(url => {
newUrl = url;
});
})
cy.get('.open-window-btn').click()
cy.get('@windowOpen').should('be.called');
cy.visit(newUrl)
赛普拉斯窗口助手(又名赛普拉斯选项卡助手) 它们实际上是弹出窗口或子窗口,但为了 api 简洁,我将它们称为选项卡
cy.openTab(url, opts)
cy.tabVisit(url, window_name)
cy.switchToTab(tab_name)
cy.closeTab(index_or_name) - pass nothing to close active tab
cy.closeAllTabs() - except main root window
// AFTER cy.visit()
cy.window().then((win) => {
cy.spy(win, 'open').as('windowOpen'); // 'spy' vs 'stub' lets the new tab still open if you are visually watching it
});
// perform action here [for me it was a button being clicked that eventually ended in a window.open]
// verify the window opened
// verify the first parameter is a string (this is the dynamic url) and the second is _blank (opens a new window)
cy.get('@windowOpen').should('be.calledWith', Cypress.sinon.match.string, '_blank');
使用此代码片段
cy.xpath("//a[@href='http://www.selenium.dev']").invoke('removeAttr','target').click();
get myButton() { return cy.get('a') }
cy.window().then((win) => {
cy.stub(win, 'open').as('redirect').callsFake(url => {
cy.visit(url);
});
myButton.invoke('removeAttr', 'target')
});
myButton.click();