访问新 url 赛普拉斯

Visit new url Cypress

我是赛普拉斯的新手。我的应用 "routing system" 手动更改 window.location.hash。 在某些时候,我单击了一个更改散列的按钮,因此应该在测试期间更改页面。我可以看到在执行过程中出现了一个 "new url" 条目,但是我怎样才能让 cypress 访问那个 url?

简而言之,问题是什么: 你可以看到我输入了密码,然后 {enter}。 运行 测试我可以看到地址栏中的哈希变化,但是页面并没有根据哈希变化而变化。

这是测试代码

context("Workflow", () => {

    it("login", () => {

        cy.visit("http://localhost:3000/src/#login")
        cy.get("#username").type("demo").should("have.value", "demouser")
        cy.get("#password").type("demo{enter}").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,最后一个不起作用(我可以看到哈希更改为 #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(`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-testidfindByTestId 添加到具有唯一 ID 的元素中。 要访问新的 URL,您可以使用 cy.visit(loc.pathname)

Cypress 有一个名为 url:changed 的事件。请参阅 Events 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("demo{enter}").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("demo{enter}").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("demo{enter}").should("have.value", "demo") // this should redirect to "/#home"
        cy.reload();
        cy.get(".subtitle").should("have.value", "Welcome");
    })
})

感谢所有解决问题的尝试,但对于像“window.location.hash 更改时触发相关侦听器”这样简单的事情,它们都是棘手的解决方法。

问题的根源是 Cypress 中的错误。 window.location.hash 上的错误存在于 4.5.0 中,但已在 4.5.04.12.1 之间的某处解决。

4.12.1问题解决