Constantin
Constantin

Reputation: 388

Fail cypress test when 500 xhr request occurs

I am writing end-to-end tests for a web application in cypress and I would like cypress to fail the test if the applications sends any request with a http 500 error response.

I am using cypress in version 3.1.5. I already tried the following, but I get an promise error.

    cy.server();
    cy.route({
      url: '**',
      onResponse: (xhr) => {
        cy.log(xhr);
      }
    });

I hope to find a more elegant solution to this problem, because this sounds to me like a pretty standard use-case.

Upvotes: 5

Views: 6772

Answers (4)

Emidomenge
Emidomenge

Reputation: 1524

If you're using a Cypress version that supports intercept (v7.x.x or later), then you can do this in your test file:

    beforeEach(() => {
      cy.intercept('**', request => {
        request.on('response', function (response) {
          expect(response.statusCode).is.lessThan(500); // Test will fail if an 500 error happen
        });
      });
    });

Upvotes: 2

Rahul L
Rahul L

Reputation: 4349

Try using below code refer doc

  cy.intercept('**').as('all')

  cy.wait('@all').its('response.statusCode').should('not.be.oneOf', [500])

OR

Checking status code using - should('be.oneOf', [200,300])

  cy.wait('@all').its('response.statusCode').should('be.oneOf', [200,300])

Upvotes: 3

You can throw an error inside the on request, that should work.

cy.server();
cy.route({
  url: '**',
  onResponse: (xhr) => {
    if(xhr.status === 500) {
        throw new Error('Failing test caused by a unhandled request with status 500')
    }
    cy.log(xhr);
  }
})

Upvotes: 1

dwelle
dwelle

Reputation: 7284

Not sure if there's some canonical way, but you can monkey-patch the XMLHttpRequest API and throw on >= 500 status responses.

If your app is using Fetch API, SendBeacon, or something else, you can do something similar.

// put this in support/index.js
Cypress.on('window:before:load', win => {
    const origSend = win.XMLHttpRequest.prototype.send;
    win.XMLHttpRequest.prototype.send = function () {
        // deferring because your app may be using an abstraction (jquery),
        // which may set this handler *after* it sets the `send` handler
        setTimeout(() => {
            const origHandler = this.onreadystatechange;
            this.onreadystatechange = function () {
                if ( this.readyState === 4 && this.status >= 500 ) {
                    throw new Error(`Server responded to "${this.url}" with ${this.status}`);
                }
                if ( origHandler ) {
                    return origHandler.apply(this, arguments);
                }
            };
            return origSend.apply(this, arguments);
        });
    };
});

WTBS, this is not gonna be very useful because you app may want to handle that 500 instead, while this will prevent it.

Better solution is to make sure you app simply throws unhandled 500 responses.

Upvotes: 1

Related Questions