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

localhost URL not accessible after cy.request on server #25397

Open
nicolas-marien opened this issue Jan 9, 2023 · 31 comments
Open

localhost URL not accessible after cy.request on server #25397

nicolas-marien opened this issue Jan 9, 2023 · 31 comments
Labels
E2E Issue related to end-to-end testing pkg/server This is due to an issue in the packages/server directory Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.

Comments

@nicolas-marien
Copy link

nicolas-marien commented Jan 9, 2023

Current behavior

Hello 👋

We are trying to integrate Cypress but we run into an issue. Cypress tells us that our frontend is not reachable.
The client runs on port 4200 and the server on port 3333.
We are working in an monorepo managed by NX. The client is a basic React application, and the server is a NestJS application.

First we make a call to our server using cy.request and then we use cy.visit.
The cy.visit fails (see screenshot attached) telling is that the connection is refused.
When opening http://localhost:4200 on a browser behaves as intended.

When we change the server URL to point to 127.0.0.1 things work fine (but cookies are broken, and we want cookie 🍪).

Capture d’écran 2023-01-09 à 11 49 55

I put together a bare bone repository where things can be reproduced: https://github.com/nicolas-marien/nx-cypress-localhost-issue

Please find attached the output of DEBUG=cypress:* NODE_DEBUG=request y nx e2e client-e2e --watch

I do not have any corporate proxy.

Thank you for your help.

Desired behavior

The cy.visit(/) call should open my client.

Test code to reproduce

Start client and server using yarn nx run-many --target=serve
Run yarn nx e2e client-e2e --watch and select the only spec file.

Cypress Version

12.3.0

Node version

18.10.0

Operating System

MacOS 12.6.1 (also happens on Ventura)

Debug Logs

