Cypress - How to get around with wait() after searching

Viewed 2206

I have the below scenario: I search for an element in search box. when the element appears (it may take some time), I click on the element which loads a new view. Then I try to click on some button in new view. since it takes some time to load the search result, the new view does not load. Any way I can avoid wait()?

This is what I have:

 cy.get('[data-cy="search"][data-component="input_box"]').type('Find me{enter}')
 cy.wait(200) // How to avoid this???
 cy.get('[data-name="Find me"]').contains('Find me').click()// Should load a new view 
 cy.get('[data-cy = "filter"]').click() // failing here as new view is not loaded

Any suggestions will be highly appreciated.

Similar one:

describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      // test step to launch a URL
      cy.visit("https://www.tutorialspoint.com/videotutorials/index.php");
      // enter test in the edit box
      cy.get("#search-strings").type("Java");
      // wait for some time
      cy.wait(3000); // ---> how to avoid this?
      // using jQuery selector to identify only visible elements
      // assertion to validate the number of search results
      cy.get('.clsHeadQuestion:visible'). should('have.length',19);
   });
});
3 Answers

In similar situation you can use cy.route() which grab the network request and wait for it. In your case, the route will grab the n/w req and wait for the "Find me" request to get processed completely so that you can proceed with the next filter action.

Steps: Open the chrome console, navigate to network tab, filter for XHR request. Now click on the ''Find me'' button in you page. You can see usually a GET request, for example if the request looks as follows, https://example.com.au/v1/api/listview?page=2 Please copy the url from /v1/api/... and add into the url value of cy.route() as below.

note: On click on Find me button, see its a GET or POST request, usually it will be GET request, check if the url has any encoded value, if it has encoded value you have to use decodeURIComponent() and the pass the url inside as follows >> url:decodeURIComponent('**/v1/api/listview?page=2**'),

beforeEach(()=>{
    cy.server();
    cy.route({
     method: 'GET',
     url:'**/v1/api/listview?page=2**',
     delay: 2000
    }).as('getLoadNewView');
  })

    it('Route waiting for loading the new view for filter action', () => {
      cy.get('[data-cy="search"][data-component="input_box"]').type('Find me{enter}')
      cy.get('[data-name="Find me"]').contains('Find me').click()// Should load a new view 
      cy.wait('@getLoadNewView');
      cy.get('[data-cy = "filter"]').click();
      })

Could you try adding an extra timeout to the get? Something like:

cy.get('[data-name="Find me"]', { timeout: 1000 }).contains('Find me').click()

It's not a perfect solution, but sometimes adding a timeout like that can help.

I would guess that there is some network activity going on on the background after you finish typing in the search bar. I usually wait for the request(s) to be completed and then check UI elements, when I have similar cases.

https://www.cypress.io/blog/2019/12/23/asserting-network-calls-from-cypress-tests/, scroll down to “Waiting for the network call to happen” section.

cy.wait('....') is still there, but this time I wait for something explicit that effects the UI

Related