问题就是这么简单。在赛普拉斯,如何访问运行测试时打开的新窗口。
重新创建的步骤:
- 运行测试。经过一些操作后,会弹出一个新窗口(网址本质上是动态的)。
- 填写新窗口中的字段,然后单击几个按钮。
- 在新窗口中完成所需操作后,关闭新窗口并返回主窗口。
- 继续使用主窗口执行。
醇>
兴趣点:焦点应该是
main window -> new window -> main window
我已经阅读了与iframe
和confirmation box
的使用相关的一些内容,但这里没有。与访问一个全新的窗口有关。像Selenium中的Window Handlers
之类的东西。很遗憾找不到与之相关的任何内容。
答案 0 :(得分:27)
目前的版本无法通过赛普拉斯访问新窗口。
但是,现在有很多方法可以在赛普拉斯测试此功能。您可以将测试分成不同的部分,但仍然可以确信您的应用程序已被覆盖。
- 编写测试以检查在您的应用中执行操作时,使用
醇>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。
答案 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')
答案 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)