Laravel Dusk & GitHub Actions: Running Dusk in CI Pipelines

Admin   Laravel   578  2022-07-19 02:30:01

We have an extensive Laravel Dusk test suite for our test management tool Testmo. In addition to our backend and unit tests, our Dusk-based (Selenium) browser tests allow us to verify all features of the product end-to-end, meaning we can test the app just like a user would: automating the browser to navigate to pages, open dialogs, fill forms and even test complex interactions such as drag&drop or pasting images.

Running these tests locally from our dev machine (or dev Docker environment) is pretty easy. You can either use your dev machine's browser (e.g. Chrome) to run your tests, or use chromium inside your dev container. Laravel Dusk also already ships with a chromedriver binary for Windows and Mac by default to make it easy to automate Chrome. Or, if you use Docker and would like to use the official Selenium browser images, this is pretty easy too (see our Selenium test automation guide).

But what about running our Laravel Dusk tests from our CI pipeline, such as GitHub Actions, GitLab CI/CD or CircleCI? This is important so we can run all our tests whenever we build and deploy a new app version. In this article we will look at the exact steps to get this working.

Running Laravel Dusk with GitHub Actions

In order to run our Laravel Dusk tests as part of our CI pipeline, we need to have access to a browser we can automate during the pipeline run. This is usually Chrome (i.e. chromium), but we can also easily use Firefox or Edge. It doesn't matter whether you are using GitHub Actions, GitLab CI/CD, CircleCI, Bibucket, Jenkins or another service, the approach is always the same.

In order to use a browser from our CI pipeline, you could simply install a browser directly from your pipeline config. But there's a better way. We can use one of the official Selenium Docker images that come pre-configured with a browser plus the matching driver so Laravel Dusk can connect to it. In the following example we will focus on GitHub Actions, but you can use the same Docker containers with GitLab CI/CD, CircleCI etc.

1# .github/workflows/test-single.yml
2name: Test
5 workflow_dispatch:
6 inputs:
7 browser:
8 type: choice
9 description: Which browser to test
10 required: true
11 default: chrome
12 options:
13 - chrome
14 - firefox
15 - edge
18 test:
19 name: Test
20 runs-on: ubuntu-latest
22 services:
23 selenium:
24 image: selenium/standalone-${{ github.event.inputs.browser }}
26 steps:
27 - uses: actions/[email protected]
29 - run: # Your Laravel Dusk test execution goes here
30 env:
31 BROWSER: ${{ github.event.inputs.browser }}
33 - uses: actions/[email protected]
34 if: always()
35 with:
36 name: screenshots
37 path: screenshots/

The above GitHub Actions workflow starts a separate service container using one of the official Selenium images. When we start the pipeline through GitHub's web interface, it asks us which browser to use (Chrome, Firefox, Edge), so we can run our tests against different browsers.

We also make an environment variable available to our Laravel Dusk environment (BROWSER) so we can fine-tune our tests for specific browser behavior if needed. From our Laravel Dusk tests we can just connect to Selenium using the host and port selenium:4444. You also need to set the Selenium capability browser name inside your Laravel Dusk base class to ensure that you ask for the correct browser (you can also use the BROWSER environment variable for this). Note: for Edge, this needs to be MicrosoftEdge.

Running Multiple Browser Sessions in Parallel

The above workflow executes our tests against a single browser. But with GitHub Actions and other CI services it's also easy to run multiple test jobs in parallel. In our case, why not just run our tests against multiple browsers at the same time?

This is pretty easy to do. We can use GitHub Actions' matrix feature to tell it to run our test job multiple times with different settings. In our case we tell GitHub to run our tests three times, once for Chrome, for Firefox and for Edge. We do not need to change our test job much for this. The only thing we need to change is to pass our matrix.browser setting to our Laravel Dusk tests this time instead of the input setting.

1# .github/workflows/test-parallel.yml
2name: Test (parallel)
4on: [workflow_dispatch]
7 test:
8 name: Test
9 runs-on: ubuntu-latest
11 strategy:
12 fail-fast: false
13 matrix:
14 browser: ['chrome', 'firefox', 'edge']
16 services:
17 selenium:
18 image: selenium/standalone-${{ matrix.browser }}
20 steps:
21 - uses: actions/[email protected]
23 - run: # Your Laravel Dusk test execution goes here
24 env:
25 BROWSER: ${{ matrix.browser }}
27 - uses: actions/[email protected]
28 if: always()
29 with:
30 name: ${{ matrix.browser }}
31 path: screenshots/

When we run our workflow now, GitHub Actions will start our test job three times in parallel. For each job it will launch a different Selenium service container with the correct browser. In our Laravel Dusk tests Selenium will always be reachable at selenium:4444. Here's what multiple parallel test jobs look like in GitHub Actions:

Reporting Test Results to Test Management

We can also report our test results from our Laravel Dusk tests to a testing tool such as our Testmo, so we can easily see all test results for our browser tests over time, share the results with our team and easily identify (and fix!) flaky, slow or broken tests. Another advantage of reporting our test results is that we can manage our automated tests together with test case management and exploratory testing in one central tool. Here's what a test automation run looks like in Testmo:

If your team uses GitHub issues, GitLab issues or a dedicated issue tracking tool such as Jira, you can also easily create and link new issues and bug reports. You can learn more about popular integrations here:

When you submit your automated tests to a testing tool, you can also easily archive and review past test results and link them to milestones. So you can always quickly reference and see past results, which would be pretty difficult if you only kept your test results in your CI service.

This guest posting was written by Dennis Gurock, one of the founders of Testmo. Testmo is built using Laravel and uses Laravel Dusk extensively. If you are not familiar with QA tools, he recently built a list of the best test management tools to try.