Running Drupal's Nightwatch test suite on DDEV

This is the third, and final post in my series on running Drupal’s various test suites using the DDEV local development stack. Previously I covered running Drupal’s Unit, Kernel, and Functional tests and then running Chromedriver to execute the FunctionalJavascript test suite. In this post, I will talk about running the newly introduced Nightwatch.js test framework.

What is Nightwatch? Straight from the website: "Write End-to-End tests in Node.js quickly and effortlessly that run against a Selenium/WebDriver server.” Added in 8.6, Nightwatch makes it easier to test Drupal’s JavaScript and expands on testing limitations found in the PHPUnit FunctionalJavascript tests — it’s not exactly practical to test JavaScript with PHP! I won’t talk about writing tests in Nightwatch, just running them. You can head over to the documentation to learn more about writing JavaScript tests in Nightwatch.

In order to run Nightwatch, you need to have a few dependencies available: Node.js, Chrome (and Chromedriver), and Yarn. Luckily for us, the web container for DDEV comes with Node.js and Yarn preinstalled! My last post covered getting up and running with Chromedriver as an additional service in your DDEV project, but I’ll reiterate that quickly.

We are going to use a Chromedriver Docker image provided by DrupalCi — the one used when executing tests on Drupal.org. To do this, we need to define a custom service for DDEV. It is petty simple: we just need to add a file called docker-compose.chromedriver.yml to our project's .ddev directory.

version: '3.6'
services:
  chromedriver:
    container_name: ddev-${DDEV_SITENAME}-chromedriver
    image: drupalci/chromedriver:production
    labels:
    # These labels ensure this service is discoverable by ddev
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
      com.ddev.app-url: $DDEV_URL
  # This links the Chromedriver service to the web service defined
  # in the main docker-compose.yml, allowing applications running
  # in the web service to access the driver at `chromedriver`.
  web:
    links:
      - chromedriver:$DDEV_HOSTNAME

This file goes right into the project’s .ddev directory. Now, restart your project and bring the new service online. The Docker image will be pulled down and the container started, managed by DDEV.

Now that you have Chromedriver available, let's get ready to run Nightwatch.

To get setup we need to install the Node.js dependencies for Drupal core. Inside of the core directory run yarn install to download the Node.js dependencies. 

ddev ssh
cd core
yarn install

You should see something similar for the output:

Thumbnail

Next, we need to configure Nightwatch by copying .env.example to .env.

cp .env.example .env

We need to edit the DRUPAL_TEST_BASE_URL variable and set it to be http://web, just like our phpunit.xml in the previous posts. By default, Nightwatch will try to use SQLite. DDEV did not provide SQLite until its latest version (LINK). So, just in case, we will configure it to use the database container. Change DRUPAL_TEST_DB_URL to mysql://db:[email protected]/db just like our phpunit.xml configuration. Finally, we need to modify the hostname for Chromedriver. Change DRUPAL_TEST_WEBDRIVER_HOSTNAME from localhost to chromedriver.

Thumbnail

We are almost ready. We have two more environment variables to change. Modify DRUPAL_TEST_CHROMEDRIVER_AUTOSTART from true to false. This tells Nightwatch to use the Chromedriver we have running as a service instead of trying to run it on the web container. We also need to pass some arguments to ensure Chrome runs headless. Uncomment DRUPAL_TEST_WEBDRIVER_CHROME_ARGS and set it to --disable-gpu --headless --no-sandbox

Here’s an example of what a finished .env would look like (comments removed):

#############################
# General Test Environment #
#############################
DRUPAL_TEST_BASE_URL=http://web
DRUPAL_TEST_DB_URL=mysql://db:[email protected]/db

#############
# Webdriver #
#############
DRUPAL_TEST_WEBDRIVER_HOSTNAME=chromedriver
DRUPAL_TEST_WEBDRIVER_PORT=9515

################
# Chromedriver #
################
DRUPAL_TEST_CHROMEDRIVER_AUTOSTART=false
DRUPAL_TEST_WEBDRIVER_CHROME_ARGS="--disable-gpu --headless --no-sandbox"

##############
# Nightwatch #
##############
DRUPAL_NIGHTWATCH_OUTPUT=reports/nightwatch
DRUPAL_NIGHTWATCH_IGNORE_DIRECTORIES=node_modules,vendor,.*,sites/*/files,sites/*/private,sites/simpletest

We are ready to go! Still, in the core folder, run yarn test:nightwatch --tag core to execute the tests.

Thumbnail

Reports are generated in core/reports to see the outcomes of the tests executed. This directory contains JUnit XML output and console logs from the various tests — useful for debugging.

Thumbnail

There you go, we have run the Nightwatch tests! It is not much yet, but the tests will be growing. I am hoping to write some of my first Nightwatch tests for Drupal soon, and write about the process.