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

Viewed 88

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

2 Answers

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

Cypress comes bundled with lodash which can help with the async nature of Cypress. You should push for better adding better selectors so your test is easier to read and maintain

// if you don't plan on using price ranges in other test files

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

it.only('There shall be a way to filter products by price range', function () {
      // sectioncode stays the same

      // check for price ranges
      Cypress._.forEach((priceRanges: any), function(pRange){
        cy.wrap(items[1]).children().should('contain.text', pRange);
        cy.log('Click on: ' + pRange);
        cy.get(`a[data-cx-focus="${pRange}"]`).check();
        

        cy.get('.items-displayed').children('.price').each( p => {
           // code to check displayed items are within price range filter          
      });
    });
  });


Related