Cypress - get element without assertion - cypress

How do I get an element in Cypress without it asserting that it is present?
cy.get('.something')
Sometimes my element might not be there and I don't want it to fail the test.
Is there a different command I should be using?

You can use cy.$$('selector') to synchronously query for an element (jquery).
If you want this to happen after a cypress command, you'll need a .then:
cy.visit('/')
cy.get('element-one').then(() => {
const $el2 = cy.$$('element-two')
if ($el2.length) {
// do this
} else {
// do that
}
})

You might want to check this section of the docs in Cypress
https://docs.cypress.io/guides/core-concepts/conditional-testing.html#Element-existence

Related

How to programmatically stop a Cypress test

I have a Cypress test that has only one testing case (using v10.9 with the test GUI):
describe("Basic test", () => {
it.only("First test", () => {
cy.visit("http://localhost:9999");
cy.pause();
//if(cy.get("#importantBox").contains(...) {
//}
//else
{
Cypress.runner.stop();
console.log("Stopping...");
}
console.log("Visiting...");
cy.visit("http://localhost:9999/page1");
If a certain element doesn't exist in the page, I don't want the test to continue, so I try to stop it.
Unfortunately, I can see this in the console:
Stopping...
Visiting...
And the test keeps going without the necessary data...
So, can I somehow stop it without using huge if statements?
Stopping the test is relatively easy, the harder part is the condition check.
Cypress runner is built on the Mocha framework, which has a .skip() method. If you issue it in your else clause and inside the Cypress queue, the test will stop.
Two ways to access skip():
Using a function() callback gives access to this which is the Mocha context
it('stops on skip', function() {
...
cy.then(() => this.skip()) // stop here
})
Use cy.state() internal command (may be removed at some point)
it('stops on skip', () => {
...
cy.then(() => cy.state('test').skip()) // stop here
})
You should be aware that all Cypress commands and queries run on an internal queue which is asynchronous to javascript code in the test like console.log("Visiting..."), so you won't get any useful indication from that line.
To use synchronous javascript on the queue, wrap it in a cy.then() command as shown above with the skip() method, so to console log do
cy.then(() => console.log("Visiting..."))

cypress should be called with value test

Looking for a test like below. Basically I get it to work using cy.get('#myLog').should('be.called') but I'm trying to test the value console log is using when called. In jest it would be toHaveBeenCalledWith() so the equivalent in cypress is what I'm after ?
cy.window().then((win) => {
cy.wrap(cy.spy(win.console, 'log')).as('myLog')
})
cy.get('#myLog')
.should('be.called')
.and('have.value', 'clicked')
cy.spy() and cy.stub() you can use Sinon-chai assertions. So for you instance you may want to use be.calledWith.
cy.window().then((win) => {
cy.wrap(cy.spy(win.console, 'log')).as('myLog')
})
cy.get('#myLog')
.should('be.calledWith', 'clicked')

I want to use assertion for the checkbox

I want to use assertion for this checkbox. It depends on duration. If it's checked duration = forever, if not = a month.
cy.wrap(cy.get('span.ant-checkbox').should('have.class','ant-checkbox-checked')).then((a) => {
if a == true {
cy.log('Forever')
}
})
A few thoughts:
You don't need to cy.wrap() your entire statement. cy.wrap() would primarily be used to wrap a JQuery yielded from cy.get() or a similar command, and insert it back into the Cypress command chain.
Your assertion that the element has a certain class will fail and stop your test before even getting to the .then() part of the command if the element does not have the ant-checkbox-checked class.
Instead, if we get the element, we can use JQuery functions (in this case, .hasClass())to determine if it has the class we want.
cy.get('span.ant-checkbox').then(($el) => {
// cy.get yields a JQuery<HTMLElement>
if ($el.hasClass('ant-checkbox-checked')) {
cy.log('Forever');
} else {
cy.log('A month');
}
});

How to handle Exceptions in Cypress in a similar way we did in selenium

In selenium we can handle exception. If any exception occur in any testcase it will then jump onto next testcase we can did in selenium. But i an confused that how can we did this in Cypress. Taking below example
it('Test Case 1', function () {
cy.visit('https://habitica.com/login')
cy.get('form').find('input[id="usernameInput"]').click().type("username")
cy.get('form').find('input[id="passwordInput"]').click().type("password")
**cy.get('.btn-info').click()**
cy.get('.modal-dialog').find('button[class="btn btn-warning"]').click()
cy.get('.start-day').find('button').click({force:true})
})
it('Test Case 2', function () {
cy.visit('https://habitica.com/login')
cy.get('form').find('input[id="usernameInput"]').click().type("username")
cy.get('form').find('input[id="passwordInput"]').click().type("password")
cy.get('.btn-info').click()
cy.get('.modal-dialog').find('button[class="btn btn-warning"]').click()
cy.get('.start-day').find('button').click({force:true})
})
Lets say browser unable to find click element (Highlighted with bold) in testcase 1 then it will jump onto Testcase 2.
How can we do it in Cypress?
Please help me on this
Exceptions like Unable to fine element or similar others.
Other than this example how can we handle exceptions or error.
Although Cypress team is saying that we need to avoid conditional test as much as possible (and maybe a need to change your approach). However, in you case, you can include a conditional test:
cy.get('.btn-info').then((body) => {
if (body.length > 0) { // continues if the element exists
cy.get('.btn-info').click();
cy.get('.modal-dialog').find('button[class="btn btn-warning"]').click()
cy.get('.start-day').find('button').click({force:true})
} // if the above condition is not met, then it skips this the commands and moves to the next test
});
Thanks alot for your response. Please have a look at this. I have used your code. "'.btn-info'" does not exist so exception occur which is fine. but problem is it do not move onto else statement. I mean If statement gets failed then it must execute else but it do not. Why it is doing so?
it('First Test Case', function() {
cy.visit('http://pb.folio3.com:9000/admin/#/login');
cy.get('.btn-info').then((body) => { // **THIS ELEMENT NOT EXIST**
if (body.length > 0) { // continues if the element exists
cy.get('.btn-info').click();
cy.get('.modal-dialog').find('button[class="btn btn-warning"]').click()
cy.get('.start-day').find('button').click({force:true})
}
else
{
**cy.visit('https://www.facebook.com/');**
}
});
it('Second Test Case', function() {
cy.visit('https://www.google.com/');
})

Post result to external api after each test case

I'm setting up a CI-chain and decided to use Cypress for the UI testing. I need to get the result for each individual testcase in my suite. Preferably from within Node in for example a afterEach statement.
Has anyone done this before? Is there any built-in support for this?
I do not want to parse the end result for testcases preferably.
It was possible by using Mocha's this.currentState in conjunction with Cypress plugins.
This is how I solved it:
cypress/plugins/index.js
on("task", {
testFinished(event) {
console.log(event.title, event.result);
return null;
}
});
in my testsuite
afterEach(function() {
cy.task("testFinished", { title: this.currentTest.title, result: this.currentTest.state });
});
The console.log in plugins can now easily be switched for a POST request to wherever you want to store the results.

Resources