Open nicolas-marien opened 1 year ago
@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?
@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.
@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
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.
@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.
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.
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.
I've created a simple reproduction here. The README explains the bug in detail. My understanding of the bug is:
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]
.127.0.0.1
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.
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.
@nicolas-marien your workflow is totally valid. I've routed this to the e2e team and they will prioritize accordingly.
@ZachJW34 thanks for the feedback.
Are there any updates on this issue? Thanks.
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.
We are unable to upgrade to node 18 due to this issue
For me instructing the bundle server (in my case vite) to explicitly use host '127.0.0.1' fixed the issue.
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
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
The original issue was reported for Macos but same was happening on Windows for us. Upgrading to latest versions of Node and Cypress didn't help. The only thing which helped was changing the precedence rules for network stack by:
netsh interface ipv6 set prefix ::ffff:0:0/96 60 4
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)
This issue is painful to me, see my test results below.
Test machines:
localhost
resolves to ::1
first.localhost
resolves to 127.0.0.1
first.Test project:
Test cases:
http://[::1]:5173
Conclusion:
@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.
[ ]
brackets back in to the literal IPv6 address and it breaks the syntax therefore.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.
News about this? We are using Gatsby v5, and Node 18 is a requirement.
Things I've tried:
NODE_OPTIONS: --dns-result-order=ipv4first
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.
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.
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.
My workaround for anyone interested (Using angular, but should work for any, imho)
I had a few personal requirements:
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
Edit 2024-08-29: The intend is to have the first http request go the front end. The support file runs before the tests (to eliminate race conditions). Depending on what other code you have in your support file, you should most likely put that line of code at the top of the file
.
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
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
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.
@RobinMeow solution worked like a charm. Thanks!
I was using Node 20.10.0 and had to downgrade to Node 16.13.2. I can confirm that this is a bug.
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
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
Can you try adding
"host": "127.0.0.1"
to yourapps/client/project.json
for theserve.options
configuration and see if it works? I tried it locally and it worked for me. You can still uselocalhost
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 usingcy.visit
.Edit: After investigating, it looks like the issue is due to Nx's use of
localhost
for the default value ofhost
used in for their webpack-dev-server executor. This use prohibits use ofipv4
. Workaround described above should be enough, you can also use0.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
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.
The solution is insane ! Works on Node 18 as well as 20 !! Could you explain the solution ? @rphmee-lo
@atefevan
The solution is insane ! Works on Node 18 as well as 20 !! Could you explain the solution ?
Here is the original comment: https://github.com/cypress-io/cypress/issues/25397#issuecomment-2030468503
It was quite some time ago. To explain it propperly I'd need dive into the cypress code itself. The bug is not really transparent and I don't wanna invest the time to dig deep into it.
Please note the solution is a hacky work-around and not a good solution. (Yet, it didnt seem to cause any other harm so might as well use the quick hack and continue productivity)
Explanation to what I know:
When I refer to http request or just requests I mean ´cy.request()´ ´cy.visit()´ etc.. they all just http requests.
The bug occurs when the first request is not your front end. In this case your other requests will fail (If I remeber correctly, this includes the requests being made by cypress itself).
Example:
Imagine you have two tests run in parallel. One test (lets call it "SERVER"-test) starts of with a cy.request to the server, whereas the other "CLIENT"-test starts of with a front end cy.visist(). You now have a race condition. You don't know which one will run first. Assumingly both tests are correct, they will both fail if the "SERVER"-test runs first. Likewise both will succeed if the "CLIENT"-tests runs first.
To prevent that we simply make sure that the very first request is made to the front end. We do this by putting that one line of code into the support file. It can by a cy.visit, a cy.request a fetch, or whatever http request (any will work). (There might be a better place to put that fetch in, than the support file, but it was the best thing I found, when I searched for a suitable place. The support file runs before the tests, the fethc should be at the top of the file depending on what other things you have in there.)
Last sidenote:
Usually a Http Request also returns a Http Response. We don't actually care about the result. We don't actually even care if it resolves at all. It only matters for the request to be made. Hence the comment "fire and forgot". Which is a comment you use to describe "work" you sheduled (like calling an async method) but you didnt wait (await) for the work to complete because you dont care when it finishes.
See https://github.com/cypress-io/cypress/issues/27962 if researching ipv6 issues, i added my comment today relating to disabling ipv6 on windows when relying on ipv4 tunnels
We are also facing this issue (cc @mageoffray) while testing a VITE v5.4.3 application.
We'd like to process some cy.request()
before loading the application and starting the tests but it fails unless adding a cy.visit()
before as a workaround.
Cypress version used: 13.4.2
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 usecy.visit
. Thecy.visit
fails (see screenshot attached) telling is that the connection is refused. When openinghttp://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 🍪).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
Runyarn 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
Other
No response