I have a javascript application and somewhere in the application I have to get the current address of the page by:
我有一个javascript应用程序,在应用程序中的某个位置,我必须通过以下方式获取页面的当前地址:
const currentUrl = window.location.href;
currentUrl
should have some value like https//example.com/somepage/
.
It works fine in manual testing, however, when I put the system under test with Cypress, the return value of window.location.href
is different from what I expected:
currentUrl应该有一些值,比如https://example.com/somepage/。它在手动测试中运行良好,但当我用Cypress测试系统时,window.location.href的返回值与我预期的不同:
https://www.example.com/__/#/specs/runner?file=cypress/e2e/integration/example.cy.js
This's the actual url on the Cypress browser address bar.
这是Cypress浏览器地址栏上的实际url。
What caused this behavior and how can I fix it so that during e2e testing with Cypress, the window.location.href
will return what I'm expecting it to return?
是什么导致了这种行为?我该如何修复它,以便在使用Cypress进行e2e测试时,window.location.htm将返回我期望的结果?
更多回答
@ShriHariL thank you for the comment. This is a cypress command, but I'm talking about application code, not test code. I don't think that I should call cypress command in my application code.
@ShriHariL感谢您的评论。这是一个柏树命令,但我说的是应用程序代码,而不是测试代码。我认为我不应该在应用程序代码中调用柏树命令。
Unfortunately testing a browser extension is not a first-class experience with Cypress.
不幸的是,使用Cypress测试浏览器扩展并不是一流的体验。
The app under test is contained in an iframe of the page, and as far as I know you can't attach your extension to that iframe specifically (which would give you the correct URL).
测试中的应用程序包含在页面的iframe中,据我所知,你不能将你的扩展名专门附加到该iframe(这会给你正确的URL)。
You may be able to "mock" the URL - the only way I can see is to add additional code into the extension
您可以“模拟”URL——我能看到的唯一方法是在扩展中添加额外的代码
let url = window.location.href;
if (window.location.hash.startsWith('#/specs')) {
url = ...
}
Testing a browser extension in it's own window
You can provide an isolated window for the extension by using this Cypress using child window
您可以使用此Cypress using子窗口为扩展提供一个隔离窗口
I made two changes to the code
我对代码做了两次更改
Cypress.Commands.add('openWindow', (url, features) => {
const w = Cypress.config('viewportWidth')
const h = Cypress.config('viewportHeight')
if (!features) {
features = `width=${w}, height=${h}`
}
console.log('openWindow %s "%s"', url, features)
return new Promise(resolve => {
if (window.top.aut) {
console.log('window exists already')
window.top.aut.close()
}
// https://developer.mozilla.org/en-US/docs/Web/API/Window/open
window.top.aut = window.top.open(url, 'aut', features)
// letting page enough time to load and set "document.domain = localhost"
// so we can access it
setTimeout(() => {
cy.state('document', window.top.aut.document)
cy.state('window', window.top.aut)
console.log('window.top.aut', window.top.aut)
resolve(window.top.aut)
}, 2000)
})
})
cy.openWindow('http://example.com').then((win) => {
cy.location('href')
.should('eq', 'http://example.com/') // ✅ passes
})
Also, adding a console.log(url)
inside the extension shows the extension is seeing the correct url now.
此外,在扩展插件中添加console.log(url)表明扩展插件现在看到了正确的url。
更多回答
Thank you for answering, maybe you misunderstood my question. I'm talking about the code and logic in my application, not test code. I don't have the win
object in the application code.
谢谢你的回答,也许你误解了我的问题。我说的是应用程序中的代码和逻辑,而不是测试代码。我在应用程序代码中没有win对象。
Indeed I did misunderstand. But the app should be running completely oblivious of the test. The URL you show particularly /#/specs/runner?
says it is seeing the runner's URL not the app URL. Are you using a framework, or is it vanilla JS?
我确实误解了。但该应用程序运行时应该完全忽略测试。你特别显示的URL/#/species/runner?说它看到的是跑步者的URL,而不是应用程序的URL。你使用的是一个框架,还是普通的JS?
Correct, it's a vanilla JS application, a browser extension.
正确,这是一个普通的JS应用程序,一个浏览器扩展。
Thank you so much, the updated solution of open child window worked for me.
非常感谢,打开儿童窗口的更新解决方案对我有效。
No it;s still good - expect(cy.state()).not.to.be.undefined
- ✅ passes.
没有;还是不错的-expect(cy.state()).not.to.be.undefined-✅ 通过。
我是一名优秀的程序员,十分优秀!