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.