我想首先获取当前页面上完整元素列表的#product_list,然后找到此列表中的每个元素 如果元素 .ajax_block_product.col-xs-12.col-sm-4.col-md-3[data-id-product='22578'] 位于第一页中,则单击它,否则单击 #pagination_next_bottom 按钮在页面底部并在其他页面中再次搜索以查找 #product_list 元素中存在的元素
我尝试使用此功能,但它只能找到每个页面并进行导航,而无需单击所需的元素。
// findItem("Printer Brother MFP Laser HL1222WEYJ1");
// function findItem(value) {
// let found = false;
// let attempts = 0;
// const maxAttempts = 20; // Define a maximum number of attempts
// function clickNext() {
// cy.get("#pagination_next_bottom").click()
// cy.wait(5000);
// }
// function findInPage() {
// if (found || attempts >= maxAttempts) {
// return; // If item found or max attempts reached, exit
// }
// cy.get("#product_list li div.produkti h5").each(itemNameEl => {
// const itemText = itemNameEl.text();
// console.log(itemText);
// if (itemText === value) {
// found = true;
// cy.get(itemNameEl).should('be.visible').click(); // Click the parent element of the product
// return false;
// }
// });
// if (!found) {
// clickNext(); // Click the "Next" button
// attempts++; // Increment attempts
// findInPage(); // Continue searching on the next page
// }
// }
// findInPage();
// }
两件事可能是一个问题(因为点击没有发生)
itemText === value
由于空格字符,这可能需要像 itemText.includes(value)
这样的不精确匹配
cy.get('itemNameEl')
也许需要是cy.wrap('itemNameEl')
,尽管我不相信这一点
代码中的问题是,检查是否找到对象的行 (
if (!found)
) 是同步的,并且在 Cypress 执行(异步)之前运行,并可能更新 found
的值。因为您在同步函数内执行 Cypress 命令,所以我建议使用 Cypress 自定义命令来处理递归。
Cypress.Commands.add("findItem", (value, attempt) => {
let currAttempt = attempt ?? 0;
const maxAttempts = 20;
if (attempt < maxAttempts) {
let found = false;
cy.get("#product_list li div.produkti h5")
.each(($item) => {
const itemText = $item.text();
console.log(itemText);
if (itemText === value) {
found = true;
return false;
}
})
.then(() => {
if (!found) {
cy.get("#pagination_next_bottom").click();
cy.wait(5000);
cy.findItem(value, currAttempt++);
} else {
cy.wrap($item).should("be.visible").click(); // Click the parent element of the product
}
});
} else {
expect(true === false); // placeholder assertion to fail if too many attempts are made
}
});
此外,将
cy.wrap($item)...
线移至 .then()
块可以使 .each()
块完全同步,不会与任何赛普拉斯命令竞争执行时间。
递归代码看起来不错,但请记住 Cypress 命令
get/each
是异步的,因此您需要等待它们完成之前if (!found)
。
用
cy.then()
包装纸做到这一点。
function findItem(value) {
let found = false;
let attempts = 0;
const maxAttempts = 20; // Define a maximum number of attempts
function clickNext() {
cy.get("#pagination_next_bottom").click()
cy.wait(5000);
}
function findInPage() {
if (found || attempts >= maxAttempts) {
return; // If item found or max attempts reached, exit
}
cy.get("#product_list li div.produkti h5").each(itemNameEl => {
const itemText = itemNameEl.text();
console.log(itemText);
if (itemText === value) {
found = true;
cy.get(itemNameEl)
.parent()
.should('be.visible').click(); // Click the parent element of the product
return false;
}
})
cy.then(() => { // wrapping found check allows previous get/each to complete
if (!found) {
clickNext(); // Click the "Next" button
attempts++; // Increment attempts
findInPage(); // Continue searching on the next page
}
}
}
findInPage();
}
也许还可以为找到的元素添加别名,并在搜索完成后单击它。
一般来说,您应该尝试将查询代码与操作代码分开,因为操作可以更改 DOM 并使已运行的查询无效。
function findInPage(value) {
...
if (itemText === value) {
found = true;
cy.get(itemNameEl).parent().as('product')
}
findInPage();
cy.get('@product').should('be.visible').click()