cypress: cy.wait timeouts on aborted xhr requests

Current behavior

Whenever there is something like this in app (pseudo code):

var xhr = new XHR()
xhr.send()
xhr.abort() // <- POI
xhr = new XHR()
xhr.send()

and this in test:

cy.intercept('...').as('xhr')
cy.visit('/')
cy.wait('@xhr')

cypress timeouts with an error Timed out retrying: cy.wait() timed out waiting 30000ms for the 1st response to the route: xhr. No response ever occurred.

image

As you can see on screenshot:

  • in network tab there is aborted and follow up requests
  • app renders response
  • on a sidebar we can see that interception recognized the query (yellow marks)
  • but somehow second requests still have spinning icon on left side

Desired behavior

Page with app loads and works as expected, cypress should handle such cases as well

Test code to reproduce

index.html - aka our app

<!DOCTYPE html>
<html>
  <head>
    <title>demo</title>
  </head>
  <body>
    <button onclick="good()">good</button>
    <button onclick="bad()">bad</button>
    <script>
      function good() {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
        xhr.responseType = "json";
        xhr.send();
        xhr.onload = () => {
          document.body.innerHTML += "<pre>" + JSON.stringify(xhr.response) + "</pre>";
        };
      }
      function bad() {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
        xhr.responseType = "json";
        xhr.send();
        xhr.abort();
        xhr = new XMLHttpRequest();
        xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
        xhr.responseType = "json";
        xhr.send();
        xhr.onload = () => {
          document.body.innerHTML += "<pre>" + JSON.stringify(xhr.response) + "</pre>";
        };
      }
    </script>
  </body>
</html>

demo.spec.js

describe("demo", () => {
  it("should handle aborted requests", () => {
    cy.intercept("https://jsonplaceholder.typicode.com/todos/1").as("xhr");
    cy.visit("http://localhost:3000");
    cy.get("button").contains("bad").click();
    cy.wait("@xhr");
  });
});

Versions

cypress - 6.0.1 node - 12.8.3 chrome - 87.0.4280.88 os - macos 11.0.1 (20B29) ci provider - undefined

PS: not sure but it might be related to this PR which was made by @brian-mann

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 17 (9 by maintainers)

Most upvoted comments

Running tests with Cypress 6.1.0 and having the same problem with cy.intercept. When my axios request is aborted (appears (canceled) on Chrome network tab), cy.intercept keeps waiting for it, instead of getting the new request that is active:

Screen Shot 2020-12-10 at 10 46 04

image

With cy.server and cy.route works fine

@mac2000 Nice. Thanks for this.

Sometimes the first time I run this it passes, but on rerun it definitely fails.

index.html

<html>
<body>
  <button onclick="bad()">bad</button>
  <script>
    function bad() {
      let xhr = new XMLHttpRequest();
      xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
      xhr.responseType = "json";
      xhr.send();
      xhr.abort();
      
      xhr = new XMLHttpRequest();
      xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1");
      xhr.responseType = "json";
      xhr.send();
      xhr.onload = () => {
        document.body.innerHTML += "<pre>" + JSON.stringify(xhr.response) + "</pre>";
      };
    }
  </script>
</body>
</html>
it('should handle non-aborted requests', () => {
  cy.intercept('https://jsonplaceholder.typicode.com/todos/1').as('xhr')
  cy.visit('index.html')
  cy.get('button').contains('good').click()
  cy.get('pre').contains('delectus') // response body renders to page
  // ✅ passes
  cy.wait('@xhr')
})

it('cy.route should handle aborted requests', () => {
  cy.server()
  cy.route('https://jsonplaceholder.typicode.com/todos/1').as('xhr')
  cy.visit('index.html')
  cy.get('button').contains('good').click()
  cy.get('pre').contains('delectus') // response body renders to page
  // ✅ passes
  cy.wait('@xhr')
})

it('cy.intercept should handle aborted requests', () => {
  cy.intercept('https://jsonplaceholder.typicode.com/todos/1').as('xhr')
  cy.visit('index.html')
  cy.get('button').contains('bad').click()
  cy.get('pre').contains('delectus')  // response body renders to page
  // ❗️ times out sometimes
  cy.wait('@xhr')
})
Screen Shot 2021-01-20 at 4 18 36 PM

Well it was meant to fix the issue, but I can still see the issue with it

Sent from my iPhone

On Feb 17, 2021, at 13:08, Jason Fairchild notifications@github.com wrote:

Does the PR from saintkhk fix the issue for Cypress, or is it just a PR to fix some tests that also demonstrate this behavior?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

hm, here you go:

git clone https://github.com/mac2000/cypress-9549
cd cypress-9549
npm i
npm start
npm test

https://user-images.githubusercontent.com/88868/105141947-9141c180-5b02-11eb-9e42-df04c343a931.mp4