[out.txt](https://github.com/cypress-io/cypress/files/10373543/out.txt)

Other

No response

@astone123
Copy link
Contributor

@nicolas-marien thanks for the repo. I cloned it, installed dependencies and ran

yarn nx e2e client-e2e --watch

which launched Cypress, but I didn't see any client or server running on port 4200 or 3333 like you described. So, the test failed when calling cy.login because the server wasn't running.

Am I missing something?

@nicolas-marien
Copy link
Author

nicolas-marien commented Jan 12, 2023

@astone123 Oh sorry! I forgot to add the start command to run everything 🙄
Both client and server can be run using yarn nx run-many --target=serve.
I'll update the OP and the repo to add a start:all script.

@astone123
Copy link
Contributor

@nicolas-marien thanks for clarifying. I was able to run the application but I'm not seeing the same error message. The test passes for me

Image

@nicolas-marien
Copy link
Author

Thank you @astone123 for your answer.
Truth be told that is a bit of a bummer 😅 Since the issue happens on several of our machines (both corporate and personal).
Do you have any idea of what could be involved? Does cy.request happens to have some inner-working behavior that might result in our issue?
Also, the error states that 127.0.0.1:4200 is unreachable. That shows that localhost has already been resolved. Do you know why that print this and not localhost:4200.
Thank you for your help.

@astone123 astone123 assigned ZachJW34 and unassigned astone123 Jan 17, 2023
@ZachJW34
Copy link
Contributor

@nicolas-marien I was able to reproduce your issue by using Node18. With Node16, the e2e test works fine. There was a DNS change between Node16 and Node18 (issue) that you might be running into. I'll keep investigating to see where the problem lies and if there is a workaround for you.

@ZachJW34
Copy link
Contributor

ZachJW34 commented Jan 18, 2023

Can you try adding "host": "127.0.0.1" to your apps/client/project.json for the serve.options configuration and see if it works? I tried it locally and it worked for me. You can still use localhost for visiting your site locally and telling Cypress how to connect but Webpack needs to be forced to use ipv4 over ipv6 (my understanding of DNS is fuzzy admittedly).

To be explicit, this is the update I made:

"serve": {
  "executor": "@nrwl/webpack:dev-server",
  "defaultConfiguration": "development",
  "options": {
    "buildTarget": "client:build",
    "hmr": true,
    "host": "127.0.0.1" <----
  },

Still investigating if there is an issue on our side. Cypress will warn the user it can't connect to the provided baseUrl, but in this case there is no warning yet the connection fails when using cy.visit.

Edit: After investigating, it looks like the issue is due to Nx's use of localhost for the default value of host used in for their webpack-dev-server executor. This use prohibits use of ipv4. Workaround described above should be enough, you can also use 0.0.0.0 to open both ipv4 and ipv6.

@ZachJW34
Copy link
Contributor

I closed this prematurely, I'm now seeing some buggy behavior based on your reproduction where a request made to your backend before visiting is causing Cypress to lock onto the ipv4 range (hence the 127.0.0.1 connection refused). Shifting the request to be after the visit doesn't display this behavior. I'm working on a very simple reproduction.

@ZachJW34 ZachJW34 reopened this Jan 24, 2023
@ZachJW34
Copy link
Contributor

I've created a simple reproduction here. The README explains the bug in detail. My understanding of the bug is:

  • Setting host to localhost for the webpack-dev-server (the default value supplied by the nrwl/webpack-dev-server executor) inhibits the use of 127.0.0.1 (ipv4). You can still access the frontend site via localhost or [::1].
  • The backend server is listening on 127.0.0.1
  • When the cy.request is executed before the cy.visit, the subsequent visit is mapped to 127.0.0.1 rather than ::1. This causes the error as the frontend server will not accept requests from this IP as it is not listening to it.

If you move the request to after the visit, everything works fine. Also, if Cypress is allowed to visit before sending the request (by commenting out the request), adding the request back in works fine. There must be some server state being set from the initial request that influences subsequent visit requests.

@ZachJW34 ZachJW34 added routed-to-e2e pkg/server This is due to an issue in the packages/server directory labels Jan 24, 2023
@nicolas-marien
Copy link
Author

Thank you @ZachJW34 for your detailed answers.
To give some more context, we issue a request before visiting the page to create a test user (possibly not the best practice) and get a cookie for this user.

@ZachJW34
Copy link
Contributor

@nicolas-marien your workflow is totally valid. I've routed this to the e2e team and they will prioritize accordingly.

@ZachJW34 ZachJW34 removed their assignment Jan 31, 2023
@nicolas-marien
Copy link
Author

@ZachJW34 thanks for the feedback.

@gitnubster
Copy link

Are there any updates on this issue? Thanks.

@cerojasg1
Copy link

Same issue here I was using node 18.10 and cypress 12.9.0, I downgraded the node version to 16.13.2 and that fixed the issue.

@nagash77 nagash77 added E2E Issue related to end-to-end testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. and removed routed-to-e2e labels Apr 19, 2023
@UgurGumushan
Copy link

We are unable to upgrade to node 18 due to this issue

@lucaslenz
Copy link

For me instructing the bundle server (in my case vite) to explicitly use host '127.0.0.1' fixed the issue.

@dbeuchler
Copy link

For me instructing the bundle server (in my case vite) to explicitly use host '127.0.0.1' fixed the issue.

This was solving the issue also on my dev-env. Using v12.9.0

@UgurGumushan
Copy link

UgurGumushan commented Aug 15, 2023

I have set default nvm version from 16 to 20 with
nvm alias default 20
To make sure apps open outside the console have some latest nvm version (I intended to use Cypress GUI)
Upgraded cypress to v12.17.3
And this resolved the problem

jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Aug 23, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 18, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 18, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 18, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 19, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 19, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 19, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 19, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to jonathankingfc/quay that referenced this issue Oct 19, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
jonathankingfc added a commit to quay/quay that referenced this issue Oct 20, 2023
- This PR adds settings pages to the organization and user organization pages.
- Admin users can edit their preferences, billing, and organization type
- Updated cypress version to address bug cypress-io/cypress#25397
@MetRonnie
Copy link

MetRonnie commented Oct 23, 2023

I get this error after upgrading Node from 16 to 18 or 20. I'm not even using cy.request().

A workaround when using Vite is hinted at here: https://vitejs.dev/config/server-options.html#server-host

// vite.config.js
import { defineConfig } from 'vite'
import dns from 'dns'

dns.setDefaultResultOrder('ipv4first')

export default defineConfig({ ...

or set server.host to true but this will allow access to the server over the network


(Adding the code ECONNREFUSED to this thread to make it easier to find)

@rkrisztian
Copy link

rkrisztian commented Nov 7, 2023

This issue is painful to me, see my test results below.

Test machines:

  • Linux (RHEL 8): localhost resolves to ::1 first.
  • MacOS (Monterey): localhost resolves to 127.0.0.1 first.
  • Windows 10

Test project:

  • Node 18.18.2
  • Vite 4.4.5 (cannot listen both on ::1 and 127.0.0.1, unless it listens on all interfaces)
  • Cypress 13.4.0
  • Chrome browser

Test cases:

  • Case 1: Vite listens on localhost, Cypress baseUrl set to localhost
    • => Linux: baseUrl check passes, test fails (can't connect to localhost)
    • => Macos: baseUrl check passes, test fails (can't connect to localhost)
    • => Windows: both pass
  • Case 2: Vite listens on 127.0.0.1, Cypress baseUrl set to 127.0.0.1
    • => Linux: both pass
    • => MacOS: baseUrl check passes, test fails.
    • => Windows: both pass
  • Case 3: Vite listens on 127.0.0.1, Cypress baseUrl set to localhost
    • => Linux: baseUrl check fails, test passes
    • => MacOS: baseUrl check fails, test passes.
    • => Windows: both pass
  • Case 4: Vite listens on ::1, Cypress baseUrl set to http://[::1]:5173
  • Case 5: Vite listens on all interfaces, Cypress baseUrl set to localhost
    • => Linux: both pass
    • => MacOS: both pass
    • => Windows: both pass

Conclusion:

  • Apart from case 5, I found no configuration that is platform independent and works.
  • Listening on all interfaces might be a security issue.

@MikeMcC399
Copy link
Contributor

@rkrisztian

Are you able to test on Node.js 20? In some circumstances I've noticed that these IPv4 / IPv6 issues are less of a problem on the later version of Node.js.

This is not to invalidate your issue in any way, but it might possibly be a workaround.

  • You've also linked to Cypress crash with literal IPv6 URL in cy.visit #25950 which I opened. I'm still waiting for the Cypress team to address this bug. I started to look at it myself and it looked like parse is working correctly, but when Cypress reconstructs a URL it doesn't put the necessary [ ] brackets back in to the literal IPv6 address and it breaks the syntax therefore.

@rkrisztian
Copy link

rkrisztian commented Nov 7, 2023

Thanks, @MikeMcC399, I did some quick checks on Linux with Node v20.9.0, my test case results did not change, even the IPv6 issue is still the same.

@cesarvarela
Copy link

cesarvarela commented Nov 17, 2023

News about this? We are using Gatsby v5, and Node 18 is a requirement.

Things I've tried:

  • setting Node v20
  • NODE_OPTIONS: --dns-result-order=ipv4first
  • using 127.0.0.1 as baseURL instead of localhost

Considering this bug is almost a year old, I'd like to know if there is any workaround I'm missing.

@levino
Copy link

levino commented Nov 20, 2023

You just have to start your dev server / app on a host with an ipv4 address. In my case bun astro dev --host 127.0.0.1. No settings / parameters for cypress needed. It looks like cypress cannot resolve localhost to an ipv6 address. Hope that helps.

krachwal added a commit to gt-sse-center/ramanujan-machine-web that referenced this issue Jan 2, 2024
Well this was an odd one... The React frontend could interact with the
Python backend using localhost when the Analyze button was click.
Cypress performing the same button click did not trigger a call to the
Python API. My initial fix was changing the url invoked by the button
click to `127.0.0.1` instead of `localhost`, but the IP didn't sit right
with me. I tried several other fixes, but [enabling
`ipv4first`](cypress-io/cypress#25397 (comment))
is the only one that worked. This is due to a fairly recent change to
NodeJS documented
[here](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder)
and further explained
[here](https://nodejs.org/api/dns.html#dnslookuphostname-options-callback)
as setting `verbatim` to false in dns lookup, which prioritized ipv4
addresses over ipv6:

> verbatim
[<boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)
When true, the callback receives IPv4 and IPv6 addresses in the order
the DNS resolver returned them. When false, IPv4 addresses are placed
before IPv6 addresses. Default: true (addresses are not reordered).
@RobertWagnerPLG
Copy link

I just run into this issue (Cypress v12.17.4 with node v18.16.1).
Configure the serving webapp (Angular) to use the host "127.0.0.1" instead the default "localhost" fixed the problem on my side.

Before I found this workaroud in this issue-thread here I had another one (Working with proxy and default "localhost"-setting"):
I'm working behind a proxy, but this proxy isn't defined globally. Only in the .npmrc the proxy is set. Cypress takes this proxy and says that it is managed by the system.

  • If I unset the proxy-settings in .npmrc cypress works fine.
  • If I let the proxy-settings in .npmrc as they are cypress cannot load localhost
  • If I let the proxy-settings in .npmrc as they are and try to override/unset them via a user-environment-variable before starting cypress it cannot load localhost (even cypress shows the correct overwritten proxysettings).
    So it points to an underlaying nodeJS-issue with a set proxy.

@RobinMeow
Copy link

RobinMeow commented Apr 1, 2024

My workaround for anyone interested
(Using angular, but should work for any, imho)

I had a few personal requirements:

  • I did not want to change the host property. I want the app to run on localhost, not on 127.0.0.1
  • The workaround should not affect performance (total runtime of e2e test) to much (not at all at best)
  • should not cause alot of boilerplate
  • should not require thrid party tools, any extra effort

go to your support file cypress/support/e2e.ts and add this one line of code:
fetch(Cypress.env('baseUrl'), { method: 'GET' }) // fire and forget

I figured, since the cause for the issue is a cy.request() (and it was still an issue, after I replaced my login logic with fetch()), we can just do a fetch before all tests run.

Of course you can use a hardcoded url for this fetch('http://localhost:4200', {method: 'GET'}), but I used mine from the cypress.config.ts
image

Give me a thumbs up, if it works for you as well. I will report back, If I improve or change anything or if it stop working :C

RobinMeow added a commit to RobinMeow/CommunityCookbook that referenced this issue Apr 2, 2024
- [x] do not use deleteTestUser at end of tests to clean up state (it
should also not use the ui with cy.)
- [x] use cy.task('db:reset') to clean up state before tests when
required
- [x] do not use createTestUser before tests to login (its using the UI
as well, which should not be)
- [x] use minimal login implementation as command (using fetch and
storing the response (access token) into localStorage

- known issue at Cypress
cypress-io/cypress#25397 (comment)
- workaround as descibred in the cypress comment. (triggering a fetch to
the spa, before all tests run)
@rphmee-lo
Copy link

go to your support file cypress/support/e2e.ts and add this one line of code: fetch(Cypress.env('baseUrl'), { method: 'GET' }) // fire and forget

This resolved the issue for me, quick and easy without having to change the host.

@fre-ben
Copy link

fre-ben commented Apr 11, 2024

@RobinMeow solution worked like a charm. Thanks!

@robbporto
Copy link

I was using Node 20.10.0 and had to downgrade to Node 16.13.2. I can confirm that this is a bug.

@ph1823
Copy link

ph1823 commented Apr 25, 2024

Ma solution de contournement pour toute personne intéressée (en utilisant angulaire, mais devrait fonctionner pour tout le monde, à mon humble avis)

J'avais quelques exigences personnelles :

  • Je ne voulais pas changer la propriété hôte. Je veux que l'application s'exécute sur localhost, pas sur 127.0.0.1
  • La solution de contournement ne devrait pas trop affecter les performances (durée d'exécution totale du test e2e) (pas du tout au mieux)
  • ne devrait pas causer beaucoup de passe-partout
  • ne devrait pas nécessiter d'outils tiers, aucun effort supplémentaire

allez dans votre fichier de support cypress/support/e2e.ts et ajoutez cette ligne de code : fetch(Cypress.env('baseUrl'), { method: 'GET' }) // fire and forget

J'ai pensé que, puisque la cause du problème est un cy.request() (et c'était toujours un problème, après avoir remplacé ma logique de connexion par fetch()) , nous pouvons simplement effectuer une récupération avant l'exécution de tous les tests.

Bien sûr, vous pouvez utiliser une URL codée en dur pour cela fetch('http://localhost:4200', {method: 'GET'}), mais j'ai utilisé la mienne ducypress.config.ts image

Donnez-moi un coup de pouce, si cela fonctionne aussi pour vous. Je ferai un rapport si j'améliore ou change quelque chose ou si cela cesse de fonctionner :C

what node version ?
what angular version ?
Because on my case dont work :(
edit: a solution for me is set host to 0.0.0.0 and that work, url in cypress is localhost

@zayehalo
Copy link

zayehalo commented May 8, 2024

Can you try adding "host": "127.0.0.1" to your apps/client/project.json for the serve.options configuration and see if it works? I tried it locally and it worked for me. You can still use localhost for visiting your site locally and telling Cypress how to connect but Webpack needs to be forced to use ipv4 over ipv6 (my understanding of DNS is fuzzy admittedly).

To be explicit, this is the update I made:

"serve": {
  "executor": "@nrwl/webpack:dev-server",
  "defaultConfiguration": "development",
  "options": {
    "buildTarget": "client:build",
    "hmr": true,
    "host": "127.0.0.1" <----
  },

Still investigating if there is an issue on our side. Cypress will warn the user it can't connect to the provided baseUrl, but in this case there is no warning yet the connection fails when using cy.visit.

Edit: After investigating, it looks like the issue is due to Nx's use of localhost for the default value of host used in for their webpack-dev-server executor. This use prohibits use of ipv4. Workaround described above should be enough, you can also use 0.0.0.0 to open both ipv4 and ipv6.

This is what worked for me. Thanks.

ETA: This works only when running the target headless. I still get the issue when using cypress open Very super annoying as it's very hard to debug failing tests. Cypress v13.8.1 Node 20.11.0

ETA #2: This only worked locally for me. Totally flopped in our gitlab pipeline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E2E Issue related to end-to-end testing pkg/server This is due to an issue in the packages/server directory Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.
Projects
None yet
Development

No branches or pull requests