Skip to content Skip to sidebar Skip to footer

Skipping A Test In Cypress Conditionally

I'm trying to find out if I'm able to conditionally skip a test it() in my test suite and deal with its async nature as well. I've read about conditional testing in Cypress docs ht

Solution 1:

Thank you for the detailed description! I provide you a solution for your very first question

I'm trying to find out if I'm able to conditionally skip a test it() in my test suite and deal with its async nature as well.

Use an environment variable, I report you a solution of mine (actually using in my pipeline).

if (!Cypress.env("SKIP_E2E_TESTS")) {
  it(...);
}

and in my package.json file I have a script that looks like this

"test":"CYPRESS_SKIP_E2E_TESTS=true npm-run-all --parallel --silent test:unit test:cypress",

My goal was the same as yours, I'd like to disable some tests in some circumstances (the CI pipeline in my case).

So put the whole test into a condition instead of having a conditional test.

Let me know if you need some more help 😉

Solution 2:

Cypress now also provides a library @cypress/skip-test which can give more controls by

  • cy.skipOn
  • cy.onlyOn
  • isOn
  • boolean flag
  • headed / headless environments
  • ENVIRONMENT

DISCLOSE: I am not associated with Cypress.

Solution 3:

I am using an adapted version of @NoriSte's answer that still registers the tests, but as skipped:

const maybeDescribe = Cypress.env('SOME_ENV_VAR') ? describe : describe.skipmaybeDescribe('Test suite', function() { /* ... */ })

and then similarly, on CI, where I want to skip the tests:

export CYPRESS_SOME_ENV_VAR=
$(npm bin)/cypress run

My source-controlled cypress.json has SOME_ENV_VAR defined so when I run locally, the tests are not skipped.

Solution 4:

I think you are almost there, but instead of the synchronous if () {...} else {...} pattern you need the asynchronous callback pattern.

it('shows the list', function() {

  const whenFailed = function() {
    this.skip()
  }

  const whenSucceeded = function() {
    cy.get('.list').should('be.visible')
  }

  queryFailed(whenFailed, whenSucceeded);
}

functionqueryFailed(whenFailed, whenSucceeded) {
  cy.get('.spin')
    .then($container => {
      const htmlLoaded = $container[0].innerHTML;

      if (htmlLoaded.indexOf('List') !== -1) {
        whenSucceeded();
        return;
      }

      if (htmlLoaded.indexOf('error') !== -1) {
        whenFailed();
        return;
      }

      cy.wait(1000);
      queryFailed(whenFailed, whenSucceeded);
    });
}

However, I note the recursive call to queryFailed(), which looks like you are manually retrying the content of the spin container.

Cypress has built in retries, so all you have to do is decide on a maximum time your result will possibly take (say 20 seconds), and it will conclude the command as soon as the desired content arrives, or fail the test altogether if it doesn't happen in 20 seconds.

Also, you should be in control of the success/failure of whatever the spinner is waiting on (e.g fetching the list via XHR). So you should split the test into two - one for success and one for failure.

context('when the list loading succeeds'function() {

  it('shows the list', function() {
    // Mock XHR success here
    cy.contains('.spin', 'List', { timeout: 20000 });
    cy.get('.list').should('be.visible');
  })

  it('does not show an error message', function() {
    ...
  })

})

context('when the list loading fails'function() {

  it('does not show the list', function() {
    // Mock XHR failure here
    cy.contains('.spin', 'error', { timeout: 20000 });
    cy.get('.list').should('not.be.visible');
  })

  it('shows an error message', function() {
    ...
  })

})

This is a bit rough as I don't know the exact HTML expected, or what the spinner is waiting on, but you can see this pattern is much tidier and tests all paths in a controlled manner.

Solution 5:

The Cypress Real World App, a payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows contains a few workflows for conditionally running tests in CI and altered workflows for mobile viewports, for instance.

In addition, as of Cypress v4.8.0 certain Test Configurations may be applied to a suite or individual test.

For instance:

it('Show warning outside Chrome', {  browser: '!chrome' }, () => {
  cy.get('.browser-warning')
   .should('contain', 'For optimal viewing, use Chrome browser')
})

Post a Comment for "Skipping A Test In Cypress Conditionally"