skip to Main Content

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();
}

Here is the error received:
enter image description here

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.

enter image description here

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


  1. Chosen as BEST ANSWER

    After keep trying I've managed to solve the issue by implementing this script:

         // Loop through pages to find the promotion
    function checkPage() {
        cy.get('body').then($body => {
            // Define a more precise selector for the rows containing promotion details
            cy.get('tr.yw-coll-browser-hyperlink').each(($row) => {
    
                // Ensure that the row contains all necessary values except for the version first
                if (
                    $row.find('.yw-listview-cell-label.z-label:contains("' + promotionCode + '")').length > 0 &&
                    $row.find('.yw-listview-cell-label.z-label:contains("' + promotionName + '")').length > 0 &&
                    $row.find('.yw-listview-cell-label.z-label:contains("' + websiteEnv + '")').length > 0) {
    
                    // Check for the correct version specifically, using each() instead of filter()
                    cy.wrap($row).within(() => {
                        cy.get('.yw-listview-cell-label.z-label').each(($el) => {
                            const versionText = $el.text().trim();
                            const className = $el.attr('class'); // Get the class name of the element
                            
                            // Ensure the class and the version both match exactly
                            if (className.includes('z-label') && versionText === promotionVersion) {
                                cy.wrap($el).click({ force: true }); // Click only if it matches the correct version
                            }
                        });
                    });
            }
            });
    
            // Handle pagination if necessary
            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();
    }
    

  2. 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 the td within the tr. Using contains('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 has 2 in the middle.

    cy.get('table#my-table')                               // identify the table
      .contains('td', new RegExp(`^${promotionVersion}$`)  // cell with version
      .parent('tr')                                        // it's row
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search