'How to test carousel with image in Cypress?

I need to write automation tests in Cypress for carousel with images.

I have something like this:

<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
    <div class="carousel-inner">
        <div class="carousel-item active">
          <img class="d-block w-100" src="..." alt="First slide">
        </div>
        <div class="carousel-item">
          <img class="d-block w-100" src="..." alt="Second slide">
        </div>
        <div class="carousel-item">
          <img class="d-block w-100" src="..." alt="Third slide">
        </div>
      </div>
      <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="sr-only">Previous</span>
      </a>
      <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="sr-only">Next</span>
      </a>
    </div>

The carousel change automatically. The active image gets class "slider_wrapper__activeSlide__2LNke", and the other image has class "slider_wrapper__nextSlide__1Vnk4". I would like to check whether the carousel is displayed on the page and whether the active image has the correct class.

I try with .should ('include') but it does not work :(



Solution 1:[1]

You can use .find() to query for elements underneath a yielded element.

cy.get('.carousel-item.active') // get the active div
  .find('img') // get the img element underneath the above div
  .should('be.visible') // check that the element is visible
  .and('have.class', 'slider_wrapper__activeSlide__2LNke'); // check for the active image class.

If you need to check each of the carousel items, you'll have to use JQuery's hasClass.

cy.get('.carousel-item') // retrieve all elements with carousel-item class
  .each(($item) => { // iterate through all elements
    cy.wrap($item) // wrap the yielded element
      .find('img') // find the img
      .should('have.class', $item.hasClass('active') ? 'slider_wrapper__activeSlide__2LNke' : 'slider_wrapper__nextSlide__1Vnk4'); 
      // ^ ternary to determine which class we are checking for

Solution 2:[2]

The carousel change automatically. To test that aspect, use cy.clock() to "freeze" the movement, then cy.tick(3000) to slide to next image (assuming 3 second delay).

cy.clock()
cy.get('div#carouselExampleControls')
  .find('div.carousel-item.active')
  .invoke('index')
  .should('eq', 0)                    // first image is active

cy.tick(3000)

cy.get('div#carouselExampleControls')
  .find('div.carousel-item.active')
  .invoke('index')
  .should('eq', 1)                    // second image is active

Try not to use classes with suffixes like __2LNke, they could be generated by the framework and change on next build.

If you want to check then, use the prefix part slider_wrapper__activeSlide and slider_wrapper__nextSlide

cy.get('[class*="slider_wrapper__nextSlide"]')  // partial matching, more robust

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 agoff
Solution 2 Fody