访问新网址赛普拉斯
Posted
技术标签:
【中文标题】访问新网址赛普拉斯【英文标题】:Visit new url Cypress 【发布时间】:2020-08-15 07:32:11 【问题描述】:我是赛普拉斯的新手。我的应用程序作为“路由系统”手动更改window.location.hash
。
在某些时候,我单击了一个更改哈希的按钮,因此应该在测试期间更改页面。我可以在执行过程中看到一个“新 url”条目,但是如何让 cypress 访问该 url?
简而言之,问题是什么:您可以看到我输入了密码,然后输入了enter
。运行测试可以看到地址栏的hash变化,但是页面并没有随着hash变化而变化。
这是测试代码
context("Workflow", () =>
it("login", () =>
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demoenter").should("have.value", "demo") // this should redirect to "/#home"
//cy.wait(10000)
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
)
)
编辑:经过无数次失败的尝试,我想出了一个部分有效、笨拙且笨拙的解决方案。我认为我不需要使用reload()
来解决这个问题(必须有更好的解决方案..),但要使其正常工作,我必须等待所有远程请求完成(否则reload()
会取消它们)。我说部分工作,因为如果我尝试先访问#login
,然后按照#home
中的重定向,然后将页面更改为#browser
,您可以从代码中的 cmets 看到,最后一个不起作用(我可以看到哈希更改为#browser
,但页面仍然是#home
)。
import 'cypress-wait-until';
let i = 0;
context("Workflow", () =>
it("login", () =>
cy.server(
onRequest: () =>
i++;
,
onResponse: () =>
i--;
);
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demouser").should("have.value", "demouser")
cy.get("#password").type("demouser").should("have.value", "demouser")
cy.get("form#formLogin").submit()
cy.waitUntil(() => i > 0)
cy.waitUntil(() => i === 0)
cy.reload(); // it correctly change the hash AND the page to #home!
cy.url().should("include", "#home")
cy.get(".version").contains( "v2.0.0-beta") // it works!!
cy.get("a[data-id=browser]").click(force: true) // it correctly changes the hash to #browser
cy.waitUntil(() => i > 0)
cy.waitUntil(() => i === 0)
cy.reload();
// the hash in the address bar is #browser, but the web page is #home
)
)
【问题讨论】:
你试过cy.visit()
吗?
cy.visit()
将 url 作为参数。我不需要那个。我只需要访问菜单按钮指向的页面。
所以你点击了一个按钮,它会手动更改锚点 AKA window.location.hash
。当您手动点击网页中的按钮时,您是否重定向到锚点?
当然可以,网站本身也可以正常工作。整个问题是当我在 cypress 中运行它时,我使用 cy.find("#mybutton").click()
单击一个按钮,而 cypress 根本不会更改页面。
你说你点击了一个按钮,但上面的日志中没有显示。可能是因为cy.find("#mybutton")
是无效语法,请参阅here。显示测试代码会更有帮助。
【参考方案1】:
有一些方法可以做到这一点。其中一种基本方法是这样的:
cy.visit(`your_login_page`)
cy.get('[data-testid="input-username"]').type(`demo`, force: true )
cy.get('[data-testid="input-password"]')
.type(`demo`,
force: true,
)
.wait(1000)
.then(() =>
cy.location().should((loc) =>
expect(loc.pathname).to.eq(your_new_url)
)
)
您应该将data-testid
或findByTestId
添加到具有唯一ID 的元素中。
访问新网址可以使用cy.visit(loc.pathname)
【讨论】:
谢谢,在我的情况下是expect(loc.hash).to.eq("#home")
,就好像你只改变了hash
pathname
是一样的。无论如何,这种断言不会失败,但赛普拉斯实际上并没有根据哈希变化来改变页面。所以如果我尝试在主页上搜索一个元素,比如cy.get(".subtitle")
,它会失败【参考方案2】:
赛普拉斯有一个名为url:changed
的事件。请参阅关于事件 here
使用这个,像这样可能工作:
context("Workflow", () =>
it("login", () =>
cy.on('url:changed', url =>
cy.location('hash').then(hash =>
if (!url.endsWith(hash))
cy.visit(url);
);
);
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demoenter").should("have.value", "demo") // this should redirect to "/#home"
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
)
)
编辑:仅出于故障排除目的并专注于您的问题,您可以在没有cy.location()
的情况下尝试这样吗:
context("Workflow", () =>
it("login", () =>
cy.on('url:changed', url =>
cy.visit(url);
);
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demoenter").should("have.value", "demo") // this should redirect to "/#home"
cy.get(".subtitle").should("have.value", "Welcome") //this line fails as ".subtitle" is an element of "/#home"
)
)
编辑:你试过cy.reload()
context("Workflow", () =>
it("login", () =>
cy.visit("http://localhost:3000/src/#login")
cy.get("#username").type("demo").should("have.value", "demouser")
cy.get("#password").type("demoenter").should("have.value", "demo") // this should redirect to "/#home"
cy.reload();
cy.get(".subtitle").should("have.value", "Welcome");
)
)
【讨论】:
你的代码抛出错误:Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise. The command that returned the promise was: > cy.visit() The cy command you invoked inside the promise was: > cy.location()
还有一件事要尝试:)
还有一个submit()
命令可以用于form
元素,例如:cy.get('form').submit()
您是否尝试在 Chrome 而不是 Electron 中运行 cypress 测试?
最后评论,我在 :) 之后放弃。我在使用 litElements 和 shadow DOM 搜索 cypress 时发现了这一点。 github.com/abramenal/cypress-shadow-dom【参考方案3】:
感谢所有解决问题的尝试,但对于“window.location.hash
更改时触发相关侦听器”这样简单的问题,它们都是棘手的解决方法。
问题的根源在于赛普拉斯中的错误。 window.location.hash
上的错误存在于 4.5.0
中,但它已在 4.5.0
和 4.12.1
之间的某个地方得到解决。
在4.12.1
中问题已解决。
【讨论】:
以上是关于访问新网址赛普拉斯的主要内容,如果未能解决你的问题,请参考以下文章