Peter Boomsma
Peter Boomsma

Reputation: 9846

Stop a test if assertion failed

I have a simple Cypress test:

    describe('My First Test', () => {
      it('Go to login page', () => {
        cy.visit('http://localhost:3000')
        cy.contains('Log in').click()
      })

      it('Login with local account', () => {
        cy.get('input[type=email]').type('[email protected]')
        cy.get('input[type=password]').type('asd123')
        cy.contains('Log in').type('{enter}')
      })
    })

The first assertion checks if there's a element with the text Log in, then clicks it. Second assertion tries to log in.

I've changed the text in the Log in button to Assertion Failed. So now the first assertion fails, but it still runs the second assertion even though I'm not redirected to the login page.

Is there a way to cancel a running spec when a assertion fails?

Upvotes: 0

Views: 5599

Answers (2)

user15544695
user15544695

Reputation:

You can also use

afterEach(() => {
  if (cy.state('test').state === 'failed') {
    Cypress.runner.stop()
  }
})

but there is a problem with this, none of your after() hooks will run, including plugins like code-coverage.

A better solution is to dynamically skip following tests, similar to this answer How to add test case grouping in Cypress

beforeEach(function() {
  const suite = cy.state('test').parent
  if (suite.tests.some(test => test.state === 'failed')) {
    this.skip()
  }
})

This is my simplified test

describe('all tests', () => {

  describe('fail fast', () => {

    beforeEach(function() {               // move up to apply to all tests
      const suite = cy.state('test').parent;
      if (suite.tests.some(test => test.state === 'failed')) {
        console.log(`skipping test "${cy.state('test').title}"`)
        this.skip()
      }
    })

    after(() => {
      console.log('after')               // runs
    })

    it('fails', () => {
      expect(true).to.eq(false)          // fails
    })

    it('next', () => {
      expect(true).to.eq(true)           // skipped
    })
  })

  describe('no fail fast', () => {
    it('no skip', () => {
      expect(true).to.eq(true)           // runs
    })
  })
})

Upvotes: 5

Alapan Das
Alapan Das

Reputation: 18601

You can add an afterEach() and write this:

afterEach(function() {
  if (this.currentTest.state === 'failed') {
    Cypress.runner.stop()
  }
});

Or

You can use the plugin cypress-fail-fast and configure it at the Test level:

describe("All tests", {
  failFast: {
    enabled: false, // Children tests and describes will inherit this configuration
  },
}, () => {
  it("sanity test", {
    failFast: {
      enabled: true, // Overwrite configuration defined in parents
    },
  }, () => {
    // Will skip the rest of tests if this one fails
    expect(true).to.be.true;
  });

  it("second test",() => {
    // Will continue executing tests if this one fails
    expect(true).to.be.true;
  });
});

or, globally for all specsby writing in cypress.json:

{
  "env":
  {
    "FAIL_FAST_ENABLED": true
  }
}

Upvotes: 2

Related Questions