cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.

Home Page:https://cypress.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Connection refused on node v18 in CI

MarcusElevait opened this issue · comments

Current behavior

We have an angular project that we test with cypress.
It runs fine, until we tried to switch from node v16 to node v18.
After switching to node v18 we get the following error in every cypress test:

http://localhost:4206/
We attempted to make an http request to this URL but the request failed without a response.
We received this error at the network level:
  > Error: connect ECONNREFUSED 127.0.0.1:4206
Common situations why this would fail:
  - you don't have internet access
  - you forgot to run / boot your web server
  - your web server isn't accessible
  - you have weird network configuration settings on your computer
Because this error occurred during a `before each` hook we are skipping the remaining tests in the current suite: 'Test navigation functionali...'
      at <unknown> (http://localhost:4206/__cypress/runner/cypress_runner.js:138168:82)
      at visitFailedByErr (http://localhost:4206/__cypress/runner/cypress_runner.js:137560:12)
      at <unknown> (http://localhost:4206/__cypress/runner/cypress_runner.js:138167:11)
      at tryCatcher (http://localhost:4206/__cypress/runner/cypress_runner.js:8914:23)
      at Promise._settlePromiseFromHandler (http://localhost:4206/__cypress/runner/cypress_runner.js:6849:31)
      at Promise._settlePromise (http://localhost:4206/__cypress/runner/cypress_runner.js:6906:18)
      at Promise._settlePromise0 (http://localhost:4206/__cypress/runner/cypress_runner.js:6951:10)
      at Promise._settlePromises (http://localhost:4206/__cypress/runner/cypress_runner.js:7027:18)
      at _drainQueueStep (http://localhost:4206/__cypress/runner/cypress_runner.js:3621:12)
      at _drainQueue ([http://localhost:4206/__cypress/runner/cypress_runner.js:3614:9](http://localhost:4206/__cypress/runner/cypress_runner.js:3614#-9))
      at ../../node_modules/bluebird/js/release/async.js.Async._drainQueues ([http://localhost:4206/__cypress/runner/cypress_runner.js:3630:5](http://localhost:4206/__cypress/runner/cypress_runner.js:3630#-5))
      at Async.drainQueues (http://localhost:4206/__cypress/runner/cypress_runner.js:3500:14)
  From Your Spec Code:
      at Context.eval (webpack:///./src/e2e/navigation/navigating-in-collections.cy.ts:25:11)
  
  From Node.js Internals:
    Error: connect ECONNREFUSED 127.0.0.1:4206
        at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)

Initially thought the angular app maybe crashed, but we see this right before the error message:
** Angular Live Development Server is listening on localhost:4206, open your browser on http://localhost:4206/ **

We're using the cypress/browsers:node18.12.0-chrome103-ff107 docker image as a base image for our pipeline.

We're running this in bitbucket.

What I've tried so far:

  • Run the cypress/browser image locally and start the tests there -> error curiously doesn't occurre
  • Use the node 18.13.0 (latest lts) image with the needed dependencies described on cypress documentation -> same error in the CI pipeline

Desired behavior

Basically just want the test to run without this connection refused error.

Test code to reproduce

Running a basic angular application on port 4206

describe('Test basic app functionalities', () => {
    beforeEach(() => {
        cy.visit('/');
    });
}

cypress.config.ts:

import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset';
import { defineConfig } from 'cypress';

const cypressJsonConfig = {
    fileServerFolder: '.',
    fixturesFolder: './src/fixtures',
    video: true,
    videosFolder: '../../dist/cypress/apps/explorait-e2e/videos',
    screenshotsFolder: '../../dist/cypress/apps/explorait-e2e/screenshots',
    chromeWebSecurity: false,
    baseUrl: 'http://0.0.0.0:4206',
    requestTimeout: 15000,
    defaultCommandTimeout: 15000,
    videoUploadOnPasses: false,
    viewportWidth: 1920,
    viewportHeight: 1080,
    retries: {
        runMode: 2,
        openMode: 0,
    },
    reporter: '../../node_modules/mochawesome',
    reporterOptions: {
        reportDir: '../../dist/cypress/apps/explorait-e2e/results',
        overwrite: false,
        html: false,
        json: true,
    },
    specPattern: 'src/e2e/**/*.cy.{js,jsx,ts,tsx}',
    supportFile: 'src/support/e2e.ts',
};
export default defineConfig({
    e2e: {
        ...nxE2EPreset(__filename),
        ...cypressJsonConfig,
        setupNodeEvents(on) {
            on('before:browser:launch', (browser, launchOptions) => {
                if (browser.name === 'chrome') {
                    // exposes window.gc() function that will manually force garbage collection
                    launchOptions.args.push('--js-flags=--expose-gc');
                }

                return launchOptions;
            });
        },
    },
});

Cypress Version

12.3.0

Node version

18.12.0

Operating System

docker image cypress/browsers:node18.12.0-chrome103-ff107

Debug Logs

Wanted to give you the logs here, but github says body is too long :-(

Other

We're using nx monorepo. There we have this anuglar application and another application which holds the cypress tests.
This is the nx project.json of the cypress app

{
    "name": "explorait-e2e",
    "$schema": "../../node_modules/nx/schemas/project-schema.json",
    "sourceRoot": "apps/explorait-e2e/src",
    "projectType": "application",
    "targets": {
        "e2e": {
            "executor": "@nrwl/cypress:cypress",
            "options": {
                "cypressConfig": "apps/explorait-e2e/cypress.config.ts",
                "tsConfig": "apps/explorait-e2e/tsconfig.e2e.json",
                "devServerTarget": "explorait:serve:e2e",
                "testingType": "e2e"
            },
            "configurations": {
                "production": {
                    "devServerTarget": "explorait:serve:production"
                }
            }
        },
        "lint": {
            "executor": "@nrwl/linter:eslint",
            "options": {
                "lintFilePatterns": ["apps/explorait-e2e/**/*.{js,ts}"]
            }
        }
    },
    "tags": ["e2e", "angular"],
    "implicitDependencies": ["explorait"]
}

I face the same error locally on my linux machine and in the pipeline using the cypress/base:18.12.1 image.

I could workaround this problem by serving Angular on 127.0.0.1 instead of localhost. You can do this by using command line ng serve --host=127.0.0.1 or by updating your angular.json:

{
  [...],
  "projects": {
    "your-project": {
      [...]
      "architect": {
        [...]
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            [...]
            "host": "127.0.0.1"
          },
     [...]

Anyways it'd be nice if Cypress would work with the default settings.

I recently investigated this very issue. I posted about it here. I believe there are two issues:

  • Use of localhost as the default host option for the Angular/webpack-dev-server builder. I don't see any documentation/recommendations for using localhost as the value here (DevServer docs). When it's used, it does not allow ipv4 addresses (so 127.0.0.1 does not work)
  • Cypress derives 127.0.0.1 from a baseUrl with http://localhost:xxxx configured when it should derive [::1] (ipv6). This is only an issue when using host: "localhost" though. host: "[::1]" works just fine.

Edit: I made some headway into the issue I linked above (new comment here). Might be related, but I'll return to this issue tomorrow to see if they are similar.

@MarcusElevait There has been a lot of info posted regarding the workaround (using the host: '127.0.0.1') and an issue on our side #25397. Have you been able to try the workaround? I wasn't able to reproduce the issue with docker locally (though you said everything was working fine with your local docker setup).

I don't run into any issues with a very simple angular + nx repo, regardless of node version. The only issue I found (which is what I linked above) is when a cy.request is made before the visit. You might be running into this issue, but we would need more information on your repo to see if you are experiencing a different issue (docker adds more complexity, especially coupled with CI). Are you able to provide a minimal reproduction exhibiting your failure? Otherwise I'm going to have to close this as a duplicate of #25397

We had a workaround by setting the following env in the docker image that we use to run the tests in our ci pipeline: NODE_OPTIONS=--dns-result-order=ipv4first.

So for us it is good with that.

But yes, in our tests we're running always a cy.request before starting the test for login reasons.

Basically we have the following setup:

  • Bitbucket CI
  • Cypress browser image 18.12.0

A test running the following code:

cy.request({
        method: 'POST',
        url: `http://localhost:3100/login/`,
        body: { username, password },
    }).then(response => {
        cy.setCookie('localhost_sso_access_token', response.body.accessToken);
        cy.setCookie('localhost_sso_refresh_token', response.body.refreshToken);
        cy.reload();
    });

cy.visit('/')

Based on your comments iI'd say the cy.request before the cy.visit is what is causing the issue. Thanks for posting back, going to close as a duplicate of #25397, you can follow that issue to track the progress.

Thanks! This helped me! I have been struggling with this for a week. Thank you so much for sharing!