2

I want to test whether the carousel on my website contains the correct items that are represented as company logos. Each carousel item has an <img> element with the 'alt' attribute which is where the name of the company is stored.

I have set an environment variable in the cypress.env.json file, which is represented something like this:

"companyPartners": {     
    "title": "Company Partners",     
    "partners": {         
        "google": "Google",         
        "facebook": "Facebook",         
        "instagram": "Instagram",         
        "linkedin": "LinkedIn"     
    } 
} 

The carousel elements are represented in an unordered list, something like this:

<ul class="carousel-partners ...">
    <li>
        <a class="carousel-item">
            <img alt="Google" src="...">
        </a>
    </li>
    <li>
        <a class="carousel-item">
            <img alt="Facebook" src="...">
        </a>
    </li>
    ...
</ul>

So, I want to iterate through each carousel item and verify that the values from the environment variable match the 'alt' attribute of the carousel items.

While running this command in Cypress, I am getting an error which says that only the first letter is retrieved:

Cypress.Commands.add("verifyPartners", () => {
    const companyPartners = Cypress.env("companyPartners").partners
    let text = ""
    for(const x in companyPartners){
        text += companyPartners[x]
    }

    cy.get('*[class^="carousel-partners"]').find("li").each(($listItem, index) => {
        cy.wrap($listItem).find("img").should("have.attr", "alt", text[index])
    })
});

assert expected <img.h-12.w-auto.object-contain.saturate-0> to have attribute alt with the value G, but the value was Google

Is there any way I can verify the items? Any help would be appreciated.

1
  • Hello! It seems that in your case there is a problem with parsing the env variable as a json object. I would say that in general Cypress Environment Variables are more intended for strings, rather than objects. I would suggest using fixtures instead. It also is more consistent with how DDT should be performed - data sets stored separately in a dedicated folder. I also generally suggest keeping env variables in a config file, rather than in a json file. Commented Jul 2 at 10:57

1 Answer 1

4

I'm going to assume there is one-to-one equivalence between the list and the DOM elements.

To do this

  • convert partners object to array of RHS values with Object.values()
  • use within() to narrow the scope of queries
  • check each partner name is in the DOM on an <img> inside an <li>
  • then check there's no surplus <img> tags
const partners = Cypress.env("companyPartners").partners

/* 
  take value part of key/value in partners object
  yields ['Google','Facebook',...]
*/
const companies = Object.values(partners)

cy.get('ul.carousel-partners').within(() => {
  // queries here only apply to the contents of the <ul>

  // Two questions:

  // 1) Does every partner exist in the DOM on an li[alt] attribute?
  companies.forEach((company) => {
    cy.get(`li img[alt="${company}"]`)   // passes if exists
  })

  // 2) Does every DOM <li> have a value in the partners list?
  cy.get('li img').each(($img) => {
    const alt = $img.attr('alt')
    expect(alt).to.be.oneOf(companies)
  })

})
  
1
  • Thank you for your answer, I really appreciate it. I used the first part of the code and resolved the issue. I managed to verify the 'alt' value with the values from the variable. Have a great day! companies.forEach((company) => { cy.get(li img[alt="${company}"]) // passes if exists })
    – bazzinga
    Commented Jul 2 at 9:25

Not the answer you're looking for? Browse other questions tagged or ask your own question.