While trying to run E2E tests using Alpine Linux we have the following mysterious error:
E/launcher - spawn (...)/selenium/chromedriver_2.40 ENOENT
How to reproduce
docker run -it --name my-alpine --rm alpine:latest /bin/ash
apk add --update nodejs nodejs-npm chromium \
&& export CHROME_BIN=/usr/bin/chromium-browser
npm install -g @angular/cli
ng new testAlpine
cd testAlpine
ng e2e
The results
[14:10:54] I/file_manager - creating folder /testAlpine/node_modules/protractor/node_modules/webdriver-manager/selenium
ℹ 「wdm」: Compiled successfully.
[14:10:54] I/update - chromedriver: unzipping chromedriver_2.40.zip
[14:10:55] I/update - chromedriver: setting permissions to 0755 for /testAlpine/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.40
(node:121) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
[14:10:55] I/launcher - Running 1 instances of WebDriver
[14:10:55] I/direct - Using ChromeDriver directly...
[14:10:55] E/launcher - spawn /testAlpine/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.40 ENOENT
[14:10:55] E/launcher - Error: spawn /testAlpine/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.40 ENOENT
at _errnoException (util.js:1024:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
at onErrorNT (internal/child_process.js:372:16)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
[14:10:55] E/launcher - Process exited with error code 199
An unexpected error occured: undefined
Some investigation details
Assuming that protractor uses Nodejs spawn function, we tried to run the command from ash, and the result was a "not found" message! digging a little bit about it found that this could be related to a missing dynamic linked library.
In order to validate the assumption, we installed binutils to check for the dynamic link dependency.
apk add --update binutils
readelf -l /testAlpine/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.40
And the results show the dependency that is not present in Alpine Linux,
/lib64/ld-linux-x86-64.so.2
Elf file type is EXEC (Executable file)
Entry point 0x490000
There are 11 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000200040 0x0000000000200040
0x0000000000000268 0x0000000000000268 R 0x8
INTERP 0x00000000000002a8 0x00000000002002a8 0x00000000002002a8
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000
0x000000000028f27c 0x000000000028f27c R 0x1000
LOAD 0x0000000000290000 0x0000000000490000 0x0000000000490000
Trying to get an updated chrome driver version using webdriver-manager didn't work as well. the downloaded version has the same issue.
npm install -g webdriver-manager
webdriver-manager update
webdriver-manager: using global installed version 12.0.6
[14:30:20] I/file_manager - creating folder /usr/lib/node_modules/webdriver-manager/selenium
[14:30:21] I/update - chromedriver: unzipping chromedriver_2.40.zip
[14:30:21] I/update - chromedriver: setting permissions to 0755 for /usr/lib/node_modules/webdriver-manager/selenium/chromedriver_2.40
/testAlpine # /usr/lib/node_modules/webdriver-manager/selenium/chromedriver_2.40
/bin/ash: /usr/lib/node_modules/webdriver-manager/selenium/chromedriver_2.40: not found
Random toughts
It is necessary to rebuild chromedriver with musl libc or to use the chromedriver package from alpine repos, you can install it with apk add --no-cache chromium-chromedriver
.
You also need to tell protractor to use the correct binary with
chromeDriver: '/usr/bin/chromedriver'
in your protractor config.
For people that have this issue in the future, I was totally unable to get the combination of alpine
+ angular
+ protractor
+ webdriver-manager
to co-operate in any out-of-the-box supported way.
After much tinkering around, I managed to get it to work by
Dockerfile:
FROM node:12-alpine
RUN \
echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
&& echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \
&& echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
&& apk --no-cache update \
&& apk --no-cache upgrade \
&& apk add --no-cache --virtual .build-deps chromium chromium-chromedriver \
&& rm -rf /var/cache/apk/* /tmp/*
ENV CHROME_BIN /usr/bin/chromium-browser
protractor.conf.js
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['--headless', '--disable-gpu', '--no-sandbox'],
},
},
directConnect: true,
The script looks somewhat like this:
before_script:
- yarn install --frozen-lockfile --cache-folder "$CI_PROJECT_DIR/.yarn"
script:
- npx webdriver-manager update --versions.chrome="$(chromium-browser --version | cut -d ' ' -f 2)"
- mv "$CI_PROJECT_DIR/node_modules/webdriver-manager/selenium/chromedriver_$(chromium-browser --version | cut -d ' ' -f 2)" "$CI_PROJECT_DIR/node_modules/webdriver-manager/selenium/chromedriver.bak"
- ln -s "/usr/bin/chromedriver" "$CI_PROJECT_DIR/node_modules/webdriver-manager/selenium/chromedriver_$(chromium-browser --version | cut -d ' ' -f 2)"
- yarn run e2e --webdriverUpdate=false
Note that the code mentioned above is code for a Gitlab CI configuration: based on your needs you will probably have to:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With