Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XHRs Not Logged/Handled (due to Service Workers) #1716

Closed
OmriAharon opened this issue May 14, 2018 · 25 comments
Closed

XHRs Not Logged/Handled (due to Service Workers) #1716

OmriAharon opened this issue May 14, 2018 · 25 comments
Labels
existing workaround type: duplicate This issue or pull request already exists

Comments

@OmriAharon
Copy link

OmriAharon commented May 14, 2018

Current behavior:

When running build in webpack 4's production mode (but probably not the root cause of this bug), Cypress is not logging XHR requests and not noticing them, hence cy.route()/cy.wait() mechanism fails. (These are not fetch requests)
This is probably not the culprit, but haven't thought of anything else that's different yet.

As per the documentation:

Now we know exactly why our test failed. It had nothing to do with the DOM. Instead we can see that either our request never went out or a request went out to the wrong URL.

But in my case I can see the requests have been made and when running locally (development mode) everything works perfectly, no change to the URL.

** Update - seems that when I comment out a test that signs in on a different site (no option to programmatically login) the rest of the tests run fine and the XHRs are logged. Somehow, having the first test sign up and then redirect to my own app breaks XHR logging. (Still weird that local setup doesn't suffer from this)

Desired behavior:

XHR requests are noticed and can be waited upon.

Steps to reproduce:

Not sure how you can reproduce it yourself.
Local setup with webpack - everything works fine.
Building in production mode (webpack 4) and serving with http-server (in order to mock how it runs in the CI which is where I initially spotted the problem) - Cypress is blind to XHRs - they don't appear in the log as well as you can see in the screenshots below. I can see the XHRs request in the network pane and my site loads up as normal. There is no difference in the URL and you can see no XHRs are even logged.
Initially I thought it might be happening because I serve under port 80, but then I changed to a random port and it still didn't work so I ruled it out.

Local scenario (everything's fine):

image

Served scenario (XHRs not logged):

image
image

Anything else I can provide that will help?

Versions

MacOS High Sierra 10.13.3
Chrome 66.0.3359.170 (Official Build) (64-bit)
Cypress 2.1.0

@OmriAharon
Copy link
Author

OmriAharon commented May 15, 2018

Is it possible that's because I have a cy.visit(siteA) and on the subsequent test I have cy.visit(mySite)? Would explain why commenting out the login test makes it work. (trying to see if it relates to #1139)

And if so, why does it work on a local run?

@OmriAharon
Copy link
Author

OmriAharon commented May 18, 2018

To anyone who encounters this situation or similar (external login: initially visiting a different domain then redirecting to own website):
I've managed to workaround by doing a cy.reload() afterwards:

cy.server({ matchBase: false });
cy.route('/someRequest').as('someRequest');
cy.visit('/');
cy.reload(); // <-- This fixes it

Though it would have been nice to get some kind of response from the library devs and not rely on workarounds.

@jennifer-shehane
Copy link
Member

Yeah - it's difficult to address issues without a reproducible example. I wasn't able to detect anything unusual from the information provided, but we'd need an example to run ourselves to give any more insight as to why this didn't work + why the workaround works.

@OmriAharon
Copy link
Author

Thanks @jennifer-shehane for the response.
I understand this is difficult, and unfortunately, this is also a complex scenario to provide reproducible steps for.
I assume as this is not an uncommon scenario, and as Cypress' popularity rises, you will probably face similar issues like this again in the near future. I'm sure there are at least logs that I can provide, and if more information is needed I'd be more than happy to help offline this issue in order to help you guys figure this out.

@maxime1992
Copy link

maxime1992 commented May 21, 2018

Hi,

I'm facing the exact same issue.

  • A call to AWS cognito happens
  • I'm waiting for it
  • The call is logged
  • The wait does not see that the call has been done
  • The global counter does not increment for that count

The relevant piece of code:

  cy.server();
  cy.route('POST', `https://sts.amazonaws.com`).as('getToken');
  cy.route('POST', `https://cognito-idp.eu-west-1.amazonaws.com`).as('cognitoRootPost');

  cy
    .get(`cnc-credential-challenge button`)
    .contains('Login')
    .click();

  cy.wait('@cognitoRootPost');

As I cannot provide a repro, I've tried to provide a detailed and absolutely beautiful screenshot 👍

e2e-cypress-bug

Notice that the call right after the wait is the one I'm expecting.

Clicking on it display what's on the right side. It's the good URL, there's no error.

The wait fail unexpectedly, the global counter is not incremented.

Context
I'm currently upgrading to Angular 6.
And as @OmriAharon pointed out, it might be related to Webpack 4 maybe? As they've switched from v3 to 4 between Angular (& Angular-Cli) v5 to 6.

@OmriAharon
Copy link
Author

OmriAharon commented May 22, 2018

@maxime1992 Looks like your URLs are mismatched, maybe that's the problem?
You're trying to capture cognito-idp but the XHR that got out is cognito-identity.

@maxime1992
Copy link

@OmriAharon you're right.

BUT, taking a closer look to my network panel, I can see the calls being done to cognito-idp as expected:

image

A coworker just noticed that too:
image

For some reason it seems that the fetch are not caught by Cypress. Probably related to #95

@mgalindo
Copy link

Since I updated to Cypress 3.0.1, I am seeing something similar but only when I run my tests in Electron 59, the tests run fine in Chrome 66.

@phellipeandrade
Copy link

Maybe related: #1201

@bsmithEG
Copy link

bsmithEG commented Jun 13, 2018

I had made a comment in #1201, however, looking at when that ticket was started and my problems now, I felt it's more relevant to comment on this issue instead, because at least for us it looks like this might be a regression with >= 3.0.0.

My use case: I just recently moved to using CircleCI (2.0) with this docker image:
https://github.com/cypress-io/cypress-docker-images/tree/master/browsers/chrome65-ff57, but did this around the same time we bumped our cypress version to 3.0. Getting the behavior listed above, where none of our tests waitForXHRs seem to be picking up on cy.wait (but verified traffic on the server side).

Running with cypress run --browser chrome (due to some electron issues from a different ticket)

Moving back to 2.1.0 and the tests work as intended with the same docker image above and same circleci config (minus the change in cypress versions, and more importantly, compiling a whole bunch of TS tests seem to take tons of time and lots of memory which really slows the build down -- this got better with 3.0.0) .

Unfortunately I'll need to go through a little effort to get a reproducible example I can share, because we are doing a few strange things like using blacklisting to intercept certain requests and rewrite them (a work around for hijacking js fetch/imports), but I'll try to isolate that's not a part of the issue and attach a reproducible cypress-tiny-test by the end of the week.

Thanks,

@bsmithEG
Copy link

It seems like it's also the Electron problem for me after all.

I figured out that if you pass invalid command line opts to cypress, it will just run default (which runs defaulted to Electron 59 headless). I was trying to glob options with the --spec flag like so:

cypress run --browser chrome --spec **/*.spec.ts

This causes cypress to actually just run as if it were:

cypress run

Dropping the spec flag runs chrome, which now works correctly for me in terms of the XHR waiting, and I'm back to the original issue involving Electron.

Sorry for the confusion.

@egucciar
Copy link
Contributor

@bsmithEG i had a similar issue with my tests but i discovered that i had an uncaught exception only in electron which prevented my xhr.

@brian-mann
Copy link
Member

@bsmithEG #1953 (comment)

@jennifer-shehane jennifer-shehane added the stage: needs information Not enough info to reproduce the issue label Oct 15, 2018
@trydionel trydionel added this to the Sprint 8 milestone Oct 22, 2018
@ShaneMckenna23
Copy link

Hey @trydionel @lilaconlee,
I have just encountered this issue on Circle CI/Electron browser. Has the source of this issue been found? I can see that it has recently been added to sprint 8. If you need help replicating, I can make an example of the issues I'm seeing. Cheers!

@lilaconlee
Copy link
Contributor

@ShaneMckenna23 We haven't found the source yet and an example reproducing your issues would be helpful!

@ShaneMckenna23
Copy link

ShaneMckenna23 commented Nov 8, 2018

Below are some snippets of the behaviour I'm seeing. I can make a working example over a longer timeframe if you are still having trouble solving this.

Setup:
React Application built using create-react-app
Cypress: 3.1.0
Circle Ci image: cypress/base:8

Circle CI

-  run:
	name:  Build the browser app
	command:  cd browser-app && npm run build
-  run:
	name:  Serve the browser app
	command:  cd browser-app && serve -l 3000 -s build
	background:  true
- run:
	name:  Running Cypress tests
	command:  cd browser-app && npm run cy:run

Cypress Test

describe('Find Player',  ()  =>  {
	beforeEach(()  =>  {
		cy.server();
		cy.route('POST',  routes.api.queryForLoginPlayer).as('queryForLoginPlayer');
		cy.visit('http://localhost:3000/');
	});
	
	it('Finds Player sucessfully',  ()  =>  {
		cy.get('[data-cy=email-input]')
		.type(testEmail)
		.should('have.value',  testEmail);
		
		cy.get('[data-cy=email-input-button]').click();
  
		// Only resolves locally
		cy.wait('@queryForLoginPlayer');
});

Cypress local

local

Cypress Circle Ci

circle ci

@vijayadurga259
Copy link

vijayadurga259 commented Nov 27, 2018

Hello

Any one found a workaround for this issue?
Am blocked as waiting for xhr's to finish is very much required in my tests.

@ShaneMckenna23
Copy link

@vijayadurga259
We have resorted to using cy.wait(1000) after API calls until this is resolved.

@Olgagr
Copy link

Olgagr commented Nov 27, 2018

@vijayadurga259 My problem was that these cancelled XHR requests fail tests. To avoid it I ignore such cancelled XHR requests.

In the support/index.js file:

Cypress.on('uncaught:exception', hackToNotFailOnCancelledXHR);
Cypress.on('fail', hackToNotFailOnCancelledXHR);

function hackToNotFailOnCancelledXHR(err) {
  const realError =
    err.message.indexOf("Cannot set property 'aborted' of undefined") === -1;
  if (realError) {
    throw err;
  } else {
    console.log(err);
  }
}

The solution was described in the other issue.

@cintrzyk
Copy link

Are you using service workers in production? If so, then try to unregister them before each spec:

Cypress.Commands.add('unregisterServiceWorkers', () => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.getRegistrations()
      .then(registrations => registrations.forEach(reg => reg.unregister()));
  }
});
beforeEach(() => {
    cy.unregisterServiceWorkers();
});

works for me 💃

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Apr 25, 2019

Unfortunately we will have to close this issue as there is not enough information to reproduce the problem. Can anyone provide example?

@drachum
Copy link

drachum commented May 2, 2019

Are you using service workers in production? If so, then try to unregister them before each spec:

Cypress.Commands.add('unregisterServiceWorkers', () => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.getRegistrations()
      .then(registrations => registrations.forEach(reg => reg.unregister()));
  }
});
beforeEach(() => {
    cy.unregisterServiceWorkers();
});

works for me

@cintrzyk just to tell that of more than 20 Cypress issues with the same theme (not logging XHR requests), your solution is the one who works for me.

@jennifer-shehane it definitely seems like service workers are of the main causes for Cypress not logging XHR requests. That explains why on related issues people tell things work on development and not on production, or not on CI, because normally SWs are disabled on localhost ;)

Hope to help and thank you again @cintrzyk

@jennifer-shehane jennifer-shehane removed this from the Sprint 16 milestone May 30, 2019
@jennifer-shehane jennifer-shehane changed the title XHRs Not Logged/Handled XHRs Not Logged/Handled (due to Service Workers?) May 30, 2019
@cypress-bot cypress-bot bot added stage: needs investigating Someone from Cypress needs to look at this and removed stage: needs information Not enough info to reproduce the issue labels Jun 3, 2019
@jennifer-shehane
Copy link
Member

@cintrzyk Thanks for providing this workaround - it does seem to be the reason some people's XHRs are not logging.

It's been tough narrowing down which cases are actual issues in Cypress because an XHR not being logged covers a very broad category. We'll look into the ServiceWorker cases.

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Jun 4, 2019

We want to include this work as part of the Lifecycle Events feature documented here: #686

We don't want to add more magical things in the background without it being explicitly stated that we are handling ServiceWorkers (as defined in the LifeCycle Events issue), so please go thumbsup / show your support in that issue if you want this addressed.

Workaround

For now, we suggest using the workaround given by @cintrzyk in this comment: #1716 (comment)

I will be closing this issue in favor of #702 which is the feature to clear service workers before each run.

@cypress-bot cypress-bot bot added stage: ready for work The issue is reproducible and in scope and removed stage: needs investigating Someone from Cypress needs to look at this labels Jun 4, 2019
@jennifer-shehane jennifer-shehane added stage: needs investigating Someone from Cypress needs to look at this type: unexpected behavior User expected result, but got another existing workaround and removed stage: ready for work The issue is reproducible and in scope labels Jun 4, 2019
@jennifer-shehane jennifer-shehane changed the title XHRs Not Logged/Handled (due to Service Workers?) XHRs Not Logged/Handled (due to Service Workers) Jun 4, 2019
@jennifer-shehane jennifer-shehane added type: duplicate This issue or pull request already exists and removed priority: high❗️ stage: needs investigating Someone from Cypress needs to look at this type: unexpected behavior User expected result, but got another labels Jun 4, 2019
@ddesna
Copy link

ddesna commented Oct 23, 2019

Could someone explain me why this test does not log XHR POST requests to https://www.academia.edu/v0/server_notifications?subdomain_param=api?

it('should log xhr', () => {
 cy.visit('https://www.academia.edu/12297791/Open_Access_Meets_Discoverability_Citations_to_Articles_Posted_to_Academia.edu')
})

I have tried some workarounds commented in this thread but had not luck.

@cypress-io cypress-io locked and limited conversation to collaborators Dec 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
existing workaround type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests