Home > front end >  Cypress - How to check the text of table subrows alongside normal rows
Cypress - How to check the text of table subrows alongside normal rows

Time:08-10

I have a table that structurally looks something like this

<table>
    <tbody>
        <tr>
            <td >--</td>
            <td >--</td>
            <td >--</td>
        </tr>
        <tr>
            <td >--</td>
            <td >--</td>
            <td >--</td>
        </tr>
        <tr>
            <td >
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
            </td>
            <td >
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
            </td>
            <td >
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
                <div>
                    <span >--</span>
                </div>
            </td>
        </tr>
    </tbody>
</table>

I'd like to write a cypress test (cucumber) that verifies that each entry in the first column is equal to '--'. I started with something like this

Then('The first column displays -- in every row', function () {
    cy.get(this.base).find('.first-col').each(($row) => {
        expect($row.text().trim()).to.equal('--');
    });
});

But of course that will concatenate the sub-rows and produce something like this when evaluating the third row

AssertionError
      expected - actual

    -'--  --  --'
     '--'

So I attempted to set up a simple check for sub-rows before expecting

Then('The first column displays -- in every row', function () {
    cy.get(this.base).find('.first-col').each(($row) => {
        const subRows = $row.find('.sub-row');
        if (subRows.length) {
            subRows.each(($subRow) => {
                expect($subRow.text().trim()).to.equal('--')
            });
        } else {
            expect($row.text().trim()).to.equal('--');
        }
    });
});

My thinking being that each $row corresponds to a tr , subRows corresponds to an array of the span elements in a given $row (if any), and then by iterating through the individual $subRows in subRows, I can assert on each of them.

The problem is that cypress is not recognizing $subRow as something it can perform functions on.

TypeError: $subRow.text is not a function

But it has no problem with the else part of the conditional that runs on the prior rows, which has very similar logic. It's not until the row with the subrows that it fails.

enter image description here

I have to imagine that I have a conceptual misunderstanding about what gets returned by .each(), or .find(), or both. Or maybe it's because the element is a span instead of a td? What am I missing?

CodePudding user response:

One fix is to wrap subrows.

cy.get('tr').find('.first-col').each(($row) => {
  const subRows = $row.find('.sub-row');
  if (subRows.length) {

    // wrap subrows variable to allow use of Cypress .each() command
    cy.wrap(subRows).each(($subRow) => {
      expect($subRow.text().trim()).to.equal('--')
    });

  } else {
    expect($row.text().trim()).to.equal('--');
  }
});

subrows is a jQuery object. If you look at the jQuery.each() docs you'll see that the callback has parameters function( index, value ), whereas the Cypress command .each() has parameters the other way round .each(($el, index, $list) => {.

The Cypress version is probably more convenient to use in this test.

  • Related