Search code examples
typescriptcypressspartacus-storefront

How do I check all values in a Spartacus shop using Cypress?


I'm currently trying to test a shop in Cypress. One test is intended to test the usage of price filters. In my example, there are 4 filters that I want to click on one after the other. Then the first step is to ensure that the filters have been applied. However, I fail when selecting the filter. As long as I only choose one, the selection works.

I suspect it has to do with the asynchronous nature of Cypress. How do you do it right?

fixture file:

[...]

"priceRanges": [
    "$50-$199.99",
    "$200-$499.99",
    "$500-$999.99",
    "$1,000-$100,000"
  ],
[...]

DOM

<a
  routerlink="./"
  class="value selected"
  href="/electronics-spa/en/USD/Open-Catalogue/Cameras/Hand-held-Camcorders/c/584?query=:relevance:allCategories:584"
  data-cx-focus="$1,000-$100,000"
  tabindex="0"
  ><span
    ><span class="label">$1,000-$100,000</span
    ><span class="count">1</span></span
  ></a
>

This is what I tried:


  it.only('There shall be a way to filter products by price range', function () {
    const homePage = new HomePage();
    homePage.openProductCategoryLink('5'); // Camcorders
    // Stores, Price, Resolution, Brand
    cy.get('cx-facet').should('have.length', 4);
    cy.get('cx-facet').then((items) => {
      expect(items).to.have.length(4);
      cy.wrap(items[1]).children('button').should('contain.text', 'Price');

      // check for price ranges
      this.filterCriteria.priceRanges.forEach((aPriceRange: any) => {
        cy.wrap(items[1]).children().should('contain.text', aPriceRange);
        cy.log(aPriceRange);
        //  Price $50-$199.991$200-$499.993$500-$999.991$1,000-$100,0001
        // TODO: narrow the range and see if the filter is applied correctly
        cy.get(`a[data-cx-focus="${aPriceRange}"]`).then((linkFound) => {
          cy.log('Click on: ' + aPriceRange);
          cy.wrap(linkFound).click();
        });
      });
    });
  });

There is only the last item checked instead all of them


Solution

  • The code looks ok, forEach loops are a bit of a red flag but that one should work.

    If you want to click all the check boxes, this should do it for you

    cy.get(`a[data-cx-focus]`)   // select all four ranges by not specifying the range value
      .click({ multiple: true }) // multiple items clicked at once
    

    By the way, cy.wrap(items[1]).children('button').should('contain.text', 'Price') - do you have to click that open first?


    Looking at the site, I think the forEach loop in the test is going too fast for the page refresh to keep up.

    Try adding a check within the loop, say looking for the Applied Filter tags

    this.filterCriteria.priceRanges.forEach((aPriceRange: any, index: number) =>{
    
      cy.wrap(items[1]).children().should('contain.text', aPriceRange);
      cy.log(aPriceRange);
      //  Price $50-$199.991$200-$499.993$500-$999.991$1,000-$100,0001
      // TODO: narrow the range and see if the filter is applied correctly
      cy.get(`a[data-cx-focus="${aPriceRange}"]`).then((linkFound) => {
        cy.log('Click on: ' + aPriceRange);
        cy.wrap(linkFound).click();
    
        cy.get('cx-active-facets a')         // get the price-range tags under "Applied filter"
          .should('have.length', index + 1)  // wait for the correct number
      });
    });