Assert sorting in an table using Cypress

2019-08-22 02:11发布

问题:

Well, I have a table with many rows and columns, I would like to check if the table is sorted for a particular column.

I have tried using different expects and asserts but its always returning true. Am I doing anything wrong here?

cy.get('table tbody tr').should(function($trs) {
  var arrayOftd = $trs.map(function (i, tr) {
    return Cypress.$(tr).find('td').eq(3).text() 
  })
  var test = arrayOftd.sort()          
  expect(arrayOftd).to.deep.equal.(test)
})

It has to return true when sorted ascending and false when descending or any other order.

This is the console log of the assert statement

Command: assert cypress_runner.js:172385 Actual: (13) ["946", "947", "948", "951", "952", "955", "956", "959", "960", "963", "964", "967", "968"] cypress_runner.js:172385 Expected: (13) ["946", "947", "948", "951", "952", "955", "956", "959", "960", "963", "964", "967", "968"] cypress_runner.js:172385 Message: expected [ Array(13) ] to equal [ Array(13) ] cypress_runner.js:172385 Error: AssertionError: expected [ Array(13) ] to equal [ Array(13) ]

回答1:

It may be a personal preference but I try not to use jQuery syntax if I don't really need to, for better readability. What I've done is:

function getCellTextAsArray(){
            let cellContents = []
            return new Cypress.Promise(resolve => {
                cy.get('table tbody tr')
                    .children()
                    .each(($el, $index) => {
                        //some logic to select the elements you want
                        //like $index % 4 == 0
                        if(...) {
                            cellContents.push($el.text())
                        }
                    })
                    .then(() => resolve(cellContents))
            })
        }

And then you do your assertion without having to worry about passing callbacks:

getCellTextAsArray()
                .then(cellContents => {
                    let actual = cellContents.slice()
                    cy.wrap(actual)
                        .should('deep.eq', cellContents.sort())})

So what happens here is that we are trying to use higher level Cypress commands to grab all the tds, and when we are done with them we resolve the Promise with the tds text content, then it's kind of easy and readable to do a final assertion.



回答2:

tl;dr

You have to copy the array before sort otherwise you assert it to itself, since sort changes the array.

var test = arrayOftd.slice().sort()

Explanation

sort doesn't return a new copy, it changes the array in-place so when you assign its return value to test and compare it to arrayOftd you compare it to itself.

Referencing the MDN docs:

The sort() method sorts the elements of an array in place and returns the sorted array.

Keep in mind that slice is doesn't create a deep copy of the array, it only copies its first level, but if you change the ordering on the first level only, you should be fine.