wait()
功能..我知道,根据官方文档,Cypress 是异步工作的,我们不需要使用
wait()
函数,尤其是 visit()
命令处理它,因为它加载页面然后继续移动。
在我的测试用例中,我想做 2 件导致问题的主要事情:
it("clicks on the 'Front End' and navigates to the correct page", () => {
visit(path, {
timeout: 120000,
pageLoadTimeout: 120000,
});
cy.get(selectors.CATEGORIES)
.eq(2)
// i use 'within', because i want to search **inside the selectors.CATEGORIES.eq(2) and not on the whole DOM**
.within(() => {
cy.get(dataCySelector("gridRow")).then(($optionsWrapper) => {
const parentEl = $optionsWrapper.parent();
const isMenuOpen = parentEl.css("display");
// if i dont add the wait(), it selects the 1st 'menu options' instead of the **3rd**
cy.wait(3000);
if (isMenuOpen === "none") {
console.log("*MENU IS CLOSE I OPEN*");
cy.contains("category").click(); // OPEN THE MENU
cy.contains("Front End").should("be.visible").click(); // click on the 'front end'
} else {
console.log("*MENU IS OPEN I DONT CLICK ON IT*");
cy.contains("Front End").should("be.visible").click(); // JUST click on the 'front end'
}
cy.url().then(() => {
cy.urlIncludes("/path/to/menu/option");
cy.wait(3000);
cy.contains(dataCySelector("AN_ELEMENT"));
});
});
});
});
所以我的流程如下:
CATEGORIES
选择器(左侧导航栏上有5个菜单)within
深入了解它的孩子(我替换了 then
因为它搜索了整个 DOM)!!display=none
wait(3000)
,parentEl
是第一个菜单包装器!!wait()
来检查元素选择器是否存在。这里一定有问题,我可以摆脱
wait
吗?
谢谢。
对于第二个
wait()
,如果您的问题与您的页面需要比默认超时更多的时间来加载这一事实有关,您仍然可以覆盖它。
cy.url().then(() => {
cy.url().should("contain", "/path/to/menu/option");
cy.contains(dataCySelector("AN_ELEMENT"), {timeout: 30_000});
});
对于第一个
wait
,If/Else 很奇怪。应该知道它何时打开,所以我会避免它(通过为这两种情况创建例如 2 个函数)然后,对于每种情况,我会在必要的地方添加一个{timeout: 30_000}
。
一般来说,把
.then()
改成.should()
就可以重试,不用等了
重试是一种聪明的等待方式,因为它只会在不满足条件时等待。
您必须使用
expect()
或assert()
来触发重试。赛普拉斯修补那些chai
方法并使用抛出的错误来触发每次重试。
检查网址
cy.url().should((url) => {
expect(url).to.include("/path/to/menu/option") // retries if not true
})
// or
cy.url().should('include', "/path/to/menu/option")
// this command can be separate,
// Cypress has a queue and this line is only run after the above succeeds
cy.contains(dataCySelector("AN_ELEMENT"))
检查 gridRow parent 的可见性
你在测试的顶部加载了一个干净的页面,所以你的菜单最初不会打开(页面应该按预期加载)。
测试可以简单地是:
cy.get(selectors.CATEGORIES)
.eq(2)
.within(() => {
cy.contains("category").click()
cy.contains("Front End").should("be.visible").click()
cy.url().should('include', '/path/to/menu/option')
cy.contains(dataCySelector("AN_ELEMENT"))
})
但出于说明的目的,如果尚未打开,这应该打开菜单。
cy.get(dataCySelector("gridRow"))
.parent()
.then($menu => {
const menuIsClosed = $menu.css("display") === 'none';
if (menuIsClosed) {
$menu.click() // jQuery click()
}
})
注释它选择第一个“菜单选项”而不是第三个似乎表明菜单项是延迟加载的。
您可以通过为菜单选项的数量(长度属性)添加
.should()
断言来克服这个问题。
cy.get(dataCySelector("gridRow"))
.should('have.length', 3)
cy.contains("Front End").should("be.visible").click()
整个测试
您想“解耦”步骤,以便您可以单独检查它们。
由于您已将基本的 Cypress 命令抽象为自定义命令,并且没有给出详细信息,因此很难准确描述代码,但这是我将采用的方法:
cy.get(selectors.CATEGORIES)
.eq(2)
.within(() => {
// open the parent
cy.get(dataCySelector("gridRow"))
.parent()
.then($menu => {
if ($menu.css("display") === 'none') {
$menu.click() // jQuery click()
}
})
.should('not.have.css', 'display', 'none') // add retry in case of lag
// ensure all options loaded
cy.get(dataCySelector("gridRow"))
.should('have.length', 3)
// click required option
cy.contains("Front End").should("be.visible").click()
cy.url().should('include', '/path/to/menu/option')
// verify page
cy.contains(dataCySelector("AN_ELEMENT"))
})