访问新窗口 - cypress.io
Posted
技术标签:
【中文标题】访问新窗口 - cypress.io【英文标题】:Access a new window - cypress.io 【发布时间】:2018-05-24 19:13:03 【问题描述】:问题就这么简单。在 Cypress 中,如何访问在运行测试时打开的新窗口。
重建步骤:
运行测试。执行一些操作后,会弹出新窗口(网址本质上是动态的)。 填写新窗口中的字段,然后单击几个按钮。 在新窗口中完成所需操作后,关闭新窗口并返回主窗口。 使用主窗口继续执行。
兴趣点:焦点应该是
main window -> new window -> main window
我读过一些与使用iframe
和confirmation box
相关的内容,但这里没有。涉及访问一个全新的窗口。类似于 Selenium 中的Window Handlers
。遗憾的是找不到任何相关内容。
【问题讨论】:
【参考方案1】:通过赛普拉斯访问新窗口是intentionally not supported。
不过,现在可以通过多种方式在赛普拉斯中测试此功能。您可以将测试拆分为单独的部分,并且仍然确信您的应用程序已被涵盖。
编写一个测试以检查在您的应用中执行操作时,是否通过使用
cy.spy()
来调用window.open
事件以侦听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()
转到将在新窗口中打开的网址,填写字段并单击按钮,就像在赛普拉斯测试中一样。
cy.visit('http://localhost:3000/new-window')
// Do the actions you want to test in the new window
可以在here找到完整的测试示例。
【讨论】:
嗯。迂回的方式,但我猜是可行的。一个问题。如何从按钮单击中获取 URL。假设每次点击 url 都会改变。 您可以使用断言be.calledWith
来代替be.called
并断言该url。我在这里创建了一个完整的工作测试示例:github.com/cypress-io/cypress-example-recipes/blob/master/…
嗯,更像是:我不知道新窗口的url,如何动态获取?我想可能会得到href
属性(如果可用)?那么这种场景是否有.getattribute
函数?
是的,您始终可以只使用 javascript。 cy.get('a').then(($a) => var url = $a[0].getAttribute('href') )
一旦我们可以访问打开的窗口,我们如何对其执行操作然后切换回旧窗口?我可以验证直到窗口打开。但我无法在这个打开的窗口上找到按钮。作品- cy.window().then((win) => cy.spy(win, 'open').as('windowOpen'); ); cy.get('button').contains('登录你的账户').click() cy.get('@windowOpen').should('have.been.callWith', Cypress.sinon.match(' about:blank')) 这不起作用 - cy.get('@windowOpen').get('#buttonid1').click() 也不确定你如何移回旧窗口?【参考方案2】:
我不是cypress专家,几天前才开始使用它,但我想出了这种带有动态链接的有状态应用程序的解决方案:
// 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
有没有更好的方法来做到这一点?
【讨论】:
哇,像魅力一样工作!这应该记录在官方文档中。 一旦我们可以访问打开的窗口,我们如何对其执行操作然后切换回旧窗口?我可以验证直到窗口打开。但我无法在这个打开的窗口上找到按钮。作品- cy.window().then((win) => cy.spy(win, 'open').as('windowOpen'); ); cy.get('button').contains('登录你的账户').click() cy.get('@windowOpen').should('have.been.callWith', Cypress.sinon.match(' about:blank')) 这不起作用 - cy.get('@windowOpen').get('#buttonid1').click() 也不确定你如何移回旧窗口? 这很棒。它按预期工作。【参考方案3】:// 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')
Cypress - tab handling anchor links
【讨论】:
一个不错的简单技巧。非常感谢。【参考方案4】:这是我在基于"Cypress using child window"的项目中使用的解决方案
Cypress Window Helpers (aka. Cypress Tab Helpers) 它们实际上是弹出窗口或子窗口,但为了 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
【讨论】:
【参考方案5】:我能够通过以下方式实现相同的要求:
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)
【讨论】:
【参考方案6】:我最近也遇到了这个问题 - 新标签的网址是动态的,所以我不知道它是什么。经过大量搜索、一些试验和错误以及来自同事的输入,通过执行以下操作解决了:
// 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.window().then((win) => cy.spy(win, 'open').as('windowOpen'); ); cy.get('button').contains('登录你的账户').click() cy.get('@windowOpen').should('have.been.callWith', Cypress.sinon.match(' about:blank')) 这不起作用 - cy.get('@windowOpen').get('#buttonid1').click() 也不确定你如何移回旧窗口? @namrata Cypress 不支持多个选项卡。这就是为什么我的代码只验证 window.open 被调用的原因。在他们的examples 中,他们提供了多种方法来处理新标签的情况。 @namrata 你必须关闭 cypress.json 中的 chromewebsecurity。默认情况下,它的值为 true,您可以在 cypress 仪表板上检查设置。例如,请从第 27 分钟开始观看此视频youtu.be/C2DjGl5a_-Y【参考方案7】:这就是您可以在同一窗口中处理选项卡的方式..
使用这个代码sn-p
cy.xpath("//a[@href='http://www.selenium.dev']").invoke('removeAttr','target').click();
【讨论】:
以上是关于访问新窗口 - cypress.io的主要内容,如果未能解决你的问题,请参考以下文章