How to run Drupal’s Nightwatch tests in Lando

Updated: 2021-10-07

This post follows on from "How to run Drupal’s PHPUnit tests in Lando" post but covers running (not writing) NightwatchJS tests instead of PHPUnit tests. NightwatchJS tests in Drupal run quickly and are fairly easy to write. As a module maintainer they are my preferred type of test over functional PHP unit tests. This post doesn't cover writing tests and is only focussed on running them within Lando containers.

We won't cover the initial set up of Lando in this blog post so please refer to the previous post in particular the sections titled "Lando set up" and "Drupal installation". Once you have a working Drupal 9 installation we can continue.

Configure Lando to run Nightwatch tests

To have an environment to run the tests we need to install a new service (container) in Lando. The Chromedriver that DrupalCI uses will be used to run the tests in a real browser.

Add the following to your service section in your existing .lando.yml file:

  chrome:
    type: compose  
    app_mount: false
    services:    
      image: drupalci/webdriver-chromedriver:production    
      command: chromedriver --log-path=/tmp/chromedriver.log --verbose --whitelisted-ips=

To run NightwatchJS tests we need to use Yarn or NPM to do so. In this example we'll use Yarn. The main problem with running Nightwatch tests in a containerised environment like Lando is that the containers can't run scripts in other containers. As Drupal's Nightwatch implementation will need to run PHP scripts and commands, PHP also needs to be available in the same container. Instead of a separate NodeJS and PHP container, it is easier to install NodeJS in the appserver container. Modify your .lando.yml config for the appserver so it looks like this:

services:
  appserver:
    build_as_root:
      - curl -sSk https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
      - echo "deb https://deb.nodesource.com/node_12.x jessie main" | tee /etc/apt/sources.list.d/nodesource.list
      - curl -sSk https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
      - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
      - apt-get update && apt-get install -y nodejs yarn
    overrides:
      environment:
        SIMPLETEST_BASE_URL: 'http://mysite.lndo.site'
        SIMPLETEST_DB: 'mysql://database:database@database/database'
        MINK_DRIVER_ARGS_WEBDRIVER: '["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless", "--no-sandbox"]}}, "http://chrome:9515"]'

Modify SIMPLETEST_BASE_URL and SIMPLETEST_DB to point to your lando site and database credentials as needed.

We also need a way of telling Lando to run yarn within the appserver container so add this tooling section:

tooling:
  yarn:
    service: appserver
    cmd: yarn

Install the needed node modules

To run the Nightwatch tests we need to install some node modules in our node container. Change directory to your Drupal core directory:

cd web/core

Note if you have a different webroot specified you'll need to modify the above command.

Now install the modules:

lando yarn install

This will use the node service (container) to install the correct node modules that Drupal core requires to run tests.

Add environment variables

When you run the tests in the next step some environment variables need to be passed to node via a .env file. This needs to be created in Drupal's core directory and should contain the following:

DRUPAL_TEST_BASE_URL=http://mysite.lndo.site
DRUPAL_TEST_DB_URL=sqlite://localhost/sites/default/files/db.sqlite
DRUPAL_TEST_WEBDRIVER_HOSTNAME=chrome
DRUPAL_TEST_WEBDRIVER_PORT=9515
DRUPAL_TEST_CHROMEDRIVER_AUTOSTART=false
DRUPAL_TEST_WEBDRIVER_CHROME_ARGS="--disable-gpu --headless --no-sandbox"
DRUPAL_NIGHTWATCH_OUTPUT=reports/nightwatch
DRUPAL_NIGHTWATCH_IGNORE_DIRECTORIES=node_modules,vendor,.*,sites/*/files,sites/*/private,sites/simpletest

Important! Edit the first line so it matches your Lando site's address (change mysite to match whatever your site is called in Lando).

Run Nightwatch tests

Now we're ready to run the tests. Make sure you're currently in the core directory. The following command runs the Drupal core test to check the login page works correctly:

lando yarn test:nightwatch tests/Drupal/Nightwatch/Tests/loginTest.js

You should see the following test output:

yarn run v1.22.4
$ cross-env BABEL_ENV=development node -r dotenv-safe/config -r babel-register ./node_modules/.bin/nightwatch --config ./tests/Drupal/Nightwatch/nightwatch.conf.js tests/Drupal/Nightwatch/Tests/loginTest.js

[Tests/Login Test] Test Suite
=============================
ℹ Connected to chrome on port 9515 (131ms).
  Using: chrome (74.0.3729.157) on Linux platform.

Running:  Test login

✔ Expected element <.user-role-form .machine-name-value> to be visible in 2000ms (534ms)
✔ User "user" was created successfully (29ms)
✔ Passed [equal]: The user "user" was logged in.
✔ Element <body> was visible after 23 milliseconds.
✔ Testing if element <h1> contains text 'Reports' (23ms)
✔ Ensuring no deprecation errors have been triggered (6ms)

OK. 6 assertions passed. (15.09s)
Done in 25.59s.

Complete .lando.yml file example

A more complete .lando.yml might look like:

name: projectname
recipe: drupal9
config:
  xdebug: true
  webroot: docroot
  php: '7.4'
proxy:
  mailhog:
    - mail.projectname.lndo.site # Change projectname to the same as the name key above.
  adminer:
    - adminer.projectname.lndo.site # Change projectname to the same as the name key above.
services:
  appserver:
    build:
      - 'if [ ! -z ${GITHUB_TOKEN} ]; then cd $LANDO_MOUNT && composer config
        --global --auth --unset github-oauth.github.com && composer config
        --global github-oauth.github.com $GITHUB_TOKEN; fi'
    overrides:
      environment:
        SIMPLETEST_BASE_URL: "http://appserver"
        SIMPLETEST_DB: "sqlite://localhost/tmp/db.sqlite"
        MINK_DRIVER_ARGS_WEBDRIVER: '["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless", "--no-sandbox"]}}, "http://chrome:9515"]'
        DRUSH_OPTIONS_ROOT: '/app/web'
        DRUSH_OPTIONS_URI: 'http://projectname.lndo.site'
  database:
    creds:
      user: database
      password: database
      database: database
  mailhog:
    type: mailhog
    hogfrom:
      - appserver
    portforward: true
  adminer:
    type: compose
    services:
      image: dehy/adminer
      command: '/bin/s6-svscan /etc/services.d'
    portforward: true
  chrome:
    type: compose
    app_mount: false
    services:
      image: drupalci/webdriver-chromedriver:production
      command: chromedriver --log-path=/tmp/chromedriver.log --verbose --whitelisted-ips=
tooling:
  drupal-check:
    service: appserver
    cmd: vendor/bin/drupal-check
  yarn:
    service: appserver
    cmd: yarn
  test:
    service: appserver
    cmd: "php /app/vendor/bin/phpunit -c /app/phpunit.xml"

This includes the ability to run PHPUnit tests (see the last blog post) as well as Nightwatch tests.

Back to blog