bahmutov / start-server-and-test

Starts server, waits for URL, then runs test command; when the tests end, shuts down server
MIT License
1.53k stars 95 forks source link

start-server-and-test failure wait for localhost of react-app Node.js 18 (update) #358

Closed MikeMcC399 closed 1 year ago

MikeMcC399 commented 1 year ago

This is an update to issue https://github.com/bahmutov/start-server-and-test/issues/356 which was closed automatically. The issue is still reproducible in start-server-and-test 1.15.5 2.0.0.

The environment is updated to start-server-and-test 1.15.5 2.0.0 and cypress 12.7.0

Environment

$ npm ls
react-app-test@0.1.0
├── @testing-library/jest-dom@5.16.5
├── @testing-library/react@13.4.0
├── @testing-library/user-event@13.5.0
├── cypress@12.7.0
├── react-dom@18.2.0
├── react-scripts@5.0.1
├── react@18.2.0
├── start-server-and-test@2.0.0
└── web-vitals@2.1.4

Node.js 18.14.x Windows 11 local ubuntu-22.04 on GitHub

Problem description

start-server-and-test fails waiting for http://localhost:3000 locally on Windows 11 with Node.js 18.14.2 and on GitHub in an ubuntu-22.04 runner using the current default Node.js 18.14.1.

Debug logs show

making HTTP(S) head request to  url:http://localhost:3000 ...
  HTTP(S) error for http://localhost:3000 Error: connect ECONNREFUSED ::1:3000

Steps to reproduce

Windows 11 local

Clone https://github.com/MikeMcC399/react-app-test

nvm use 18.14.2
npm ci
export DEBUG=start-server-and-test
npm run test:cypress

test hangs although the default browser successfully opens http://127.0.0.1:3000.

$ netstat -an | grep LISTENING | grep 3000
  TCP    0.0.0.0:3000           0.0.0.0:0              LISTENING

curl receives a reponse for: http://localhost:3000 http://127.0.0.1:3000 not for http://[::1]:3000

GitHub

View workflow log https://github.com/MikeMcC399/react-app-test/actions/workflows/test-react-app.yml or fork https://github.com/MikeMcC399/react-app-test and run .github/workflows/test-react-app.yml

Workaround

wait for http://127.0.0.1:3000 instead of http://localhost:3000

On Windows 11

npm run test:cypress:workaround

Related issues

haoqunjiang commented 1 year ago

Cross-post my comment here as it's likely relevant: https://github.com/bahmutov/start-server-and-test/pull/357#issuecomment-1445818922

As for the Node.js 17+ and 0.0.0.0 issues, there's an explanation in the Vite documentation: https://vitejs.dev/config/server-options.html#server-host

In Vite, we choose to default to localhost for the least surprise, and warn the users when their configuration might be problematic.

MikeMcC399 commented 1 year ago

@sodatea

Many thanks for the vite documenation link https://vitejs.dev/config/server-options.html#server-host which clears up an issue I have in https://github.com/cypress-io/github-action/issues/802!

MikeMcC399 commented 1 year ago

I don't believe that this issue can be resolved by start-server-and-test directly (assuming that start-server-and-test continues to depend on wait-on).

Ideally react-app should allow starting a development server which listens on both IPv4 and IPv6. I could not find any way to do this. I tried setting the environment variable HOST to 0.0.0.0 but it still didn't listen to requests on IPv6 ::1.

Secondly, the wait-on technology, that start-server-and-test relies on to check whether a server is running, needs to implement "Happy Eyeballs" to check on both IPv4 and IPv6 stacks for a running server. (See issue https://github.com/jeffbski/wait-on/issues/137.)

In the meantime there is the workaround of waiting for the IPv4 loopback address 127.0.0.1 instead of waiting for the hostname localhost for Node.js 18 environments and later.

I will leave this issue open for comments first, then I intend to close it.

MikeMcC399 commented 1 year ago

I guess it would be possible to add a new feature to start-server-and-test with a selectable new option to make a special case out of testing localhost.

If wait-on fails testing localhost, then start-server-and-test could explicitly try both 127.0.0.1 and ::1 in addition. This would be like "Happy Eyeballs".

I don't know if it would be a good thing to implement it here. It should really be a change to wait-on. The wait-on maintainer has however so far not responded, so I have no idea what the chances are that wait-on will indeed be upgraded. wait-on would need to cope with localhost on Node.js 18 and later when the server is only responding on one of the two network stacks consisting of IPv4 and IPv6.

joshribakoff-sm commented 1 year ago

I don't know if it would be a good thing to implement it here. It should really be a change to wait-on

Or even NodeJS itself, or potentially whatever lower level things NodeJS is relying on. This affects the entire NodeJS ecosystem, and shouldn't be imposed on package maintainers maybe beyond a callout in the readme IMO.

For me, I was able to just switch from localhost to 127.0.0.1 both in my dev server, and in this package.