I’ve received a Cypress error suggesting that multiple elements contain the searched value, so it cannot recognize the requested one.
Here is the Cypress script I’ve used for testing:
it('Check all promotions', () => {
// Check Promotion 1
let promotionCode = 'UK_ZYN_MULTI_BUY_20';
let promotionName = '10 ZYN Cans multi-buy + 10 ZYN Cans multi-buy';
let websiteEnv = 'Inactive';
let promotionVersion = '2';
searchPromotion(promotionCode, promotionName, websiteEnv, promotionVersion);
});
});
// searchPromotion function
function searchPromotion(promotionCode, promotionName, websiteEnv, promotionVersion) {
cy.get('.z-bandbox-input')
.eq(6)
.should('exist')
.clear()
.type(promotionCode, { force: true })
.wait(300);
cy.get('.yw-textsearch-searchbutton.z-button')
.eq(1)
.click({ force: true })
.wait(10000);
const selector = "tr.yw-coll-browser-hyperlink:has(.yw-listview-cell-label.z-label:contains("" + promotionCode + "")):has(.yw-listview-cell-label.z-label:contains("" + promotionName + "")):has(.yw-listview-cell-label.z-label:contains("" + websiteEnv + "")):has(.yw-listview-cell-label.z-label:contains("" + promotionVersion + ""))";
function checkPage() {
cy.get('body').then($body => {
if ($body.find(selector).length > 0) {
cy.get(selector).within(() => {
cy.get('.yw-listview-cell-label.z-label')
.filter((_, el) => {
// Ensure the version is an exact match
const versionText = el.innerText.trim();
return versionText === promotionVersion; // Exact match check
})
.first() // Ensure only one element is selected
.click({ force: true });
});
} else {
cy.get('button.z-paging-button.z-paging-next[title="Next Page"]').eq(2).then($button => {
if ($button.is(':visible') && !$button.attr('disabled')) {
cy.wrap($button).click({ force: true }).wait(5000);
checkPage(); // Recursively check the next page
} else {
cy.log('Promotion not found or next page button is not clickable');
}
});
}
});
}
checkPage();
}
Cypress searched for the promotions and there is 3 of them. Basically those are 3 versions of the same promotion, so only their version number is different, everything else is the same, including the class name of each field.
In order to comprehend it better: When promotions are searched they are listed with their Code, Name, Status, Version etc. All these fields contains the same class name. When you search for the one promotion in particular by its code, you get a list of various versions of that promotion. It means that only the version value differs, and by that value Cypress can determine which promotion should it choose for further testing.
I’ve solved that by implementing this const:
const selector = "tr.yw-coll-browser-hyperlink:has(.yw-listview-cell-label.z-label:contains("" + promotionCode + "")):has(.yw-listview-cell-label.z-label:contains("" + promotionName + "")):has(.yw-listview-cell-label.z-label:contains("" + websiteEnv + "")):has(.yw-listview-cell-label.z-label:contains("" + promotionVersion + ""))";
Still, it seems that my functions didn’t solve the problem of searching for exact values.
What I believe is the issue here is that Cypress is mistaking the "2" value set for the version field with the number "2" that is appearing in each promotion code: UK_ZYN_MULTI_BUY_20
I thought that the function I’ve set in my script could handle this, but it seems that it is missing something additional.
2
Answers
After keep trying I've managed to solve the issue by implementing this script:
I guess in the absence of attributes other than
class
(maybe aria-label?) you want exact text match.Since there is a
tr
it’s a table, you don’t really need the classes in the selector, you can use thetd
within thetr
. Usingcontains('td', ...)
you want an exact match, so a regex text value would do this.In the regex
^
is start and$
is end, if you add front and back it excludes the larger string that has2
in the middle.I’m not sure how to fit that into the
selector
const, maybe:nth-child()
does it, but it’s getting harder to "know" your selector is correct with more clauses in it.The test is much easier to follow when it’s simple, so I would just break it down with smaller steps.