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?