Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress visit and wait timeouts ignored

I created a test where I setup a route, try to visit a page which makes an API request to the route and then wait for the route response:

cy
    .server()
    .route('GET', '/api/testing')
    .as('testing');
cy.visit('/index.html', { timeout: 60000 });
cy.wait('@testing', { timeout: 60000 });

This only waits for the Cypress global default responseTimeout of 30 seconds and then fails the API request.

Here's the error message logged by Cypress in the console:

Cypress errored attempting to make an http request to this url: https://localhost:4200/api/testing

The error was:

ESOCKETTIMEDOUT

The stack trace was:

Error: ESOCKETTIMEDOUT
at ClientRequest. (…\node_modules\cypress\dist\Cypress\resources\app\packages\server\node_modules\request\request.js:778:19)
at Object.onceWrapper (events.js:314:30)
at emitNone (events.js:105:13)
at ClientRequest.emit (events.js:207:7)
at TLSSocket.emitTimeout (_http_client.js:722:34)
at Object.onceWrapper (events.js:314:30)
at emitNone (events.js:105:13)
at TLSSocket.emit (events.js:207:7)
at TLSSocket.Socket._onTimeout (net.js:402:8) at ontimeout (timers.js:469:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:264:5)

Adding a responseTimeout to the global config of Cypress will increase the timeout, but why isn't the timeout for either the visit or the wait occurring?

like image 332
chris Avatar asked Mar 30 '18 19:03

chris


People also ask

How do I fix timeout error in Cypress?

Developers may opt to manually address flaky tests caused by timeout errors by pursuing one or a combination of the following: Use the Cypress intercept and aliasing commands to require Cypress to wait on your asynchronous operations to complete before running the next command or assertion.

Does Cy Visit wait for page to load?

cy. visit() can time out waiting for the page to fire its load event. cy. visit() can time out waiting for assertions you've added to pass.

What is the best way to wait and test the page in Cypress?

You can wait for basically anything by passing a callback function into . should() command. It will use the built in retry logic and wait for the function to pass. For example, you can wait until all of the elements on page have the proper text.

How do I stop waiting in Cypress?

There are three options that we prefer mostly to avoid implicit waits as adding delays in your application is considered a bad practice 99% of the time we should not do it. You need to make sure that your element is going to definitely appear. Option-2: Custom Wait -> We can wait for certain elements to disappear.


1 Answers

See the code example on this page commands - wait - Alias

// Wait for the route aliased as 'getAccount' to respond
// without changing or stubbing its response
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((xhr) => {
  // we can now access the low level xhr
  // that contains the request body,
  // response body, status, etc
})

I would add the then((xhr) => to your code and see what response is coming through.

Logic says that if a bogus route waits the full timeout, but a 'failed legitimate route' does not, then a response with failure code is being sent back from the server within the timeout period.


The block of code in request.js where the error comes from has an interesting comment.

self.req.on('socket', function(socket) {
  var setReqTimeout = function() {
    // This timeout sets the amount of time to wait *between* bytes sent
    // from the server once connected.
    //
    // In particular, it's useful for erroring if the server fails to send
    // data halfway through streaming a response.
    self.req.setTimeout(timeout, function () {
      if (self.req) {
        self.abort()
        var e = new Error('ESOCKETTIMEDOUT')  <-- LINE 778 REFERENCED IN MESSAGE
        e.code = 'ESOCKETTIMEDOUT'
        e.connect = false
        self.emit('error', e)
      }
    })
  }

This may be a condition you want to test for (i.e connection broken mid-response).
Unfortunately, there seems to be no syntax cy.wait().catch(), see Commands-Are-Not-Promises

You cannot add a .catch error handler to a failed command.

You may want to try stubbing the route instead of setting the breakpoint on the server, but I'm not sure what form the fake response should take. (Ref route with stubbing)

like image 97
Richard Matsen Avatar answered Oct 01 '22 03:10

Richard Matsen