Skip to content

Testing

DXPR Builder has four kinds of automated checks: a Puppeteer test of the editor, Bash end-to-end tests for the Drush commands, a Selenium visual regression suite in the separate dxpr_maven repository, and linters. This page lists each one, how to run it locally and how CI runs it.

What exists

Check Where it lives Runs on
Editor console and layout test test/test-editor.js Pull requests that touch JavaScript, HTML or test/ (.github/workflows/fe-test.yaml)
Drush end-to-end tests scripts/drush-e2e/ Pull requests that touch PHP, YAML or Markdown (.github/workflows/review.yaml)
Selenium visual regression suite dxpr_maven repository PR comment commands (.github/workflows/e2e-command.yaml, e2e-bs3-command.yml, e2eV2-command.yaml)
PHP coding standards (phpcs) scripts/linters/run-drupal-lint.sh, phpcs.xml.dist Pull requests that touch PHP, YAML or Markdown; every push to 3.x
PHPStan scripts/linters/run-drupal-check.sh Pull requests that touch PHP, YAML or Markdown; every push to 3.x
ESLint, Stylelint, Rust Clippy scripts/linters/ Pull requests, filtered by changed paths
Deprecation detectors .github/workflows/deprecations.yml Pull requests that touch js/ or dxpr_builder/build/
Docs checks (markdownlint, check_docs.py, Vale) .markdownlint-cli2.yaml, docs/lint/, .vale.ini Pull requests that touch docs/ (review.yaml)

The only PHPUnit test in the repository is modules/dxpr_builder_media/tests/src/FunctionalJavascript/MediaEntityBrowserTest.php for the legacy media submodule. No GitHub workflow runs it; the drupal.org GitLab pipeline (.gitlab-ci.yml) uses the standard DrupalCI templates, whose PHPUnit job is not switched off there.

Editor console test

test/test-editor.js starts a static server on port 3000 (test/start-standalone-server.js) and opens four standalone pages from test/standalone-editor/ in headless Chrome: test-bs5-anon.html, test-bs5-cms-block.html, test-bs5-editor.html and test-bs5-clean-html.html. It fails when:

  • a page throws a JavaScript error;
  • the full editor is not ready within 2000 ms, or no off-screen controls are left deferred after load (the performance gate);
  • element controls overlap in Power user mode (the baseline is zero overlapping pairs);
  • the saved HTML of the full editor page is larger than the reference of 32,094 characters;
  • a page-specific check fails, for example the parsing of clean Bootstrap HTML, the breadcrumb, the Panel types, the local video Muted setting or the CMS block preview.

The pages load the built files from dxpr_builder/, so build first.

  1. Install dependencies:

bash npm install

  1. Build the editor bundle. The CI script runs these tasks in this order (test/scripts/run-fe-tests.sh):

bash npx grunt concat npx grunt exec:gen npx grunt babel npx grunt terser npx grunt sass npx grunt postcss

  1. Run the test:

bash npm run fe-test

Use npm run fe-test:headed to watch the browser, and npm run fe-test:dev to serve the standalone pages without running assertions.

In CI, .github/workflows/fe-test.yaml runs the same test through Docker:

docker compose --profile fe-test run --rm fe-test

Drush end-to-end tests

scripts/drush-e2e/run-e2e-tests.sh installs a fresh Drupal 11 site with SQLite inside a Composer container, symlinks the module into it, enables it, creates a Basic page content type with the dxpr_builder_text formatter, a page template and a user template, then runs every scripts/drush-e2e/test-*.sh file:

File Commands under test
test-cleartext-key-update.sh Update 9026 clears a clear-text product key left under Key module storage, and keeps it when the chosen Key is gone (cleartext-key-update.php)
test-cms-cache-tags.sh Cache invalidation of block and view listings (cms-cache-tags.php)
test-elements.sh drush dxb:element:list
test-migration-summary.sh Singular and plural wording of the migration column summary (migration-summary.php)
test-migrations.sh drush dxb:migrate and content migration regressions (migration-regressions.php)
test-page-controller.sh The page controller builds for its routes (page-controller.php)
test-page-create.sh drush dxb:page:create
test-page-get-update.sh drush dxb:page:get, drush dxb:page:update
test-page-module.sh The Drag and Drop Page module ships every configuration it lists (page-module.php)
test-profile-buttons.sh Text editor buttons of builder profiles (profile-buttons.php)
test-profile-order.sh Which profile applies by weight, and the order of the profile list (profile-order.php)
test-settings-form.sh Saving and validating the product key on General Settings, and the licence sync it triggers (settings-form.php)
test-setup-ai.sh drush dxb:setup-ai
test-templates.sh drush dxb:template:list
test-user-licenses-page.sh The licence card shows once on User Licenses and still shows on People (user-licenses-page.php)
test-user-settings.sh Each editor's own editor settings (user-settings.php)
test-user-templates.sh drush dxb:user-template:list, drush dxb:user-template:create

