59

问题就这么简单。在赛普拉斯中,我如何访问运行测试时打开的新窗口。

重建步骤:

  1. 运行测试。一些操作后,会弹出新窗口(网址本质上是动态的)。
  2. 填写新窗口中的字段,然后单击几个按钮。
  3. 在新窗口中完成所需操作后,关闭新窗口并返回主窗口。
  4. 使用主窗口继续执行。

兴趣点:重点应该是

main window -> new window -> main window

我读过一些与使用iframe和有关的东西confirmation box,但这里没有。涉及访问一个全新的窗口。类似于Window HandlersSelenium 中的东西。不幸的是找不到任何与之相关的东西。

4

7 回答 7

79

故意不支持通过 Cypress 访问新窗口。

但是,现在有很多方法可以在赛普拉斯中测试此功能。您可以将测试拆分为单独的部分,并且仍然可以确信您的应用程序已被覆盖。

  1. 编写一个测试,检查在您的应用程序中执行操作时,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')
  1. 在新测试中,使用cy.visit()转到将在新窗口中打开的 url,填写字段并单击按钮,就像在赛普拉斯测试中一样。
cy.visit('http://localhost:3000/new-window')

// Do the actions you want to test in the new window

可以在此处找到完整工作的测试示例。

于 2017-12-13T21:43:09.710 回答
17

我不是柏树专家,几天前才开始使用它,但我想出了这种带有动态链接的有状态应用程序的解决方案:

// 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

有没有更好的方法来做到这一点?

于 2019-12-18T11:39:46.887 回答
8
// 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 - 选项卡处理锚链接

于 2020-05-13T14:03:05.670 回答
6

这是我在项目中使用的基于“赛普拉斯使用子窗口”的解决方案

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
于 2020-07-19T00:22:39.180 回答
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)
于 2021-05-05T10:22:32.457 回答
4

我最近也遇到了这个问题——新标签的网址是动态的,所以我不知道它是什么。经过大量搜索,一些试验和错误以及来自同事的输入,通过执行以下操作解决:

// 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');
于 2021-03-17T15:31:46.043 回答
1

这就是您可以在同一窗口中处理选项卡的方式..

使用此代码段

cy.xpath("//a[@href='http://www.selenium.dev']").invoke('removeAttr','target').click();
于 2021-07-11T05:31:14.650 回答