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