First of all, make sure that you have Chrome at least 59.0 installed.
To run your code using headless chrome, use
-R chrome (
--runner chrome) option:
$ opal -Rchrome -e "puts 'Hello, Opal'" Hello, Opal
The runner also listens for any exceptions and prints formatted stracktraces back to your console:
$ opal -Rchrome -e " def raising_method raise 'test error' end raising_method " RuntimeError: test error from <internal:corelib/…>:2693:7:in `<main>' from -e:1:1:in `undefined'
By default headless chrome runner explicitly sets exit code to 1 when there was any error in the code.
$ opal -Rchrome -e "42"; echo $? 0 $ opal -Rchrome -e "raise 'error'"; echo $? RuntimeError: error from <internal:corelib/kerne…>:2693:7:in `<main>' from -e:1:1:in `undefined' 1
You can change final exit code by using
Kernel#exit, but make sure to require
opal/platform in your code.
$ opal -Rchrome -ropal/platform -e "exit(0)"; echo $? 0 $ opal -Rchrome -ropal/platform -e "exit(1)"; echo $? 1
Kernel#exit doesn't abort your script. It simply takes the value that was passed to the first
invocation and persists it in
window.OPAL_EXIT_CODE. Later headless chrome runner extracts it from the chrome runtime.
exitdoesn't abort you script (but
console.log(one, two, three)from your code headless chrome prints only the first passed object. The reason behind it is the format of the message that chrome sends to the runner. Opal intentionally uses a simplified method from Chrome API (
Console.messageAdded) to catch
lib/opal/cli_runners/chrome.jsdo get more information)
Under the hood when you call
opal -Rchrome -e 'your code' Opal uses chrome runner that is defined in
lib/opal/cli_runners/chrome.rb. This runner tries to connect to
localhost:9222 (9222 is a default port for a headless chrome server)
or runs the server on its own. It detects your platform and uses a default path to the chrome executable
Opal::CliRunners::Chrome#chrome_executable) but you can override it by specifying
When the server is up and running it passes compiled js code to
as a plain input using stdin (basically, it's a second part of the runner).
chrome_cdp_interface.rb is a node js + Opal script that does the main job. It runs any provided code on the running chrome server,
catches errors and forwards console messages.
If you want to change a default chrome port or your chrome server is running on a different host:port
you can override default values by specifying
CHROME_PORT environment variables:
$ CHROME_HOST=10.10.10.10 CHROME_PORT=8080 opal -Rchrome -e "puts 42" Connecting to 10.10.10.10:8080... 42
CHROME_HOST requires a chrome server to be started. You can't start remotely a server on a different host.
If you need to pass additional CLI options to the Chrome executable you can do so by setting the
CHROME_OPTS environment variable:
$ CHROME_OPTS="--window-size=412,732" opal -Rchrome -e "puts 42" 42
Docker users may need
CHROME_OPTS="--no-sandbox" due to the user namespaces limitations.
For a list of additional options see https://developers.google.com/web/updates/2017/04/headless-chrome