Testing JavaScript
When to Use
Use when verifying JavaScript functionality, especially AJAX interactions, accessibility, and cross-browser compatibility.
Decision
Drupal uses Nightwatch.js for JavaScript testing (replaced PHPUnit's FunctionalJavascriptTestBase). Nightwatch runs tests in real browsers using WebDriver, enabling true JavaScript and accessibility testing.
Pattern
Test file location:
modules/custom/MODULE/tests/src/Nightwatch/Tests/featureTest.js
Basic Nightwatch test:
module.exports = {
'@tags': ['module_name'],
'Test feature behavior': (browser) => {
browser
.drupalInstall()
.drupalLoginAsAdmin()
.drupalRelativeURL('/admin/config')
.waitForElementVisible('.element-selector', 1000)
.click('.button-selector')
.assert.textContains('.result', 'Expected text')
.drupalLogAndEnd({onlyOnError: false});
}
};
Testing AJAX:
'Test AJAX interaction': (browser) => {
browser
.click('.ajax-trigger')
.waitForElementVisible('.ajax-result', 2000)
.assert.textContains('.ajax-result', 'Updated content');
}
Accessibility testing (with aXe):
'Test accessibility': (browser) => {
browser
.drupalRelativeURL('/page')
.initAccessibility()
.assert.accessibility();
}
Running tests:
# From Drupal root
yarn test:nightwatch tests/Nightwatch/Tests/featureTest.js
Common Mistakes
- Wrong: Testing with PHP instead of JavaScript → Right: Use Nightwatch for JS
- Why: Can't test actual JavaScript execution, Nightwatch is correct tool
- Wrong: No accessibility tests → Right: Include accessibility assertions
- Why: Misses WCAG compliance issues that affect users
- Wrong: Not testing AJAX scenarios → Right: Test AJAX interactions
- Why: Most common source of JavaScript bugs in Drupal
- Wrong: Hardcoded waits instead of waitForElement → Right: Use smart waits
- Why: Flaky tests, timing issues
See Also
- AJAX Integration - What to test
- Reference: JavaScript Testing with Nightwatch
- Reference: Nightwatch in Drupal Core
- Reference: Functional JavaScript Testing