Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress XHR stubbing ignores ajax requests performed with fetch

Important Information

The original question here was not directly about the lack of support for the fetch api in Cypress, but that was the cause for the problem I initially posted here. I've edited the title of the question and added this preamble here. Below this paragraph is the original content of the question:

Original question

The Cypress documentation is filled with examples where you can set an alias to a particular web request, and then you can instruct cypress to wait on it. Like for instance, this one:

cy.route('POST', '/login').as('postLogin')

cy.get('input[name=username]').type('jane.lae')
cy.get('input[name=password]').type('password123{enter}')

// we should always explicitly wait for
// the response for this POST to come back
// so our tests are not potentially flaky or brittle
cy.wait('@postLogin')

The thing is I'm trying to use this exact technique in my app's tests, but I need to wait on a request that is not made against the same server where the app is hosted. Therefore I am assuming that I can type in the full URL of the backend endpoint, so that cy.route does not prepend the baseUrl, which is the host of where the frontend app is hosted.

// The following URL points to a backend rails app
// The frontend app I'm testing with cypress is at http://localhost:8080
cy.route('POST', 'http:/localhost:3000/session').as('postLogin')
// ... fill login form
cy.wait('@postLogin')
// The test never reaches this point

However, when I run my test, I get a timeout because cypress never realizes the request was performed, it continues to wait on it until it timeouts. Turns out when I inspect the test script on the left sidebar in the browser where cypress is running, the route has the explicit host I set, not only the path, but still the test stayed waiting for this request to occur, and it says it never occurs. When I inspect the network tab of the browser dev tools I can see the request occurred. And I can see in the terminal where my backend app is running, that it was indeed hit with a login request. Furthermore, I can see in my frontend app running in cypress' browser session, that the user signed in successfully and the app was redirected to the intended page after request.

The question is: can I make cypress aware of cross-origin requests so that it can wait for them? If so, how?

Update:

Stubbed routes are also not caught by cypress, and I cannot wait on them, or prevent them from occurring, as it is expected for stubbed requests.

like image 843
Ernesto Avatar asked Nov 28 '17 15:11

Ernesto


1 Answers

Turns out this has anything to do with cross origin requests. I started to realize this by making by app assume the backend was in its same domain, and writing the test without specifying the host in the mocked route. I got the same behavior. Then I realized that Cypress should show any XHR request in the script of the running test on the left sidebar in the browser. It did not show this request either as "XHR" or "XHR STUB", even though the request was occurring. So I realized that I am not using the browser's XHR interface to make ajax requests, but fetch instead. And after some searching I found that this is an issue with Cypress, that assumes all ajax requests are done via XHR. I found an issue in Cypress' github repo about this, which is still unresolved as of today :(

Here's a comment in the issue mentioned above with the workaround I ended up using for the time being:

// Add this to cypress/support/commands.js
Cypress.on("window:before:load", win => {
  win.fetch = null;
});
like image 187
Ernesto Avatar answered Nov 17 '22 11:11

Ernesto