Reputation: 2988
I want to run a headless chrome inside a Docker container using selenium and webdriver with nodejs. I have created a container with everything installed and while I can launch a headless chrome inside successfully launching a nodejs webdriver test always crashes after some time.
WebDriverError: unknown error: Chrome failed to start: exited abnormally
(Driver info: chromedriver=2.32.498513 (2c63aa53b2c658de596ed550eb5267ec5967b351),platform=Linux 4.9.41-moby x86_64)
at WebDriverError (/usr/src/app/node_modules/selenium-webdriver/lib/error.js:27:5)
at Object.checkLegacyResponse (/usr/src/app/node_modules/selenium-webdriver/lib/error.js:529:15)
at parseHttpResponse (/usr/src/app/node_modules/selenium-webdriver/lib/http.js:509:13)
at doSend.then.response (/usr/src/app/node_modules/selenium-webdriver/lib/http.js:441:30)
at process._tickCallback (internal/process/next_tick.js:109:7)
From: Task: WebDriver.createSession()
at Function.createSession (/usr/src/app/node_modules/selenium-webdriver/lib/webdriver.js:769:24)
at Function.createSession (/usr/src/app/node_modules/selenium-webdriver/chrome.js:761:15)
at createDriver (/usr/src/app/node_modules/selenium-webdriver/index.js:170:33)
at Builder.build (/usr/src/app/node_modules/selenium-webdriver/index.js:642:16)
at Object.<anonymous> (/usr/src/app/selenium.js:19:4)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
Full code can bee seen here too.
My Dockerfile is something like this
FROM debian:sid
# Install deps + add Chrome Stable + purge all the things
RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl unzip \
gnupg \
--no-install-recommends \
&& curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update && apt-get install -y \
nodejs npm google-chrome-stable \
--no-install-recommends \
&& apt-get purge --auto-remove -y gnupg \
&& rm -rf /var/lib/apt/lists/*
# Add Chrome as a user
RUN groupadd -r chrome && useradd -r -g chrome -G audio,video chrome \
&& mkdir -p /home/chrome && chown -R chrome:chrome /home/chrome
# Add app and install dependencies
WORKDIR /usr/src/app
RUN chown -R chrome: /usr/src/app
USER chrome
COPY . .
RUN npm install
ENV DBUS_SESSION_BUS_ADDRESS=/dev/null
CMD ["node", "selenium.js"]
I have tried several version but it is always more or less the same.
Asp npm dependencies I have
"chromedriver": "^2.32.0",
"selenium-webdriver": "^3.5.0"
And my code is this kind of hello world that works smooth in my regular computer
const fs = require('fs');
const webdriver = require('selenium-webdriver');
const chromedriver = require('chromedriver');
// const PATH_TO_CHROME = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe';
const PATH_TO_CHROME = '/usr/bin/google-chrome';
const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set('chromeOptions', {
binary: PATH_TO_CHROME,
'args': [
'--headless --window-size=800,600 --disable-gpu',
]
});
const driver = new webdriver.Builder()
.forBrowser('chrome')
.withCapabilities(chromeCapabilities)
.build();
// Navigate to google.com, enter a search.
driver.get('https://www.google.com/ncr');
driver.findElement({ name: 'q' }).sendKeys('webdriver', webdriver.Key.RETURN);
driver.wait(webdriver.until.titleIs('webdriver - Google Search'), 1000);
// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
fs.writeFileSync('screenshot.png', new Buffer(base64png, 'base64'));
});
driver.quit();
Finally I run everything with
docker run --rm --cap-add=SYS_ADMIN headless
What is happening? I don't know how to get more log details too. I read different articles about the particularities for running chrome in docker but there seems to be something preventing my webdriver to work.
I have filled an issue in the webdriver project to track this issue.
Upvotes: 3
Views: 1968
Reputation: 2988
The problem is passing the chrome arguments. It is an array and should be passed this way instead as in the CLI
chromeCapabilities.set('chromeOptions', {
binary: PATH_TO_CHROME,
'args': [
'--headless', '--verbose', '--window-size=1920,1080', '--ignore-certificate-errors'
]
});
After that the error is not shown anymore.
Upvotes: 2
Reputation: 74750
Selenium distribute a "standalone" Chrome Docker container (Firefox too) that uses the Selenium standalone java server. You can run these in the background and then connect to them with your webdriver tests.
Any webdriver library will be able to connect (like https://webdriver.io) without you having to worry about the low level details of getting browsers to launch.
The Selenium Chrome docker image is also debian based but it includes some extended chrome and webdriver config.
Upvotes: 0