Reputation: 2445
In my Cypress tests, I am trying to compare an array of objects (names) returned to me from a SQL query against a list of elements on my UI (the same names).
Here is my initial attempt at comparing the values:
import searchResultsPage from "../page_objects/searchResults.page"
cy.task('queryDb', `SELECT * FROM myTable where name like '%${queryInput}%';`).then(result => {
for(var i=0;i<result.length;i++) {
searchResultsPage.name(i+1).should('have.text', `${result[i].name}`)
}
})
Here is my page object file - searchResults.page.js
:
class searchResultsPage {
name(index) { return cy.get(`#mat-option-${index+1} > .mat-option-text`) }
}
module.exports = new searchResultsPage()
The problem with the above code is that the lists contain the exact same values, however they are not in the same order.
The database can store the names like Adam, Bill, Charlie, but the UI may display them like Charlie, Adam Bill.
The test should pass if the same records are in both lists, regardless of their order.
I attempted to re-order both arrays alphabetically below, & compare the values. The array from the SQL query (result
) is sorting as expected. However, the array of HTML elements (myArray
) is not sorting alphabetically:
cy.task('queryDb', `SELECT * FROM myTable where name like '%${queryInput}%';`).then(result => {
let myArray;
cy.get('mat-option').then(elements => {
myArray = Array.from(elements, element => element.innerText);
cy.log(myArray)
myArray.sort((a, b) => {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
cy.log('HTML array:')
for (var i = 0; i < myArray.length; i++) {
cy.log(myArray[i])
}
cy.log('*********')
result.sort((a, b) => {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
cy.log('SQL array:')
for (var i = 0; i < result.length; i++) {
cy.log(result[i].name)
}
cy.log('*********')
}).then(() => {
for (var i = 0; i < result.length; i++) {
cy.log(result[i].name)
cy.log(myArray[i])
expect(result[i].name).to.deep.eq(myArray[i])
}
})
})
Can someone please explain why the result
array isn't sorting alphabetically above?
Upvotes: -1
Views: 849
Reputation: 10555
Rather than trying to sort it yourself, you can use set membership
cy.task('queryDb', `SELECT * FROM myTable...`).then(result => {
cy.get('mat-option')
.should(elements => {
const elementNames = Array.from(elements, element => element.innerText))
const resultNames = result.map(r => r.name)
expect(resultNames).to.have.members(elementNames)
})
})
Using .should()
will allow Cypress to retry to the assertion (in case the elements are still loading).
Ref: Testing Arrays and Objects with Chai.js
Upvotes: 1
Reputation: 35684
One way to do it is to split sort and join both the sql and the html texts
it("does some checking", () => {
// this would come from the sql task
const myExpectation = "Charlie, Adam, Bill";
// split, trim, sort, and join the string
const cleanSql = str => str.split(/[\,]/gi).map(s => s.trim()).sort().join(",");
// function uses `then` to get texts and sort and join it
const getNames = (index) => {
return cy
.get(`#mat-option-${index + 1} > .mat-option-text`)
.then((chainer) => {
const values = [...chainer.map((el) => chainer[el].innerText)];
return values.sort().join(",");
});
};
// uses `equal` because the returned value is a string (have.text wouldn't work on it)
getNames(1).should("equal", cleanSql(myExpectation));
});
This assumes your html looks like this
<div id="mat-option-2">
<div class="mat-option-text">Bill</div>
<div class="mat-option-text">Adam</div>
<div class="mat-option-text">Charlie</div>
</div>
I'm using static myExpectation
for local testability. You would, obviously, have to adapt that to your setup.
Upvotes: 0