2

I want to check in Cypress if the content in all rows of the column Name Document is identical. Let's say

Name Document Issue Date
GOL 21-06-2023
GOL 30-05-2023

This table does not have a fixed number of rows.

enter image description here

Bonus question: How can check if the most recent (Issue date column) is on the top?

A.Givens
  • 47
  • 4
Ingridd Brito
  • 91
  • 1
  • 15

2 Answers2

4

All of first column has value "GOL"

To extract column 1 elements only, use cy.get('tr td:nth-child(1)')

To map to the text inside, this is a useful recipe Getting Text from List of Elements

const getTexts = (els) => Cypress._.map(els, 'innerText')
cy.get('tr td:nth-child(1)')
  .then(getTexts)
  .should('deep.equal', ['GOL', 'GOL', 'GOL'])

If the rows are dynamic, use .every()

cy.get('tr td:nth-child(1)')
  .then(getTexts)
  .should(vals => {
    const allFirstColHasGol = vals.every(val => val === 'GOL')
    assert(allFirstColHasGol, 'All first column has value "GOL"'))
  })

First date is the latest

I recommend the dayjs library to handle dates

const dayjs = require('dayjs')
const customParseFormat = require('dayjs/plugin/customParseFormat')
dayjs.extend(customParseFormat)


const getTexts = (els) => Cypress._.map(els, 'innerText')
const toDate = (els) => Cypress._.map(els, el => dayjs(el, 'MM-DD-YYYY').$d) 

cy.get('tr td:nth-child(4)')
  .then(getTexts)
  .then(toDate)
  .should(dates => {
    const firstDateIsLateset = dates.slice(1).every(date => dates[0] > date)
    assert(firstDateIsLateset, 'First date is the largest'))
  })

TDD with the following, and change column values to make it pass/fail

<table>
  <tbody>
    <tr>
      <td><a>GOL</a></td>
      <td><span>06-02-2023</span></td>
    </tr>
    <tr>
      <td><a>GOL</a></td>
      <td><span>06-01-2023</span></td>
    </tr>
  </tbody>
</table>
Lola Ichingbola
  • 3,035
  • 3
  • 16
1

You can grab all of the tr elements underneath the tbody. You can then query for all results that are underneath tbody, are tr, and have your text (in your example, GOL), and compare the size of those two lists. This example assumes there is only one table on the screen.

cy.get('tbody tr').then(($tr) => { // find all `tr` underneath `tbody`
  cy.get('tbody tr:contains("GOL")') // use JQuery :contains() to find elements
    .should('have.length', $tr.length)
});

If you did not know the text of the first row, you could grab it from the yielded $tr element.

cy.get('tbody tr').then(($tr) => {
  const firstRowText = $tr[0].text();
  cy.get(`tbody tr:contains("${firstRowText}")`).should('have.length', $tr.length);
});

And if you need to operate an if/else based on them being equal:

cy.get('tbody tr').then(($tr) => {
  const firstRowText = $tr[0].text();
  cy.get(`tbody tr:contains("${firstRowText}")`).then(($el) => {
    if ($el.length === $tr.length) {
      // code here
    } else {
      // code here
    }
  });
});

For your bonus question, you would have to grab all of the dates. From that list, you could sort them and check if the first item in each list is equal.

cy.get('tbody tr span').then(($dates) => {
  const firstDate = $dates[0].text()
  // For an explanation of what this is doing, look at the linked answer
  const sortedDates = $dates.sort(function(a,b) {
    a = a.text().split('/').reverse().join('');
    b = b.text().split('/').reverse().join('');
    return a > b ? 1 : a < b ? -1 : 0;  
  });
  expect(sortedDates[0].text()).to.eql(firstDate);
});
agoff
  • 5,818
  • 1
  • 7
  • 20
  • the first solution was having a discrepancy in '.should('have.length', $tr.length)' it was expecting a number but was returned other. So, I removed this part and it worked, it is comparing the lines. about the bonus answer I am getting ```$dates[0].text is not a function``` . I forgot to mention the dates on my system are on the format mm/dd/yyyy – Ingridd Brito Jun 21 '23 at 17:19