I've created a script for testing inside of SAP Hybris with Cypress. Generally everything works fine, although I wanted to include a function that will basically navigate to the next page if the searched element is not found on the current page. Please take a look at the code:
const checkProductOnPage = (CATALOG_LABEL, retries = 0) => {
const maxRetries = 5; // Adjust this based on the maximum number of pages you expect
// Try to find the product on the current page
return cy.contains('span.yw-coll-browser-hyperlink', CATALOG_LABEL, { timeout: 10000 }) // Adjust timeout as needed
.then(productElement => {
if (productElement.length) {
// If the product element is found
return cy.wrap(productElement).scrollIntoView().should('be.visible').click({ force: true });
} else if (retries < maxRetries) {
// If the product element is not found and we haven't exceeded max retries
return cy.get('body').then(body => {
if (body.find('.z-paging-icon.z-icon-angle-right').length > 0) {
// Click on the pagination button and wait for the page to update
return cy.get('.z-paging-icon.z-icon-angle-right').eq(0).click({ force: true })
.wait(5000) // Adjust wait time as needed
.then(() => checkProductOnPage(CATALOG_LABEL, retries + 1)); // Recurse with increased retry count
} else {
throw new Error('Reached the last page and product not found');
}
});
} else {
throw new Error('Product not found after maximum retries');
}
});
};
const checkProductReplacements = (productCode, replacements, isFirstSearch) => {
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
// Determine the correct input element to type into based on whether it's the first search
const inputIndex = isFirstSearch ? 3 : 5;
cy.get('.z-bandbox-input').eq(inputIndex).type(productCode, { force: true }).wait(300);
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(3000);
return checkProductOnPage(CATALOG_LABEL).then(() => {
cy.wait(5000);
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Use cy.then to properly chain the commands
cy.then(() => {
replacements.forEach(replacement => {
const label = LABELS[replacement.level];
cy.get('.z-listitem')
.contains(replacement.code)
.should('contain', label)
.parent()
.should('contain', CATALOG_LABEL);
});
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
});
});
};
it('should test the replacement matrix', () => {
checkProductReplacements("G0000605", [
{ code: "G0000605", level: 'L1' },
{ code: "G0000592", level: 'L2' },
{ code: "G0000604", level: 'L1' }
], true);
checkProductReplacements("G0000606", [
{ code: "G0000606", level: 'L1' },
{ code: "G0000592", level: 'L3' },
{ code: "G0000604", level: 'L2' }
], false);
checkProductReplacements("G0000607", [
{ code: "G0000607", level: 'L1' },
{ code: "G0000605", level: 'L2' },
{ code: "G0000593", level: 'L3' }
], false);
});
});
It successfully tested the first product (G0000605) while when it tried to do the same with the second product (G0000606) I've received this error:
Timed out retrying after 10000ms: Expected to find content: 'Tunisia Product Catalog : Staged' within the selector: 'span.yw-coll-browser-hyperlink' but never did.
cypress/e2e/New.cy.js:40:19
38 | 39 | // Try to find the product on the current page > 40 | return cy.contains('span.yw-coll-browser-hyperlink', CATALOG_LABEL, { timeout: 10000 }) | ^ 41 | .then(productElement => { 42 | if (productElement.length) { 43 | // If the product element
It didn't find the G0000606 product because it is located on the second page, so Cypress should have navigate to the second page, but instead it just dropped an error where it cannot find the requested product.
I believe that something should be modified in this part of the script:
const checkProductOnPage = (CATALOG_LABEL, retries = 0) => {
const maxRetries = 5; // Adjust this based on the maximum number of pages you expect
// Try to find the product on the current page
return cy.contains('span.yw-coll-browser-hyperlink', CATALOG_LABEL, { timeout: 10000 }) // Adjust timeout as needed
.then(productElement => {
if (productElement.length) {
// If the product element is found
return cy.wrap(productElement).scrollIntoView().should('be.visible').click({ force: true });
} else if (retries < maxRetries) {
// If the product element is not found and we haven't exceeded max retries
return cy.get('body').then(body => {
if (body.find('.z-paging-icon.z-icon-angle-right').length > 0) {
// Click on the pagination button and wait for the page to update
return cy.get('.z-paging-icon.z-icon-angle-right').eq(0).click({ force: true })
.wait(5000) // Adjust wait time as needed
.then(() => checkProductOnPage(CATALOG_LABEL, retries + 1)); // Recurse with increased retry count
} else {
throw new Error('Reached the last page and product not found');
}
});
} else {
throw new Error('Product not found after maximum retries');
}
});
};
The if/else
block will never get to else
This is the culprit;
cy.contains('span.yw-coll-browser-hyperlink', CATALOG_LABEL, { timeout: 10000 })
.then(productElement => {
if (productElement.length) {
...
} else if (retries < maxRetries) {
cy.contains('span.yw-coll-browser-hyperlink', CATALOG_LABEL)
test fails if it doesn't find CATALOG_LABEL.
if (productElement.length)
is saying "if I have found the element". But this always true because if it's not, point #1 above has already failed the test.
Instead, this is the code you need. I'm assuming there might be several different span.yw-coll-browser-hyperlink
containing different text.
cy.get('span.yw-coll-browser-hyperlink', {timeout: 10_000})
.then(links => {
// check the contains CATALOG_LABEL here (non-failing if not found)
const productElement = links.filter(`:contains(${CATALOG_LABEL})`)
if (productElement.length) {
...
} else if (retries < maxRetries) {