Samira Arabgol
Samira Arabgol

Reputation: 389

Cypress: check the value of a cell in a table using polling

I have a table that has a status column, I want to check the status of the fist row (which is at last column) . the status goes from "in progress" to completed after some amount of time (max 5 min);

here is the DOM:

<tbody>
   <tr>
      <td>...</td>
      <td> ... </td>
      <td> in progress / complete </td> //status => want to check this cell.
  </tr>
   <tr>
      <td>...</td>
      <td> ... </td>
      <td> ... </td> //status
  </tr>
   <tr>
      <td>...</td>
      <td> ... </td>
      <td> ... </td> //status
  </tr>
</tbody>

how to reach to the cell I want and use polling mechanism to see if the status completed?

thank you for your help

Upvotes: 1

Views: 3160

Answers (5)

jjhelguero
jjhelguero

Reputation: 2555

It's unclear how the cell in your table is updated. Is there a request sent in intervals or only when first loading the page?

If its former, then it would be simple as such

// assuming only table on page and last cell of first row is always the cell you want
cy.get('tbody')
  .should('be.visible') // check table is fully loading in case
  .find('tr')
  .first() // same as .eq(0), just more readable
  .find('td')
  .last() // same as .eq(3), jut more readable
  .should('be.visible')
  .and('match.text', /complete/i) // can update command timeout

If you are dealing with the latter, then you'll have to use recursion to check after each page reload. Recommend using cypress-recurse

import { recurse } from 'cypress-recurse'

recurse ({
  () => {
    return cy.get('tbody tr:nth-child(0) td:nth-child(3)') // eq to above
    .should('be.visible')
  },
  ($el) => expect($el).to.have.text('complete'),
  {
    // can alter configurations
    timeout: 30_000,
    delay: 3_000,
    post: { cy.reload() }
  }
)
  

Upvotes: 0

I would first check the "in progress" status to ensure the sequence is correct.

cy.contains('tbody tr:eq(0)', 'in progress')
cy.contains('tbody tr:eq(0)', 'complete', {timeout:300000})

Upvotes: 2

TesterDick
TesterDick

Reputation: 10550

Cypress has built-in polling, no need to code a special routine.

This is all you need!

cy.contains('tbody tr:nth-of-type(1) td:nth-of-type(3)', 'complete', {timeout:300000})

No need for .find() or .within(), the selector 'tbody tr:nth-of-type(1) td:nth-of-type(3)' takes care of searching the table hierarchy.

The cy.contains() command asserts that the text "complete" should be in that cell, and the timeout automatically polls for 5 minutes.

It will pass earlier if the status changes earlier.

Note using .within() can give you "detached from DOM" error if the whole row is replaced upon status change.

Upvotes: 1

Alapan Das
Alapan Das

Reputation: 18626

You can also use within to go inside the first tr and wait for the desired amount of time for the text complete to appear. Something like this:

For exact text match:

cy.get('tbody')
  .find('tr')
  .eq(0)
  .within(() => {
    //eq(0) gets the first tr
    cy.get('td', {timeout: 300000}).eq(2).should('have.text', 'complete') //Exact text match
  })

For Partial text match:

cy.get('tbody')
  .find('tr')
  .eq(0)
  .within(() => {
    //eq(0) gets the first tr
    cy.get('td', {timeout: 300000}).eq(2).should('contain.text', 'complete') //partial text match
  })

Upvotes: 1

Fody
Fody

Reputation: 32044

The pattern for selecting row and column in Cypress would be

cy.get('tbody tr').eq(0)          // first row
  .find('td').eq(2)               // third col
  .should('contain', 'complete')  // criteria to check 

This waits for the defaultCommandTimeout setting which is 4000 ms. To extend to 5 minutes add a 300000 timeout.

cy.get('tbody tr').eq(0)              
  .find('td').eq(2, {timeout:300000})  
  .should('contain', 'complete')      // on fail retry above up to 5 minutes

But you might get errors with this depending on what changes in the DOM after status is updated. If the row or the table are refreshed with a new copy, you might need to combine the steps into one selector.

cy.get('tbody tr:nth-child(1) td:nth-child(3)', {timeout:300000})           
  .should('contain', 'complete') 

It's not always clear which steps in a command chain will be repeated when .should() fails.

Upvotes: 3

Related Questions