Run all of them:

docker compose --profile drush-e2e run --rm e2e-test

Run one file by passing part of its name; the script matches scripts/drush-e2e/test-*<filter>*.sh:

docker compose --profile drush-e2e run --rm e2e-test page-create

To add a test, create scripts/drush-e2e/test-<name>.sh, call section "<Title>", and use the helpers from scripts/drush-e2e/_helpers.sh: assert_success, assert_fail, assert_eq, assert_has, assert_not_empty, assert_runs and assert_dry_run. Each helper takes a description and a command string.

In CI this suite is the "Run Drush E2E tests" job in .github/workflows/review.yaml. It runs when a pull request changes .php, .module, .inc, .install, .yml, .md, composer.json or composer.lock files.

Selenium visual regression suite

The browser tests are Java TestNG suites in the dxpr_maven repository. They run against a Docker stack defined in docker-compose.test.yml (Selenium hub, Chrome nodes and a Maven container) on a site installed from this repository. You do not run them from a local checkout; you trigger them from a pull request comment. .github/workflows/command-dispatcher.yml turns the comment into a workflow run.

Command Suite Workflow
/e2e chrome.editor.bs5.parallel.xml plus the anonymous BS5 suite e2e-command.yaml
/e2e-bs3 chrome.editor.bs3.parallel.xml e2e-bs3-command.yml
/e2eV2 BS5 editor and anonymous suites on the DXPR CMS stack e2eV2-command.yaml
/qa-demo-2x-dxpr_theme6x-tests QA demo with DXPR Theme 6.x qa-demo-2x-dxpr_theme6x-tests-command.yaml

Options, as documented in CONTRIBUTING.md:

  • groups=row-element-test,icon-element-test runs the named <test name="..."> groups from the suite XML.
  • tests=RowColumnLayoutVisualTest runs the named test classes.
  • maven_ref=branch-name uses a dxpr_maven branch, which is how a builder change and its test update are reviewed together.

The workflow uploads target/reports/** and the screenshots as a build artifact and posts the result as a comment on the pull request, listing failures or tests that only passed on retry. Each suite job has a 90-minute timeout.

Linters and static analysis

Each linter is a Docker Compose service, so no local toolchain is required beyond Docker.

Service Command What it checks
drupal-lint docker compose run --rm drupal-lint phpcs with PHPCompatibility (PHP 8.3 and up), Drupal and DrupalPractice standards
drupal-check-D11 docker compose run --rm drupal-check-D11 PHPStan level 5 with mglaman/phpstan-drupal inside a fresh drupal/recommended-project
eslint docker compose run --rm eslint ESLint on js/ and dxpr_builder/build/, plus a spellcheck of dxpr_builder/extracted_t_functions.js
stylelint docker compose run --rm stylelint Stylelint on dxpr_builder/sass/ and sass/
rust-lint docker compose run --rm rust-lint Clippy on the Rust sources in rust/
no-jquery, no-underscore, html-in-js docker compose run --rm <service> Deprecation detectors from .github/workflows/deprecations.yml

Auto-fix variants exist for phpcs, ESLint and Stylelint (drupal-lint-auto-fix, eslint-auto-fix, stylelint-auto-fix). The same checks are available without Docker through npm run lint:scss, npm run lint:no-jquery, npm run lint:no-underscore and npm run lint:html-in-js.

npm install also installs a Husky pre-commit hook (.husky/pre-commit). It runs the matching auto-fix and lint services on the staged JavaScript, PHP and SCSS files and the Rust sources, and docs/video-tools/bin/lint-videos.mjs when files under docs/ are staged.

.github/workflows/review.yaml runs the linters that match the changed paths on every pull request. .github/workflows/main.yaml runs drupal-lint, eslint, drupal-check-D11 and rust-lint on every push to 3.x. Both fail the build when a check fails and write a summary with the offending files.

What's next?

  • Contributing for the pull request process and the maven_ref workflow for test updates.
  • Drush commands for the commands the Bash suite exercises.
Something wrong or missing on this page? Report it or edit the page.