# AJAX Loading 2.0 – testing

How the plugin is tested, how to run the suites, and the results of the latest full run. The test
suite (`tests/`) lives in the development checkout and is not included in the plugin package
downloaded from WordPress.org; the build tooling (`tools/`, `package.json`) is included but never
loaded by the plugin. Setup details, every command option, the test fixture plugin and how to write
tests are in `tests/README.md` in the development checkout.

Contents

1. [Test suites](#1-test-suites)
2. [Running the tests](#2-running-the-tests)
3. [Results](#3-results)
4. [Bundle sizes](#4-bundle-sizes)
5. [Not covered](#5-not-covered)

---

## 1. Test suites

| Suite | Command | What it runs |
|---|---|---|
| Unit | `npm run test:unit` | `node:test` with a happy-dom document; imports the front-end and admin modules from `assets/src/js/` directly. No WordPress needed. |
| PHP | `npm run test:php` | PHP tests inside a real WordPress request (WordPress Playground on port 9402). Any PHP notice, warning, deprecation or `_doing_it_wrong()` from a plugin file fails the test. |
| End-to-end | `npm run test:e2e` | Playwright in Chromium against a Playground site on port 9401 with the test fixture plugin. Projects: `setup`, `block` (Twenty Twenty-Five), `classic` (Twenty Twenty-One), `serial` (admin screen and the PHP tests, plus the debug-log check). |
| Version matrix | `npm run test:matrix` | For each combination (port 9403, one after the other): the PHP tests, the `@smoke` end-to-end subset and the debug-log check. |

What each unit file and each end-to-end spec covers is listed in
`tests/README.md` (development checkout).

## 2. Running the tests

Requirements: Node.js 22 or newer and Chromium for Playwright (`npx playwright install chromium`).
No PHP, MySQL or Docker: the sites run on WordPress Playground (PHP compiled to WebAssembly, SQLite).

```sh
npm install
npm run test:unit                 # about 30 s
npm run test:php
npm run test:e2e
npm run test:matrix
npm test                          # unit + end-to-end (the e2e run includes the PHP tests)
```

If `npm` or `npx` time out while connecting, export a longer connect timeout first (the Playground
scripts add it for their own processes):

```sh
export NODE_OPTIONS="--network-family-autoselection-attempt-timeout=3000 --dns-result-order=ipv4first"
```

`npm run build` rebuilds `assets/dist/` and prints the size table; `npm run size` only prints the
sizes of the current build.

## 3. Results

Latest full run: **2026-10-30**, plugin 2.0.0.

Environment: WordPress Playground CLI 3.1.61 (`@wp-playground/cli`), Chromium via Playwright 1.64.1
(`@playwright/test`).

| Suite | WordPress / PHP | Tests | Passed | Failed | Skipped |
|---|---|---|---|---|---|
| Unit (`npm run test:unit`, 33 suites, about 34 s) | – | 268 | 268 | 0 | 0 |
| PHP (`npm run test:php`) | 7.1.4 / 8.3 | 64 | 64 | 0 | 0 |
| End-to-end (`npm run test:e2e`, 5.5 min) | 7.1.4 / 8.3 | 92 | 91 | 0 | 1 |

End-to-end tests per project:

| Project | Tests | Result |
|---|---|---|
| `setup` | 1 | passed |
| `block` | 64 | all passed |
| `classic` | 15 | 14 passed, 1 skipped |
| `serial` | 12 | all passed; the debug log of the whole run was clean |

The skipped test is "core navigation › new history entries keep foreign state such as
wpInteractivityId" in the `classic` project. It is skipped on purpose because Twenty Twenty-One does
not load `@wordpress/interactivity`; it runs and passes in the `block` project.

Version matrix (`npm run test:matrix`, exit code 0):

| Combination | WordPress | PHP | Theme | PHP tests | E2E smoke | Debug log |
|---|---|---|---|---|---|---|
| `wp6.0-php7.4` | 6.0.18 | 7.4.33 | classic (Twenty Twenty-One) | 64 / 64 passed | 21 / 21 passed | clean |
| `wplatest-php8.3` | 7.1.4 | 8.3.33 | block | 64 / 64 passed | 21 / 21 passed | clean |
| `wplatest-php8.5` | 7.1.4 | 8.5.10 | block | 64 / 64 passed | 21 / 21 passed | clean |

No test failed in any suite or matrix combination. `php -l` passes on all 52 PHP files of the
plugin and its tests.

## 4. Bundle sizes

Measured by `npm run build` (esbuild) after the last source change, from `assets/dist/sizes.json`.
KB = 1,024 bytes.

| File | Raw | Gzip |
|---|---|---|
| `frontend.min.js` (loaded on the front end) | 174,255 bytes (170.17 KB) | 60,266 bytes (58.85 KB) |
| `frontend.min.css` (loaded on the front end) | 8,330 bytes (8.13 KB) | 2,255 bytes (2.20 KB) |
| `frontend.js` (with `SCRIPT_DEBUG`) | 362,453 bytes (353.96 KB) | 81,970 bytes (80.05 KB) |
| `frontend.css` (with `SCRIPT_DEBUG`) | 10,160 bytes (9.92 KB) | 2,410 bytes (2.35 KB) |
| `admin.min.js` (plugin settings screen only) | 119,878 bytes (117.07 KB) | 41,064 bytes (40.10 KB) |
| `admin.min.css` (plugin settings screen only) | 17,669 bytes (17.25 KB) | 4,149 bytes (4.05 KB) |
| `admin.js` (with `SCRIPT_DEBUG`) | 239,811 bytes (234.19 KB) | 55,479 bytes (54.18 KB) |
| `admin.css` (with `SCRIPT_DEBUG`) | 21,346 bytes (20.85 KB) | 4,371 bytes (4.27 KB) |

The admin bundle includes the front-end integration module (`compat.js`), because **Test
navigation** runs the same `exclude`-mode checks as the front end. No size budget is enforced: the
build fails on errors and when a minified bundle contains `eval(` or `new Function(`, never on size.

## 5. Not covered

- **Another site of a multisite network** (a fetched marker whose `data-site` differs, which loads
  normally as `bypass`): the test sites are single sites, so only the navigation unit tests cover this
  branch.
- **Horizontal slides** when a theme clips horizontal overflow only on `<body>`: the slide is kept, and
  a script that scrolls the page horizontally during the slide can offset it briefly (see
  [architecture.md § Known limitations](architecture.md#16-known-limitations)).
- The plugin was not tested against specific third-party plugin or theme versions; integration
  behaviour is described from the code in [compatibility.md](compatibility.md).
