I have one page for uploading a file which will be processed by the server in the background. I then have a second page where it shows only files that have been processed, which can take anything up to 5 seconds.
At the moment the code I have does this
cy.visit('/') cy.get('.busy-spinner').should('not.exist', { timeout: 10000 }) cy.contains('Submit file').click() cy.get('[id="requestinputFile"]').attachFile('test-file.txt'); cy.contains('Upload').click() cy.contains('.notifications', 'Your file has been uploaded', { timeout: 10000 }) cy.wait(5000) cy.visit('/processed-files') cy.get('[data-render-row-index="1"] > [data-col-index="1"]').contains(filename)
Sometimes the wait is far too long, sometimes it is not long enough. What I want to do is to go to /processed-files
immediately and check if the row with my filename exists.
If it does then continue. Otherwise
- Pause for 1 second
- Click a specific button (to reload the data on the page)
- Wait until .busy-spinner does not exist (the data has been reloaded)
- Check if the row exists
If it does then pass, otherwise loop – but for a maximum of 30 seconds.
This pattern will be repeated in many places, what is the best way to achieve this?
Advertisement
Answer
Can you just wait on the filename?
cy.contains('[data-render-row-index="1"] > [data-col-index="1"]', filename, { timeout: 30_000 } )
If the reload is needed to get the correct row entry, a repeating function is a possibility
function refreshForData(filename, attempt = 0) { if (attempt > 30 ) { // 30 seconds with a 1s wait below throw 'File did not appear' } // Synchronous check so as not to fail const found = Cypress.$(`[data-render-row-index="1"] > [data-col-index="1"]:contains('${filename}')`) if (!found) { cy.wait(1_000) cy.get('Reload button').click() cy.get('Spinner').should('not.be.visible') refreshForData(filename, ++attempt) } } refreshForData(filename) // pass in filename, function can be globalized // maybe also pass in selector?