Home > Software design >  How to wait for children to be greater than X in Cypress
How to wait for children to be greater than X in Cypress

Time:05-24

I'm writing a test for a page, that loads the content via an AJAX-call. Here is the events:

Step 1: Page loads
Step 2: AJAX-call fetches content
Step 3: AJAX-call retrieves status 200
Step 4: X seconds passes
Step 5: Content is displayed on the page

My test is flaky, since it varies a lot how many seconds that passes in step 4, before the content is displayed.

Here is my code:

it( 'Test content is there', () => {
  cy.fixture( 'my-fixture-path/article.json', "utf8" ).as( 'article' );


  cy.get( "@article" ).then( ($article) => {
    cy.intercept({
      method: 'GET',
      url: '/wp-json/my-namespace/public/v1/article/'   $article.postId,
    }).as('contentApiCall');
  });

  cy.get( "@article" ).then( ($article) => {
    cy.wait( '@contentApiCall' ).then( ({response}) => {


      // This expect-line always passes
      expect( response.statusCode ).to.equal( 200 );


      // This check here is flaky, depending on how quickly the content renders
      // after the API-call is returned.
      cy.get( '#main .post-content' ).children().its( 'length' ).should( 'be.gte', 4 );
      // The "Greater than 4" is because I'm checking for "More than 4 <p>-tags"

      
    });
  });
});

Can (and should) I change this line here:

cy.get( '#main .post-content' ).children().its( 'length' ).should( 'be.gte', 4 );

From:

'Are the length of #main .post-content-children more than 4'

To:

'Wait until the length of #main .post-content-children is more than 4'

?

... And if so - how do I do that?

CodePudding user response:

Should assertions will continue to retry until the expected conditions are met. Now by default timeout is 4 seconds in cypress, but you can give custom timeouts for this.

cy.get('#main .post-content', {timeout: 7000})
  .children({timeout: 7000})
  .its('length')
  .should('be.gte', 4)

CodePudding user response:

Some times using .its('length') in a chain will break the retry mechanism.

You can fix it by using the callback version of .should()

cy.get( '#main .post-content' ).children()
  .should( $children => {
    const count = $children.length    // move this inside the callback
    expect(count).to.be.gte(4) 
  })
  • Related