---
url: 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/testen'
title: 'Testen | DXPR'
author:
  name: Jurriaan
  url: 'https://dxpr.com/users/jurriaan'
date: '2026-10-24T02:33:23+00:00'
updated: '2026-10-24T17:19:22+00:00'
copyright: 'Copyright DXPR. All rights reserved.'
type: article
summary: |-
  DXPR Builder heeft vier soorten geautomatiseerde controles: een Puppeteer-test van
  de editor, Bash end-to-end-tests voor de Drush-opdrachten, een Selenium
  visuele-regressiesuite in de aparte dxpr_maven-repository, en
  linters. Deze pagina somt elk op, hoe je hem lokaal draait en hoe CI
  hem draait.
tags:
  - Tooling
image: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
published: true
og:
  site_name: DXPR
  updated_time: '2026-10-24T17:19:22+0000'
  'image:alt': 'DXPR, powered by Drupal: AI-powered Drupal for marketers.'
schema:
  '@context': 'https://schema.org'
  '@graph':
    -
      mainEntity: {  }
    -
      '@type': TechArticle
      headline: Testen
      description: |-
        DXPR Builder heeft vier soorten geautomatiseerde controles: een Puppeteer-test van
        de editor, Bash end-to-end-tests voor de Drush-opdrachten, een Selenium
        visuele-regressiesuite in de aparte dxpr_maven-repository, en
        linters. Deze pagina somt elk op, hoe je hem lokaal draait en hoe CI
        hem draait.
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-24T02:33:23+0000'
      dateModified: '2026-10-24T17:19:22+0000'
      author:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      mainEntityOfPage: 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/testen'
      articleSection: Tooling
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/testen'
      description: |-
        DXPR Builder heeft vier soorten geautomatiseerde controles: een Puppeteer-test van
        de editor, Bash end-to-end-tests voor de Drush-opdrachten, een Selenium
        visuele-regressiesuite in de aparte dxpr_maven-repository, en
        linters. Deze pagina somt elk op, hoe je hem lokaal draait en hoe CI
        hem draait.
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: Home
            item: 'https://dxpr.com/nl'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: nl
---
[Helpcentrum](/nl/hc)/[Documentatie](/nl/hc/documentatie) /[DXPR Builder leren](/nl/hc/documentation/learn-dxpr-builder) /[Uitbreiden](/nl/hc/documentation/learn-dxpr-builder/extend) /[Tooling](/nl/hc/documentation/learn-dxpr-builder/extend/tooling) # Testen.

 DXPR Builder lerenUitbreidenTooling

   ## In deze gids

 Gerelateerde gidsen

- [Bijdragen](/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/bijdragen)
- [Drush-opdrachten](/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/drush-opdrachten)

DXPR Builder heeft vier soorten geautomatiseerde controles: een Puppeteer-test van de editor, Bash end-to-end-tests voor de Drush-opdrachten, een Selenium visuele-regressiesuite in de aparte `dxpr_maven`-repository, en linters. Deze pagina somt elk op, hoe je hem lokaal draait en hoe CI hem draait.

## Wat bestaat

