I've found that running WebDriver-based tests using GitHub Actions is relatively inexpensive and pretty easy to set up and maintain. I'm sure others are doing this already but I couldn't find much on this topic and there are a few gotchas, so here's a summary of my experience getting this up and running.
I am working on a testing library called bff and a plugin for it called bff-webdriver that allows you to run WebDriver-based tests. To continuously test the plugin, I've been using GitHub Actions but only running WebDriver test through the plugin's BrowserStack integration (shout out to BrowserStack for providing the service for free). When my colleague Jim submitted the first PR, however, the CI job failed. This is because the BrowserStack credentials that are stored as secrets in the repo are not shared (otherwise people would be able to submit a PR to your repo with malicious code that can access/leak those secrets). I decided that it was time to not only test the BrowserStack integration but also run the tests with a local Selenium server.
The first thing I needed to do was set up "services" in my workflow file. Services are just Docker images that are run as containers to support your workflow. I first had to set these up for testing a web framework I'm working on called nrg. It was more straightforward in that case because the requests are unidirectional. The web framework makes requests to the Redis and PostgreSQL services and that's it. With WebDriver, it's bidirectional. The test framework makes requests to the Selenium Hub, the Selenium Hub makes requests to the browser services, and the browsers make requests to the server being tested.
Set up the Selenium Hub and a Firefox service (Click here for the whole file):
services:
hub:
image: selenium/hub:3.141.59-gold
firefox:
image: selenium/node-firefox:3.141.59-gold
env:
HUB_HOST: hub
HUB_PORT: 4444
(You can set up other browsers like Chrome or maybe even Edge and Safari since GitHub Actions can run Windows and macOS VMs but this is beyond the scope of what I needed).
Next I had to configure a --network-alias
option which is used as the hostname
for your test server by the browser(s). I also had to specify an environment
variable for the Selenium Hub hostname (it's the same name as the service,
hub
) so that the test framework knows where to make the WebDriver requests as
well as an environment variable for the network alias so that my tests know
where to tell the browser(s) to navigate.
Set up your server and tests within a container (Click here for the whole file):
container:
image: node:13.6
options: --network-alias testHost
env:
SELENIUM_HUB_HOST: hub
TEST_HOST: testHost
Now in your tests, make requests to http://testHost
and that's it, you should
now have a WebDriver testing setup using GitHub Actions. If you're interested in
a lighter-weight browser testing setup, checkout my
Playwright GitHub Action
which makes testing in a headless Chrome environment easier.