I am trying to read data from API response. The html in Chrome Inspect shows the value, but the number changes either to 4 or 5. I need Cypress to read the data, and based on the value, do a certain condition.
html
<p _ngcontent-wvl-c5="" class="availablelicenses"> 5 </p>
cypress
it("number of licences", function(){
cy.get('p[class="availablelicenses"]').as("avc");
cy.get('p[class="totallicenses"]').as("ls");
if (avc == ls){
cy.get('button[id="cyAdd"]').click()
cy.get('p[class="add-user"]').contains('All licenses are already assigned')
}
else {
cy.get('button[id="cyAdd"]').click()
cy.get('[data-cy=cyFirst').type('testName')
cy.get('[data-cy=cyLast').type('testLast')
cy.get('[data-cy=cyEmail').type('testEmail@mailinator.com')
}
});
The easiest way is to get text first like this:
const licensesOne = document.querySelector('p[class="availablelicenses"]').innerText;
const licensesTwo = document.querySelector('p[class="totallicenses"]').innerText;
if (licensesOne === licensesTwo) {
// Checks to run if texts are equal
} else {
// Checks to run if texts are different
}
Note that both .innerText
& .querySelector(…)
work only with one element at aa time. If you have more than one element, you might want to use a loop. Also, .innerText
might work inconsistently across browsers.
Apart from that, as @eric99 correctly points out, document.querySelector
will not wait at all for element to update/appear. So, if you run this test just after API call, you might prefer to use the method explained below.
There's also an alternative & slightly more involved way proposed by Cypress . Applied to your case, it would look something like this:
// Gets text of element and passes it to "then" callback
cy.get(`p[class="availablelicenses"]`).invoke('text').then(
availableLicensesText => {
//Gets text of second element & passes it to "then" callback
cy.get(`p[class="totallicenses"]`).invoke(`text`).then(totalLicensesText => {
if( availableLicensesText === totalLicensesText){
// Checks to run if texts are equal
} else {
// Checks to run if texts are different
}
});
}
);
If possible, I recommend ditching the if statement, and performing two tests. This will give you better coverage by ensuring both paths are tested.
context("number of licences", function() {
it('when max licences not assigned, should allow licence entry', () => {
cy.server();
// Stubbed with mock response of same shape as real response
cy.route('api/path/to/licence/count', {
assigned: 4,
total: 5
})
cy.contains('p[class="availablelicenses"]', '4'); // confirms stubbed response used
cy.contains('p[class="totallicenses"]', '5');
cy.get('button[id="cyAdd"]').click()
cy.get('[data-cy=cyFirst').type('testName')
cy.get('[data-cy=cyLast').type('testLast')
cy.get('[data-cy=cyEmail').type('testEmail@mailinator.com')
});
it('when max licences assigned, should not allow licence entry', () => {
cy.server();
// Stubbed with mock response of same shape as real response
cy.route('api/path/to/licence/count', {
assigned: 5,
total: 5
})
cy.contains('p[class="availablelicenses"]', '5'); // confirms stubbed response used
cy.contains('p[class="totallicenses"]', '5');
cy.get('button[id="cyAdd"]').click()
cy.get('p[class="add-user"]').contains('All licenses are already assigned')
});
});
If you can't stub the API, you could use something similar to Igor's last suggestion, but I would stay away from document.querySelector('p[class="availablelicenses"]')
as it's going to be flakey, see this section of the docsRetry-ability .
Also, use should()
instead of .then()
for the same reason.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.