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

Cypress tests fail in air-gapped network on Firefox #31036

Open
ChadiEM opened this issue Feb 6, 2025 · 11 comments
Open

Cypress tests fail in air-gapped network on Firefox #31036

ChadiEM opened this issue Feb 6, 2025 · 11 comments

Comments

@ChadiEM
Copy link

ChadiEM commented Feb 6, 2025

Current behavior

In an air gapped network, running a component or e2e tests using cypress on Firefox using the cypress/included docker image fails with the following error:

Cypress failed to make a connection to Firefox.

This usually indicates there was a problem opening the Firefox browser.

FetchError: request to https://raw.githubusercontent.com/mozilla/geckodriver/release/Cargo.toml failed, reason: read ECONNRESET
    at ClientRequest.<anonymous> (file:///root/.cache/Cypress/14.0.2/Cypress/resources/app/packages/server/node_modules/node-fetch/src/index.js:108:11)
    at ClientRequest.emit (node:events:518:28)
    at emitErrorEvent (node:_http_client:101:11)
    at TLSSocket.socketErrorListener (node:_http_client:504:5)
    at TLSSocket.emit (node:events:518:28)
    at emitErrorNT (node:internal/streams/destroy:169:8)
    at emitErrorCloseNT (node:internal/streams/destroy:128:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

This is likely a regression introduced in release 13.15.1 which started using geckodriver.

Desired behavior

I expect the test to run in an air gapped network. It should not send any request to the internet.

Test code to reproduce

Any test in Firefox in an air-gapped network.

Cypress Version

14.0.2

Node version

v22.13.1

Operating System

Debian bookworm

Debug Logs

Other

I also attempted to override the environment variables supported by geckodriver to use a local path

GECKODRIVER_VERSION = '0.35.0'
GECKODRIVER_CDNURL = 'file:///path/to/geckodriver/'

But it failed node-fetch does not support file:.

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Feb 6, 2025

The issue is reproducible with cypress/included and cypress/browsers Docker images. Edit: It does not appear to be an issue in native Ubuntu or Windows environments.

Steps to reproduce

git clone https://github.com/cypress-io/cypress-docker-images
cd cypress-docker-images
cd examples/basic-mini
docker run -it --rm -v .:/app -w /app --entrypoint cypress cypress/included:14.0.2 run -b firefox

OR

cd examples/basic
npm install [email protected]
docker build . -f Dockerfile.browsers -t test-browsers
docker run -it --rm --entrypoint bash test-browsers -c "npx cypress run -b firefox"
  • Run first with network connection
  • Repeat final docker run with disconnected network
Cypress:        14.0.2
Browser:        Firefox 135 (headless)
Node Version:   v22.13.1 (/usr/local/bin/node)

@MikeMcC399
Copy link
Contributor

https://www.npmjs.com/package/geckodriver

found in

"geckodriver": "4.5.1",

attempts to download a driver
https://github.com/webdriverio-community/node-geckodriver/blob/92a64548339a9fe2fa6902498e15e506b45213a1/src/constants.ts

export const GECKODRIVER_CARGO_YAML = 'https://raw.githubusercontent.com/mozilla/geckodriver/release/Cargo.toml'

@AtofStryker
Copy link
Contributor

We should be able to preinstall geckodriver in those images before distributing them so at least we know.a version of the driver is there.

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Feb 7, 2025

@AtofStryker

We should be able to preinstall geckodriver in those images before distributing them so at least we know.a version of the driver is there.

I repeated my tests and found that the issue is also reproducible without using a Cypress Docker image, so any fix would be better placed directly in Cypress rather than in a Cypress Docker image.

Ubuntu 24.04.1 LTS, Firefox 135.0, Node.js 22.13.1 LTS

First with connected network:

git clone https://github.com/cypress-io/cypress-docker-images
cd cypress-docker-images
cd examples/basic
npm ci
npm install cypress@latest

Disconnect network, reboot, then navigate to same directory cypress-docker-images/cd examples/basic

npx cypress run -b firefox

Debug Logs

DEBUG=cypress:server:browsers:firefox npx cypress run -b firefox

DevTools listening on ws://127.0.0.1:39059/devtools/browser/693301c6-de97-411f-8194-95c0ac96e6d6

====================================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:        14.0.2                                                                         │
  │ Browser:        Firefox 135 (headless)                                                         │
  │ Node Version:   v22.13.1 (/home/mike/n/bin/node)                                               │
  │ Specs:          1 found (spec.cy.js)                                                           │
  │ Searched:       cypress/e2e/**/*.cy.{js,jsx,ts,tsx}                                            │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  spec.cy.js                                                                      (1 of 1)
  cypress:server:browsers:firefox firefox open { browser: { name: 'firefox', family: 'firefox', channel: 'stable', displayName: 'Firefox', version: '135.0', path: 'firefox', profilePath: '/home/mike/snap/firefox/current', majorVersion: '135', isHeadless: true, isHeaded: false }, url: 'http://localhost:35789/__/#/specs/runner?file=cypress/e2e/spec.cy.js', browsers: [ { name: 'chrome', family: 'chromium', channel: 'stable', displayName: 'Chrome', version: '131.0.6778.204', path: 'google-chrome', majorVersion: '131' }, { name: 'chrome-for-testing', family: 'chromium', channel: 'stable', displayName: 'Chrome for Testing', version: '131.0.6778.204', path: 'chrome', majorVersion: '131' }, { name: 'chromium', family: 'chromium', channel: 'stable', displayName: 'Chromium', version: '132.0.6834.110', path: 'chromium-browser', profilePath: '/home/mike/snap/chromium/current', majorVersion: '132' }, { name: 'firefox', family: 'firefox', channel: 'stable', displayName: 'Firefox', version: '135.0', path: 'firefox', profilePath: '/home/mike/snap/firefox/current', majorVersion: '135' }, { name: 'edge', family: 'chromium', channel: 'stable', displayName: 'Edge', version: '129.0.2792.52', path: 'microsoft-edge', majorVersion: '129' }, { name: 'electron', channel: 'stable', family: 'chromium', displayName: 'Electron', version: '130.0.6723.137', path: '', majorVersion: 130 } ], userAgent: null, proxyUrl: 'http://localhost:35789', proxyServer: 'http://localhost:35789', socketIoRoute: '/__socket', chromeWebSecurity: true, isTextTerminal: true, downloadsFolder: '/home/mike/github/cypress-io/cypress-docker-images/examples/basic/cypress/downloads', experimentalModifyObstructiveThirdPartyCode: false, experimentalWebKitSupport: false, protocolManager: undefined, projectRoot: '/home/mike/github/cypress-io/cypress-docker-images/examples/basic', shouldLaunchNewTab: false, onError: [Function (anonymous)], videoApi: undefined, automationMiddleware: { onBeforeRequest: [Function: onBeforeRequest], onAfterResponse: [Function: onAfterResponse] }, onWarning: [Function: onWarning], onBrowserClose: [Function (anonymous)], relaunchBrowser: [AsyncFunction (anonymous)], onBrowserOpen: [Function: onBrowserOpen] } +0ms
  cypress:server:browsers:firefox available ports: { marionettePort: 43297, webDriverBiDiPort: 34367 } +3ms
  cypress:server:browsers:firefox firefox directories { path: '/home/mike/snap/firefox/current/Cypress/firefox-stable/run-7720', cacheDir: '/home/mike/snap/firefox/current/Cypress/firefox-stable/run-7720/CypressCache', extensionDest: '/home/mike/snap/firefox/current/Cypress/firefox-stable/run-7720/CypressExtension' } +27ms
  cypress:server:browsers:firefox launching geckodriver with browser envs { MOZ_REMOTE_SETTINGS_DEVTOOLS: '1', MOZ_HEADLESS_WIDTH: '1280', MOZ_HEADLESS_HEIGHT: '720' } +1ms
  cypress:server:browsers:firefox launch in firefox {
  url: 'http://localhost:35789/__/#/specs/runner?file=cypress/e2e/spec.cy.js',
  args: [
    '-new-instance',
    '-start-debugger-server',
    '-no-remote',
    '-headless'
  ]
} +0ms
Cypress failed to make a connection to Firefox.

This usually indicates there was a problem opening the Firefox browser.

FetchError: request to https://raw.githubusercontent.com/mozilla/geckodriver/release/Cargo.toml failed, reason: getaddrinfo EAI_AGAIN raw.githubusercontent.com
    at ClientRequest.<anonymous> (file:///home/mike/.cache/Cypress/14.0.2/Cypress/resources/app/packages/server/node_modules/node-fetch/src/index.js:108:11)
    at ClientRequest.emit (node:events:518:28)
    at emitErrorEvent (node:_http_client:101:11)
    at TLSSocket.socketErrorListener (node:_http_client:504:5)
    at TLSSocket.emit (node:events:518:28)
    at emitErrorNT (node:internal/streams/destroy:169:8)
    at emitErrorCloseNT (node:internal/streams/destroy:128:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

@AtofStryker
Copy link
Contributor

I repeated my tests and found that the issue is also reproducible without using a Cypress Docker image, so any fix would be better placed directly in Cypress rather than in a Cypress Docker image.

@MikeMcC399 I don't know how feasible this would be because we would need to ship every OS specific version of the driver with each OS specific version of the binary for a not very common use case. I'm suggesting we ship it in the docker container to at least mitigate the inconvenience of downloading the driver for the most likely use case of having an offline system.

The tests should still run offline, assuming geckodriver is already downloaded on the machine running the tests.

@MikeMcC399

This comment has been minimized.

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Feb 8, 2025

I can offer the following comments & suggestions:

To allow testing of Firefox with Cypress inside an air-gapped network requires the provisioning of Geckodriver binaries to the air-gapped network. Cypress uses the npm module geckodriver to download the driver for use with Firefox.

If a custom Cypress Docker image is built in a network connected to Internet with a Dockerfile which runs Cypress, such as with the addition of the following Dockerfile command:

RUN npx cypress run -b firefox

then the Docker image will include the Geckodriver saved to /tmp/geckodriver. The Internet connection can be dropped and the image can be used in the air-gapped network.

It should also be possible to use the information Setting a CDN URL for binary download which describes creating a local copy of the Geckodriver CDN and using the environment variable GECKODRIVER_CDNURL as in the following example:

GECKODRIVER_CDNURL=https://INTERNAL_CDN/geckodriver/download

As noted in the OP, the file: protocol is not supported using GECKODRIVER_CDNURL with Cypress.

Reasons for not adding a cached Geckodriver to Cypress itself were already given in #31036 (comment). Now, after looking at this in detail, I don't feel that there should be any steps added to standard Cypress Docker images to include cached Geckodriver images either, unless there were to be a high demand from multiple users. This is a special case which is better dealt with by individual customization. I have decided against opening a new issue in the cypress-io/cypress-docker-images/issues for this reason.

@MikeMcC399
Copy link
Contributor

@ChadiEM

If you need more specific advice for using Cypress Docker images to test Firefox in an air-gapped network, I suggest that you open a new issue in https://github.com/cypress-io/cypress-docker-images/issues. It might be helpful to add this as a known issue with a documented workaround. For instance, using GECKODRIVER_AUTO_INSTALL=1 npm install geckodriver seems like a convenient way to get the driver installed and saved.

@ChadiEM
Copy link
Author

ChadiEM commented Feb 10, 2025

Thanks for the help and the analysis, @MikeMcC399 & @AtofStryker.

I created cypress-io/cypress-docker-images#1298.

@MikeMcC399
Copy link
Contributor

@ChadiEM

@MikeMcC399
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants