I have a Docker script that runs some Selenium test scripts.
Here are the Dockerfile contents:
FROM selenium/hub:nightly
WORKDIR /usr/src/app
RUN sudo apt-get update
COPY . /usr/src/app/
RUN sudo curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
RUN sudo apt-get install nodejs -y
CMD ./start.sh
The "start.sh" file looks a bit like this:
#!/usr/bin/env bash
echo "init..."
npm run test:dev
"test" is a NodeJs command (from package.json) which runs:
"test": "cucumber-js features/"
This loads the Selenium Chrome driver and runs a series of Selenium/Cucumber tests.
When run on the desktop (MacOS), everything works great! When I run this using Docker, I get the following error at the beginning of each test. I assume that the test cannot even begin because it cannot load the Chrome driver:
Error: Server terminated early with status 127
at /usr/src/app/node_modules/selenium-webdriver/remote/index.js:259:24
The commands that I'm using to build & run docker are:
docker build - < Dockerfile && docker run selenium_automation_tests < Dockerfile
The contents of our run.sh file are:
#!/usr/bin/env bash
docker build --platform linux/x86_64 -t selenium_automation_tests .
docker run --platform linux/x86_64 -d -p 4442-4444:4442-4444 -it selenium_automation_tests #/bin/bash
I've searched Google & stackoverflow for this error ("Server terminated early with status 127") and have tried a lot of the suggestions, but so far nothing has worked. What can I do to get rid of this error and run the Selenium/Cucumber tests in Docker?
Assuming that your project looks something like this:
├── Dockerfile
├── features
│ ├── step_definitions
│ │ └── test_steps.js
│ └── test.feature
├── package.json
├── run.sh
└── start.sh
🗎 Dockerfile
FROM selenium/standalone-chrome:latest
USER root
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs
WORKDIR /usr/src/app
COPY . .
RUN npm install
RUN chmod +x ./start.sh
USER seluser
CMD ["./start.sh"]
🗎 package.json
{
"name": "selenium-test",
"type": "module",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test:dev": "cucumber-js features/"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"selenium-webdriver": "^4.18.1",
"supabase": "^1.145.4"
},
"keywords": [],
"description": "",
"devDependencies": {
"@cucumber/cucumber": "^10.3.1",
"chai": "^5.1.0",
"chromedriver": "^122.0.6"
}
}
🗎 test.feature
Feature: Chrome Loads Page
Scenario: Load example page
Given I am on the example.com page
Then the page has loaded
🗎 test_steps.js
(The various options ensure that Chrome will run happily inside a container. They might not all be necessary.)
import { Given, Then, After } from '@cucumber/cucumber';
import { Builder, By, until } from 'selenium-webdriver';
import assert from 'assert';
import chrome from 'selenium-webdriver/chrome.js';
let driver;
let options = new chrome.Options();
options.addArguments('--headless');
options.addArguments('--no-sandbox');
options.addArguments('--disable-dev-shm-usage');
options.addArguments('--disable-gpu');
options.addArguments('--disable-extensions');
options.addArguments('--remote-debugging-port=9222');
Given('I am on the example.com page', async function () {
driver = await new Builder().forBrowser('chrome').setChromeOptions(options).build();
await driver.get('http://www.example.com');
});
Then('the page has loaded', async function () {
let element = await driver.wait(until.elementLocated(By.css('h1')), 10000);
let text = await element.getText();
assert.strictEqual(text, "Example Domain", 'The page did not load correctly.');
});
After(async function () {
if (driver) {
await driver.quit();
}
});
The run.sh
and start.sh
files are the same as the ones provided in the question.