| Controle | Waar die staat | Draait op |
|---|---|---|
| Editor console and layout test | `test/test-editor.js` | Pull requests die JavaScript, HTML of `test/` raken (`.github/workflows/fe-test.yaml`) |
| Drush end-to-end tests | `scripts/drush-e2e/` | Pull requests die PHP, YAML of Markdown raken (`.github/workflows/review.yaml`) |
| Selenium visual regression suite | `dxpr_maven`-repository | PR-reactieopdrachten (`.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 die PHP, YAML of Markdown raken; elke push naar `3.x` |
| PHPStan | `scripts/linters/run-drupal-check.sh` | Pull requests die PHP, YAML of Markdown raken; elke push naar `3.x` |
| ESLint, Stylelint, Rust Clippy | `scripts/linters/` | Pull requests, gefilterd op gewijzigde paden |
| Deprecation detectors | `.github/workflows/deprecations.yml` | Pull requests voor `js/` of `dxpr_builder/build/` |
| Docs checks (markdownlint, `check_docs.py`, Vale) | `.markdownlint-cli2.yaml`, `docs/lint/`, `.vale.ini` | Pull requests die `docs/` raken (`review.yaml`) |

De enige PHPUnit-test in de repository is `modules/dxpr_builder_media/tests/src/FunctionalJavascript/MediaEntityBrowserTest.php`voor de legacy mediasubmodule. Geen GitHub-workflow draait hem; de drupal.org GitLab-pipeline (`.gitlab-ci.yml`) gebruikt de standaard DrupalCI-templates, waarvan de PHPUnit-job daar niet is uitgeschakeld.

## Editorconsoletest

`test/test-editor.js` start een statische server op poort 3000 (`test/start-standalone-server.js`) en opent vier standalone pagina's uit `test/standalone-editor/` in headless Chrome: `test-bs5-anon.html`, `test-bs5-cms-block.html`, `test-bs5-editor.html` en `test-bs5-clean-html.html`. Hij faalt wanneer:

- een pagina een JavaScript-fout gooit;
- de volledige editor niet binnen 2000 ms klaar is, of er na laden geen uitgestelde off-screen controls overblijven (de performancegate);
- elementbediening overlapt in de Power user-modus (de baseline is nul overlappende paren);
- de opgeslagen HTML van de volledige editorpagina groter is dan de referentie van 32.094 tekens;
- een paginaspecifieke controle mislukt, bijvoorbeeld het parsen van schone Bootstrap-HTML, de breadcrumb, de Panel types, de lokale video-instelling **Muted** of de CMS-blokpreview.

De pagina's laden de gebouwde bestanden uit `dxpr_builder/`, dus bouw eerst.

1. Installeer afhankelijkheden:

    ```bash
    npm install

    ```
2. Bouw de editorbundle. Het CI-script draait deze taken in deze volgorde (`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

    ```
3. Draai de test:

    ```bash
    npm run fe-test

    ```

    Gebruik `npm run fe-test:headed` om de browser te bekijken, en `npm run fe-test:dev` om de standalone pagina's te serveren zonder asserts uit te voeren.

In CI draait `.github/workflows/fe-test.yaml` dezelfde test via Docker:

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

```

## Drush end-to-end-tests

`scripts/drush-e2e/run-e2e-tests.sh` installeert een verse Drupal 11-site met SQLite in een Composer-container, symlinkt de module erin, schakelt hem in, maakt een Basic page-inhoudstype met de `dxpr_builder_text`-formatter, een paginasjabloon en een gebruikerssjabloon, en draait daarna elk `scripts/drush-e2e/test-*.sh`-bestand:

| Bestand | Geteste opdrachten |
|---|---|
| `test-cleartext-key-update.sh` | Update 9026 wist een clear-text productsleutel achtergelaten onder Key-moduleopslag, en behoudt hem wanneer de gekozen Key weg is (`cleartext-key-update.php`) |
| `test-cms-cache-tags.sh` | Cache-invalidatie van blok- en viewlijsten (`cms-cache-tags.php`) |
| `test-elements.sh` | `drush dxb:element:list` |
| `test-migration-summary.sh` | Enkelvoud- en meervoudsformulering van de migratiekolomsamenvatting (`migration-summary.php`) |
| `test-migrations.sh` | `drush dxb:migrate` en inhoudsmigratie-regressies (`migration-regressions.php`) |
| `test-page-controller.sh` | De paginacontroller bouwt voor zijn 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` | De Drag and Drop Page-module levert elke configuratie die hij vermeldt (`page-module.php`) |
| `test-profile-buttons.sh` | Teksteditorknoppen van builderprofielen (`profile-buttons.php`) |
| `test-profile-order.sh` | Welk profiel geldt op gewicht, en de volgorde van de profielenlijst (`profile-order.php`) |
| `test-settings-form.sh` | De productsleutel opslaan en valideren op **General Settings**, en de licentiesync die hij triggert (`settings-form.php`) |
| `test-setup-ai.sh` | `drush dxb:setup-ai` |
| `test-templates.sh` | `drush dxb:template:list` |
| `test-user-licenses-page.sh` | De licentiekaart toont één keer op **User Licenses** en toont nog steeds op **People** (`user-licenses-page.php`) |
| `test-user-settings.sh` | De eigen editorinstellingen van elke redacteur (`user-settings.php`) |
| `test-user-templates.sh` | `drush dxb:user-template:list`, `drush dxb:user-template:create` |

Draai ze allemaal:

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

```

Draai één bestand door een deel van zijn naam door te geven; het script matcht `scripts/drush-e2e/test-*<filter>*.sh`:

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

```

Om een test toe te voegen, maak je `scripts/drush-e2e/test-<name>.sh`, roep je `section "<Title>"` aan, en gebruik je de helpers uit `scripts/drush-e2e/_helpers.sh`: `assert_success`, `assert_fail`, `assert_eq`, `assert_has`, `assert_not_empty`, `assert_runs` en `assert_dry_run`. Elke helper neemt een beschrijving en een opdrachtstring.

In CI is deze suite de "Run Drush E2E tests"-job in `.github/workflows/review.yaml`. Hij draait wanneer een pull request `.php`-, `.module`-, `.inc`-, `.install`-, `.yml`-, `.md`-, `composer.json`- of `composer.lock`-bestanden wijzigt.

## Selenium visuele-regressiesuite

De browsertests zijn Java TestNG-suites in de `dxpr_maven`-repository. Ze draaien tegen een Docker-stack gedefinieerd in `docker-compose.test.yml` (Selenium-hub, Chrome-nodes en een Maven-container) op een site geïnstalleerd uit deze repository. Je draait ze niet vanuit een lokale checkout; je triggert ze vanuit een pull request-reactie. `.github/workflows/command-dispatcher.yml` maakt van de reactie een workflowrun.

| Opdracht | Suite | Workflow |
|---|---|---|
| `/e2e` | `chrome.editor.bs5.parallel.xml` plus de anonieme BS5-suite | `e2e-command.yaml` |
| `/e2e-bs3` | `chrome.editor.bs3.parallel.xml` | `e2e-bs3-command.yml` |
| `/e2eV2` | BS5-editor en anonieme suites op de DXPR CMS-stack | `e2eV2-command.yaml` |
| `/qa-demo-2x-dxpr_theme6x-tests` | QA-demo met DXPR Theme 6.x | `qa-demo-2x-dxpr_theme6x-tests-command.yaml` |

Opties, zoals gedocumenteerd in `CONTRIBUTING.md`:

- `groups=row-element-test,icon-element-test` draait de genoemde `<test name="...">`-groepen uit de suite-XML.
- `tests=RowColumnLayoutVisualTest` draait de genoemde testklassen.
- `maven_ref=branch-name` gebruikt een `dxpr_maven`-branch, waarmee een builderwijziging en zijn testupdate samen worden gereviewd.

De workflow uploadt `target/reports/**` en de screenshots als buildartefact en post het resultaat als reactie op de pull request, met mislukkingen of tests die alleen bij retry slaagden. Elke suitejob heeft een timeout van 90 minuten.

## Linters en statische analyse

Elke linter is een Docker Compose-service, dus behalve Docker is geen lokale toolchain nodig.

| Service | Opdracht | Wat het controleert |
|---|---|---|
| `drupal-lint` | `docker compose run --rm drupal-lint` | phpcs met PHPCompatibility (PHP 8.3 en hoger), `Drupal`- en `DrupalPractice`-standaarden |
| `drupal-check-D11` | `docker compose run --rm drupal-check-D11` | PHPStan level 5 met `mglaman/phpstan-drupal` in een verse `drupal/recommended-project` |
| `eslint` | `docker compose run --rm eslint` | ESLint op `js/` en `dxpr_builder/build/`, plus een spellcheck van `dxpr_builder/extracted_t_functions.js` |
| `stylelint` | `docker compose run --rm stylelint` | Stylelint op `dxpr_builder/sass/` en `sass/` |
| `rust-lint` | `docker compose run --rm rust-lint` | Clippy op de Rust-bronnen in `rust/` |
| `no-jquery`, `no-underscore`, `html-in-js` | `docker compose run --rm <service>` | Deprecation-detectoren uit `.github/workflows/deprecations.yml` |

Auto-fix-varianten bestaan voor phpcs, ESLint en Stylelint (`drupal-lint-auto-fix`, `eslint-auto-fix`, `stylelint-auto-fix`). Dezelfde controles zijn zonder Docker beschikbaar via `npm run lint:scss`, `npm runlint:no-jquery`, `npm run lint:no-underscore`en `npm run lint:html-in-js`.

`npm install` installeert ook een Husky pre-commit hook (`.husky/pre-commit`). Hij draait de bijpassende auto-fixen lintservices op de gestagede JavaScript-, PHP- en SCSS-bestanden en de Rust-bronnen, en `docs/video-tools/bin/lint-videos.mjs` wanneer bestanden onder `docs/` zijn gestaged.

`.github/workflows/review.yaml` draait de linters die bij de gewijzigde paden passen op elke pull request. `.github/workflows/main.yaml` draait `drupal-lint`, `eslint`, `drupal-check-D11` en `rust-lint` op elke push naar `3.x`. Beide laten de build falen wanneer een controle faalt en schrijven een samenvatting met de overtredende bestanden.

## Wat nu?

- [Bijdragen](/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/bijdragen) voor het pull request-proces en de `maven_ref`-workflow voor testupdates.
- [Drush-opdrachten](/nl/hc/documentatie/dxpr-builder-leren/ontwikkeling/drush-opdrachten) voor de opdrachten die de Bash-suite oefent.