访问一个新窗口 - cypress.io

时间:2017-12-11 09:39:26

标签: javascript ui-automation cypress

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

重新创建的步骤:

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

兴趣点:焦点应该是

main window -> new window -> main window

我已经阅读了与iframeconfirmation box的使用相关的一些内容,但这里没有。与访问一个全新的窗口有关。像Selenium中的Window Handlers之类的东西。很遗憾找不到与之相关的任何内容。

7 个答案:

答案 0 :(得分:27)

目前的版本无法通过赛普拉斯访问新窗口。

但是,现在有很多方法可以在赛普拉斯测试此功能。您可以将测试分成不同的部分,但仍然可以确信您的应用程序已被覆盖。

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

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

可以找到完整工作的测试示例here

答案 1 :(得分:2)

这是我在基于"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

答案 2 :(得分:1)

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

// 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');

答案 3 :(得分:1)

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

使用此代码片段

        Process: com.trad, PID: 21555
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://media/external/images/media/76207 flg=0x1 (has extras) }} to activity {com.trad/com.trad.ui.activities.AddProductActivity}: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5506)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5547)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.set(ArrayList.java:453)
        at com.trad.ui.activities.AddProductActivity.onActivityResult(AddProductActivity.kt:354)
        at android.app.Activity.dispatchActivityResult(Activity.java:8541)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5499)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5547) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:246) 
        at android.app.ActivityThread.main(ActivityThread.java:8512) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) 
2021-07-11 14:33:46.867 637-1917/? E/BufferQueueProducer: [Application Error: com.trad#0](id:27d00004287,api:0,p:-1,c:637) disconnect: not connected (req=1)

答案 4 :(得分:0)

我不是赛普拉斯专家,几天前才开始使用它,但是我想出了一种用于具有动态链接的有状态应用程序的解决方案:

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

还有更好的方法吗?

答案 5 :(得分:0)

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

答案 6 :(得分:0)

我能够通过以下方式实现相同的要求。

        var 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)