How to test an infinite scroll component in Cypress
Asked Answered
B

2

6

I have an dynamically loaded table based on an infinite-scroll component. I can test the loaded items as follows, but only 20 items are loaded at a time.

How can I repeat until the 500th item comes into view without repeating the code 100 times?

cy.get('div.infinite-scroll-component')
  .children()
  .should('have.length', 20)
  .last()
  .scrollIntoView()

cy.contains('Loading')
  .should('be.visible')
<div class="infinite-scroll-component" style="height: auto; overflow: auto;">List:
  <div style="height: 30px; border: 1px solid green; margin: 6px; padding: 8px;">Item #0</div>
  <div style="height: 30px; border: 1px solid green; margin: 6px; padding: 8px;">Item #1</div>
  <div style="height: 30px; border: 1px solid green; margin: 6px; padding: 8px;">Item #2</div>
  <div style="height: 30px; border: 1px solid green; margin: 6px; padding: 8px;">Item #3</div>
  ...
Bane answered 6/8, 2022 at 1:42 Comment(0)
K
7

To repeat an action until a certain element appears on the page, use a recursive function.

You must be careful to only take the next step after the action is complete.

In your case the "Loading" indicator has appeared, and then wait for the load to complete (timing may need adjusting).

const findItem = (item, attempt = 1) => {
  if (attempt === 100) throw 'Not found'
  return cy.get('div.infinite-scroll-component')
    .children()
    .then($els => {
      const found = [...$els].some(el => el.innerText === item)
      if (!found) {
        // trigger load with scroll
        cy.get('div.infinite-scroll-component')   
          .children()
          .last()
          .scrollIntoView()
        cy.contains('Loading')
          .should('be.visible')
          .then(() => {
            cy.wait(100)                       // wait for loading

            // OR check the list length 
            const expectedListLength = (attempt +1) * 20
            cy.get('div.infinite-scroll-component').children()
              .should('have.length', expectedListLength)     

            return findItem(item, ++attempt)   // next step
          })
      }
      return cy.get('div.infinite-scroll-component')
        .children(`:contains(${item})`)
    })
}

findItem('div - #100').should('have.length', 1)  // just one item
  .and('contain.text', 'div - #100')             // verify it's text
Kelikeligot answered 6/8, 2022 at 1:57 Comment(2)
Thank that work pretty well, expect it returns the whole list and not just the found item.Bane
Sorry I missed a step.Kelikeligot
C
-1
describe("implemented the cypress scripts for the infinite scroll", () => {
    it("test case for the infinite scroll", () => {
        cy.visit('https://scrollmagic.io/examples/advanced/infinite_scrolling.html');
        cy.get('.box1').should('have.length.greaterThan', 0);

    // Define the number of times to scroll
    const scrollTimes = 8;
    
    // Define a function to scroll to bottom and assert loader is not visible
    const scrollAndWait = () => {
      cy.window().scrollTo('bottom',{duration:1000});
      cy.get('#loader').should('not.be.visible');
      cy.scrollTo('bottom', { duration: 1000 });
    };

    // Use a loop to scroll multiple times
    for (let i = 0; i < scrollTimes; i++) {
      scrollAndWait();
      cy.wait(1000); // Adjust the wait time as needed
    }

    // Final assertion to check more items are loaded
    cy.get('.box1').should('have.length.greaterThan', 20); 

    cy.scrollTo('top', {duration:5000})
  });
})
Coinsurance answered 8/7 at 6:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.