Reputation: 1370
So I built out a command that I'm using in multiple tests that looks at the page and if a prompt is there then the page is redirected to another page to handle the prompt (in this case approving a schedule). Then it additionally looks at that new page and if the page has some text instead then it redirects to the home page (where the issue lies) OR it clicks the button to approve and redirects to the home page and continues normally through the test.
Cypress.Commands.add('approval_redirect', () => {
cy.get('body').then(($body) => {
if ($body.text().includes(
'You must approve your weekly schedule before starting!'
)) {
cy.get('.container a')
.first()
.click()
cy.get('main').then(($main) => {
if ($main.text().includes('schedule')) {
cy.get('button')
.click()
cy.pause()
} else {
cy.get('ul > button')
.click()
}
})
}
})
})
Right now if it's going to the new page to verify the schedule and does NOT have a button to click it's returning home and then pausing. I put in the pause because it would then continue the test with massive failures.
So for example in one test I have:
it('starts here', function (){
cy.login()
.wait(1000)
cy.approval_redirect()
cy.get('#Route')
.click()
.wait(1000)
})
So in this if it redirects home after not clicking the button I'd like for it to completely stop the test. There's nothing to actually do.
Is there a way to completely stop the runner? How do I put that in my test to check against the command for failure?
I thought I could just wrap a function around the command with something like:
function findFailure(failure,success){cy.get...}
Then instead of cy.pause() I put
failure();
return;
And under the ul > button I put
success();
return;
Then in my test I did:
it('starts here', function (){
cy.login()
.wait(1000)
cy.approval_redirect()
const failure = function(){
this.skip()
}
const success = function(){
cy.get('#Route')
.click()
.wait(1000)
}
})
There are no errors and the test runs but it doesn't actually go through the command now. So how do I conditionally stop the cypress test?
Upvotes: 3
Views: 9563
Reputation: 1370
After a bit I noticed an issue with my conditional as it was looking for if a prompt was there then go to the schedule; then if certain text wasn't there then go home (where the pause/desire to abort lived) OR click on the button, go home and finish. I noticed that I didn't put in another else on the first condition.
My solution was to just create a function that contained all the steps for a complete test barring no redirects/redirect that had a button click. Then I put in the failures a console log about what happened to end the test. Something like:
cy.log('Schedule not approved, redirected, no published schedule. Test ended.')
This gives a clean end/break to the test. Albeit wrapping a success/failure would be wonderful.
Upvotes: 1
Reputation: 355
This one is interesting. I commend your resourcefulness, especially since Cypress has strong feelings when it comes to conditional testing due to its asynchronous nature.
I had a similar problem recently. For me, nothing on a page was clickable at a certain point if there was network activity, and a toast would appear saying "Loading...", and nothing could be done until network activity was done and the toast disappeared. Basically, I needed the page to wait as long as it needed for the toast to disappear before continuing (thus conditional testing).
What I did was something like this:
In commands.js
:
Cypress.Commands.add('waitForToast', () => {
cy.get('toast-loading', {timeout: 20000}).should('not.exist');
});
Then in the actual test.spec.js
, using the command:
cy.waitForToast();
What's happening here is Cypress is pausing the test and looking for the toast, and waiting with a timeout of 20000 milliseconds. If the toast gets stuck, the test will exit/fail. If the toast disappears, the test will continue.
Using asserts so far has been the most effective way to do conditional testing. If you're waiting for a button to appear, use an assert with a longer timeout to wait for it. Then, if it doesn't show up, the test will exit and fail.
In your case, you can assert if you didn't go home.
Alternatively
If you want the test to just end without asserting and failing, you can try something like this:
cy.get('home-page-item`)
.its('length')
.then(numberOfItems => {
if (numberOfItems > 0) {
DO-NOTHING-ASSERT
} else {
CONTINUE-TEST
}
});
Otherwise I don't think Cypress has anything like cy.abortTest()
, so you'll have to work around their anti-conditional testing methodology with asserts or if else.
Upvotes: 1