cypress.io:如何从cy.then或cy.each函数中发送触发器? [英] Cypress.io: How to send a trigger out of cy.then or cy.each function?
问题描述
我试图验证天气,如果页面元素之间是否有我想要的存储关键字.
I try to verify weather if there have store keyword I want between the elements of pages.
例如:
store关键字=苹果"
store keyword = "apple"
页面的部分结构:
<tbody>
<tr>
<td class="store">
<img class="offer-store" ... alt="amazon store" .../></td>
<td ...
...</td>
</tr>
...
<tr>
<td class="store">
<img class="offer-store" ... alt="apple store" .../></td>
<td ...
...</td>
</tr>
</tbody>
我有3个产品,需要验证每个产品的商店都包含store关键字.
I have 3 products,need to verify that every product have a store contains store keyword.
一种产品可能有10页,每页有10家商店.
One product may have 10 pages,and have 10 stores per page.
转到产品页面,然后开始查找商店关键字.
Go to a product page,and start to find store keyword.
如果我在第三页的第二家商店中找到store关键字,则转到另一个产品页面.
If I find store keyword in second store on third page,then go to another product page.
我的策略:
for(var i = 0; i < 3; i++) // three product
{
//assume I can go to store page of a product here(using var i)
for(var j = 1; j < 10; j++) //search 10 store pages of the product
{
cy.get(".offer-store").each(($item)=>{
cy.get($item).its('context').invoke('attr','alt').then((store)=>{
if(store.indexOf('apple')!=-1)
cy.log("found store!!")
//send trigger to break cy.then, cy.each and a for loop
})
})
cy.get('.btn-group').contains('>').click({force: true})
//go to next page if not found in this page
}
}
一开始,我使用变量作为触发器来执行中断命令.
At the beginning,I use a variable as a trigger to do break command.
以后我知道您不能将外部变量更改为触发器,需要在cy.then()或cy.each()的末尾使用cy.then()进行进一步的操作.
I know later that you can't change outer variable as a trigger,need to use cy.then() at the end of cy.then() or cy.each() to do further operation.
我尝试使用except()代替if()进行验证,但是当它在第一个元素中没有找到关键字时会出现断言错误(但是我想找到下一个).而且我还尝试了一个未捕获的异常:忽略错误:
I have tried to use except() to do verification instead of if(),but it will get assertion error when it did not find keyword in first element(but I want to find next one). And I also tried to make a uncaught:exception to ignore error:
Cypress.on('uncaught:exception', (err, runnable) => {
return false
})
我将此代码放在cypress/support/commands.js上,但没有用.
I put this code at cypress/support/commands.js,and it didn't work.
我尝试的另一种方法是在cy.then()/cy.each()中返回一个值作为触发器,我得到了
Another way I tried is that return a value as a trigger in cy.then()/cy.each(),and I got
CypressError: cy.then() failed because you are mixing up async and sync code.
我的问题:
1.在这种情况下,如何发送触发器来中断cy.then,cy.each和for循环?
1.How to send trigger to break cy.then, cy.each and a for loop in this case?
2.如何忽略断言错误?
2.How to ignore assertion error?
推荐答案
您所追求的目标可能最好是通过递归命令/帮助程序来解决,该命令/帮助程序对页面进行爬网直到找到商店或没有其他页面为止
What you're after is probably best solved by a recursive command/helper that crawls the pages until a store is found or until no other page/stores are left.
下面, findStore
是一个调用 _walkStores
的函数,该函数是递归的.它会抓取当前页面,并在未找到任何内容的情况下尝试加载下一页.
Below, the findStore
is a function that calls _walkStores
which is recursive. It crawls current page, and tries to load next page if nothing is found.
describe('test', () => {
function _walkStores ( store ) {
let found = false;
return cy.get('.store').each( elem => {
if ( Cypress.$(elem).find(`[data-store="${store}"]`).length ) {
found = true;
return false; // exit early (not required)
}
}).then(() => {
if ( found ) {
return true;
} else {
if ( Cypress.$('.nextPage').length ) {
cy.get('.nextPage').click();
// if your `.nextPage` button doesn't immediately repaint
// DOM as my mock helper does, you should assert url
// change or something similar, before calling _walkStores,
// so as to ensure the _walkStores doesn't retrieve the
// same old DOM nodes
return _walkStores(store);
}
return false;
}
});
}
function findStore ( store ) {
return _walkStores(store).then( found => {
expect(found, `store "${store}"`).to.true;
});
}
function loadProduct ( name ) {
cy.window().then(win => {
const pages = [
`
<div class="store">
<div class="offer-store" data-store="apple">Apple</div>
</div>
<div class="store">
<div class="offer-store" data-store="amazon">Amazon</div>
</div>
<button class="nextPage" onclick="nextPage()">next</button>
`,
`
<div class="store">
<div class="offer-store" data-store="microsoft">Microsoft</div>
</div>
<div class="store">
<div class="offer-store" data-store="dell">Dell</div>
</div>
<button class="nextPage" onclick="nextPage()">next</button>
`,
`
<div class="store">
<div class="offer-store" data-store="ibm">IBM</div>
</div>
<div class="store">
<div class="offer-store" data-store="lenovo">Lenovo</div>
</div>
`,
];
const doc = win.document;
win.nextPage = () => {
const page = pages.shift();
if ( !page ) return;
doc.querySelector('.content').innerHTML = 'loading...';
setTimeout(() => {
doc.querySelector('.content').innerHTML = page;
}, 1000 );
};
doc.body.innerHTML = `
<h1>${name}</h1>
<div class="content">
${pages.shift()}
</div>
`;
});
}
it('test', () => {
['Laptop A', 'Laptop B'].forEach( name => {
loadProduct(name);
// will pass
findStore('ibm');
});
// will fail
findStore('xx');
});
});
这篇关于cypress.io:如何从cy.then或cy.each函数中发送触发器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!