'How to open open card and verify the content inside then open the second card and verify the content and so on

I need to open the first card and verify that everything inside matches the hashtag 'Fashion' and then do the same for the next 3 cards and then press the 'next' button and do the same for next 4 cards. how would I do it? I tried the regular way by clicking on the element.eq(0) and verifying everything inside and then cy.go('back') and so on but that's so much code duplication. how would I do it the other way?

First 4 cards:

first 4 cards

Second 4 cards:

second 4 cards

The CSS selector for all of them is the same [class="discover-card"]. please help:) thank you



Solution 1:[1]

You can use Cypress's .each() functionality to iterate through elements with the same CSS selector.

cy.get('.discover-card').each(($card, index) => {
  // cy.go('back') can cause the list to become detached, so find element by index of original list.
  cy.get('.discover-card').eq(index).click();  
  // validations after clicking the card
  // unsure on this exact function, but was provided in question
  cy.go('back').then(() => {
    // if this is the fourth item checked, we need to press the next button.
    if ((index + 1) % 4 === 0) {
      cy.get('.next-btn').click(); // this selector is the next button on the carousel
    }
  });
});

If the data between the cards is unique, I'd advise creating a data object you can use to store the data and reference it in your test. You can do this by having each data object have a unique key equal to the text on the card, or by storing them in an array.

// unique keys
const data = { fashion: { foo: 'bar' }, beauty: { foo: 'bar2' }, ... };
// array
const data = [{ foo: 'bar' }, { foo: 'bar2' }, ...];
...
// unique keys
cy.wrap($card).should('have.attr', 'foo', data[$card.text()].foo);
// array
cy.wrap($card).should('have.attr', 'foo', data[index].foo);

Solution 2:[2]

If you are concerned about code duplication, put the common code in a function

const expectedData [
  { index: 1, title:'Fashion', ... } // anything you want to check
  { index: 2, title:'Beauty', ... } 
]

const checkCard = (cardIndex) => {
  const data = expectedData[cardIndex]
  cy.get('.discover-card')
    .should('contain', data.title)
    .click()                  // open card

  // test card internals

}

Cypress._.times(3, (pageNo) => {  // loop 3 times between pages
  Cypress._.times(4, (cardNo) => {  // loop 4 times for cards
    const cardIndex = ((pageNo+1) * (cardNo+1)) -1
    checkCard(cardIndex)
    cy.go.back()                // revert to menu
  })
  cy.get('.next-btn').click()
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 SuchAnIgnorantThingToDo-UKR