Let's say you are visiting a page and sometimes the "agree to the terms & conditions" checkbox is already checked. If the checkbox is unchecked, the Submit button is disabled. Here is a typical markup and application code:
1 | <body> |
You are trying to write the test code to click the Submit button. If you assume the checkbox is checked, the code is this:
1 | it('submits the terms forms', () => { |
Ughh, if the checkbox is clear, the test fails, because the cy.click command refuses to click the disabled button by default.
Ok, fine. Let's check the "agree" checkbox using the cy.click command.
1 | it('submits the terms forms', () => { |
If we inspect the "CLICK" command DOM snapshot, we see the "Agreed" checkbox was already checked, and our click flipped it to unchecked state.
Conditional logic using cy.then
We need a way to click the input box IF it is unchecked. One solution is to grab the input element and check ourselves using the cy.then command.
1 | it('submits the terms forms', () => { |
Ughh, the code is less clear. It requires knowing the jQuery selectors and commands, and using the cy.wrap command to get th element back into a Cypress chain and use .click()
command.
Tip: for more examples of writing conditional commands, see my Cypress examples site.
Conditional logic using cypress-if
Instead of writing .then
callbacks, you could use my cypress-if plugin. This plugin lets you write if / else
commands right inside a chain of commands without using cy.then
and cy.wrap
. If you need an introduction to the plugin, watch this video below
Let's install the plugin as a dev dependency and simplify our test
1 | npm i -D cypress-if |
1 | import 'cypress-if' |
The child commands .if()
and .else()
come from the cypress-if
plugin. You can use any Cypress assertion as the .if(assertion)
condition; by default it is element existence. If the input button is unchecked, the test takes the "IF" path and skips the "ELSE" portion of the command chain:
In other test runs, the input element was checked already, and the test took the "ELSE" portion, skipping the .click()
command:
You can have multiple commands in the "IF" and "ELSE" portions, you can use cy.then
, cy.within
commands, etc. See the plugin's README for more examples of writing conditional command chains.
🎓 I have recorded several lessons showing the
cypress-if
plugin in action via hands-on exercises, check out my course Cypress Plugins. There is even a free lesson aboutcypres-if
specifically!
Warning: not every situation requires conditional commands
In our situation the best solution is to use the cy.check command. This command does nothing if the checkbox is already checked!
1 | it('submits the terms forms', () => { |
For a similar lesson on using the built-in Cypress commands instead of conditional testing, see the free lesson "Lesson d4: How to avoid conditional test logic" in my course Cypress Plugins. Deterministic tests are the best, use the conditional test commands only if you really cannot control the application in any other way.
Bonus 1: conditional type into the input field
Sometimes, the test starts typing into the input element before the element is ready to process the input events. For example, this input element clears itself at the start and sometimes loses the first letters.
Using cypress-if
we can clear the input element and type the word again.
1 | cy.get('#name') |
What if the input element again loses part of the entered text? You could probably look at the application design, or use the cypress-recurse plugin that repeats Cypress commands until a certain condition is met.