Hello!
I'm trying to build an AWS Lambda function that shells out to execute a command-line A11Y checker called axe-cli. This checker uses headless chrome, which is expected to be in the PATH.
I've tried to include headless chrome using the serverless-plugin-chrome plugin, but I keep getting an WebDriverError: unknown error: cannot find Chrome binary error.
Here's the code for this function, what am I doing wrong? Thanks!
https://gist.github.com/jaimeiniesta/2c2c42a6487b4a468f64dc9238d41a26
To make the question shorter, what is the path to the Chrome executable installed by serverless-chrome?
Hi @jaimeiniesta. On AWS Lambda, the headless shell should be at /var/task/node_modules/@serverless-chrome/lambda/dist/headless-chromium.
Thanks!
So, I tried adding this to the PATH but still doesn't work in AWS Lambda, it looks like selenium-webdriver can't find it:
2018-07-09 13:39:37.224 (+02:00) bfd787ed-836c-11e8-b351-eb04a73ff2bb Path is:/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/var/task/node_modules/@serverless-chrome/lambda/dist/
START RequestId: bfd787ed-836c-11e8-b351-eb04a73ff2bb Version: $LATEST
2018-07-09 13:39:37.773 (+02:00) bfd787ed-836c-11e8-b351-eb04a73ff2bb Command to run: ./node_modules/axe-cli/axe-cli http://jaimeiniesta.com --save pGd6e6m8tzsD250jVxWcbu6t5Cqd3MuthYj2zhHPCOxfWbeHM01531136377771.json -d /tmp
2018-07-09 13:39:39.028 (+02:00) bfd787ed-836c-11e8-b351-eb04a73ff2bb { Error: Command failed: ./node_modules/axe-cli/axe-cli http://jaimeiniesta.com --save pGd6e6m8tzsD250jVxWcbu6t5Cqd3MuthYj2zhHPCOxfWbeHM01531136377771.json -d /tmp
/var/task/node_modules/selenium-webdriver/lib/promise.js:2626
throw error;
^
WebDriverError: unknown error: cannot find Chrome binary
(Driver info: chromedriver=2.40.565383 (76257d1ab79276b2d53ee976b2c3e3b9f335cde7),platform=Linux 4.9.93-41.60.amzn1.x86_64 x86_64)
at WebDriverError (/var/task/node_modules/selenium-webdriver/lib/error.js:27:5)
at Object.checkLegacyResponse (/var/task/node_modules/selenium-webdriver/lib/error.js:546:15)
at parseHttpResponse (/var/task/node_modules/selenium-webdriver/lib/http.js:509:13)
at doSend.then.response (/var/task/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 (/var/task/node_modules/selenium-webdriver/lib/webdriver.js:769:24)
at Function.createSession (/var/task/node_modules/selenium-webdriver/chrome.js:761:15)
at createDriver (/var/task/node_modules/selenium-webdriver/index.js:170:33)
at Builder.build (/var/task/node_modules/selenium-webdriver/index.js:642:16)
at startDriver (/var/task/node_modules/axe-cli/lib/webdriver.js:33:27)
at testPages (/var/task/node_modules/axe-cli/lib/axe-test-urls.js:11:10)
at Object.<anonymous> (/var/task/node_modules/axe-cli/index.js:73:1)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at ChildProcess.exithandler (child_process.js:204:12)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:886:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
killed: false,
code: 1,
signal: null,
cmd: './node_modules/axe-cli/axe-cli http://jaimeiniesta.com --save pGd6e6m8tzsD250jVxWcbu6t5Cqd3MuthYj2zhHPCOxfWbeHM01531136377771.json -d /tmp' }
Maybe it's the file name, not the PATH? I have /var/task/node_modules/@serverless-chrome/lambda/dist/ in the PATH, but maybe selenium-webdriver doesn't expect the executable to be named headless-chromium?
@jaimeiniesta yes; that's likely true. I think there's an option for selenium/chrome webdriver to specify a path to the chrome executable, but it doesn't seem to be exposed by axe-cli. Perhaps there's an env var that does that same, but I don't know it.
Alternatively, you could grab the chromium binary directly from the releases and package it yourself in your Lambda function. Then you can name it as whatever selenium/webdriver expects.
Thanks! @WilcoFiers can you throw some light here? Is there a way in axe-cli to specify the path to the chrome executable?
@jaimeiniesta if you can't get it working with axe-cli, you might be able to hack something together with axe-core directly in combination with puppeteer or chrome-remote-interface.
@jaimeiniesta Axe-cli doesn't support this. If the only alternative is to rewrite Axe-cli, best to just add it as a feature. Didn't think that'd be necessary though. Let me reach out to someone who's a bit more familiar with Lambda's than I am. --> @stephenmathieson
Disclaimer: I have not tried to run axe-cli on Lambda.
axe-cli uses chromedriver, which can be configured to run headlessly. Based on https://github.com/dequelabs/axe-cli/blob/v3.0.0/lib/webdriver.js#L14-L28, telling it to use "chrome-headless" _should_ Just Workâ„¢. I haven't verified this, but it's probably worth a shot. If it doesn't work, feel free to reach out (_stephen dot mathieson at deque dot com_) and we can try to get something figured out :)
Thanks! I can assure you axe-cli runs great on AWS Lambda - I have been running it for months in production, with axe-core 2.5.0 and phantomjs.
It's only that when I try to update to axe-core 3.0, which uses chrome, I can't get it to work in AWS Lambda. But it looks just a matter of letting it find the executable in the path, it seems.
I'll try to prepare an example repo with the code to run axe-cli + phantomjs + serverless so you can see it working, and a branch with the update to axe-core 3.0 + chrome.
Cool, sounds great Jaime! Let me know 😃
Thanks @stephenmathieson, I just pushed some working code, added you and also @WilcoFiers and @adieuadieu as collaborators (the repo is private by now until the code is more polished up). Thanks a lot for your help!
I would love to see this as well - working on getting this working in a Docker container and running in to a similar issue.
Appreciate your work on this.
@nicklemmon relevant conversation is at https://github.com/jaimeiniesta/serverless-axe-cli/pull/1, which has been made public
Most helpful comment
Hi @jaimeiniesta. On AWS Lambda, the headless shell should be at
/var/task/node_modules/@serverless-chrome/lambda/dist/headless-chromium.