| 1 |
# Agent and cloud environment guide |
| 2 |
|
| 3 |
Short reference for Cursor Cloud and other non-interactive agents. For full human onboarding use [](.github/CONTRIBUTING.mdCONTRIBUTING.md](.github/CONTRIBUTING.md](.github/CONTRIBUTING.md) and [](tests/test-environment-setup.mdtests/test-environment-setup.md](tests/test-environment-setup.md](tests/test-environment-setup.md). |
| 4 |
|
| 5 |
## Choosing a WordPress environment |
| 6 |
|
| 7 |
| Runtime | When to use | Ports / URL | |
| 8 |
|--------|-------------|----------------| |
| 9 |
| **wp-lite-env** (Docker) | Same stack as Playwright in CI (`.github/workflows/playwright.yml`). Full PHP/MySQL containers, two WP instances. | http://localhost:8888 and http://localhost:8889 | |
| 10 |
| **WP Playground CLI** (`npm run wp-playground`) | No Docker. WordPress in WASM; quick editor and blueprint-driven setup. Default listen address matches local Playwright dev base URL. | http://127.0.0.1:9400 | |
| 11 |
| **wp-env** (`npm run wp-env`, [](.wp-env.json.wp-env.json](.wp-env.json](.wp-env.json)) | Alternative Docker-based `@wordpress/env` setup used in other workflows and docs. | See `@wordpress/env` defaults after `wp-env start` | |
| 12 |
|
| 13 |
Use **wp-lite-env** when you need Docker parity with CI (full Playwright against 8888/8889, `setup.sh`, theme on disk). Use **WP Playground** when Docker is missing or broken; it is sufficient for many editor checks and aligns with `tests/playwright/playwright.config.ts` local `localDevServer` / `localTestServer` (both `http://127.0.0.1:9400` when not in CI). WP Playground still uses a blueprint ([](tests/playwright/blueprints/local.jsontests/playwright/blueprints/local.json](tests/playwright/blueprints/local.json](tests/playwright/blueprints/local.json)) so PHP/WordPress versions may differ from [](tests/playwright/.playwright-wp-lite-env.jsontests/playwright/.playwright-wp-lite-env.json](tests/playwright/.playwright-wp-lite-env.json](tests/playwright/.playwright-wp-lite-env.json). |
| 14 |
|
| 15 |
## Cursor Cloud specifics |
| 16 |
|
| 17 |
### System requirements (typical VM image) |
| 18 |
|
| 19 |
- Node.js version from [](.nvmrc.nvmrc](.nvmrc](.nvmrc) (via nvm; PATH in `~/.bashrc`) |
| 20 |
- PHP >= 7.4 with extensions: mbstring, xml, zip, curl, dom, bcmath (see [](composer.jsoncomposer.json](composer.json](composer.json)) |
| 21 |
- Composer 2.x |
| 22 |
- Docker only if you use wp-lite-env or wp-env (often needs fuse-overlayfs and iptables-legacy in nested setups) |
| 23 |
|
| 24 |
### PATH |
| 25 |
|
| 26 |
The image may ship a system Node under `/exec-daemon/node` that does not match `.nvmrc`. If installs or engines fail, confirm `which node` points at the nvm-managed binary. |
| 27 |
|
| 28 |
### Common commands |
| 29 |
|
| 30 |
| Action | Command | |
| 31 |
|--------|---------| |
| 32 |
| Install deps | `npm ci --ignore-scripts && composer install` | |
| 33 |
| Build packages | `npm run build:packages` | |
| 34 |
| Build styles | `npx grunt styles` | |
| 35 |
| Build scripts | `npx grunt scripts` | |
| 36 |
| Full dev watch | `npm run watch` | |
| 37 |
| Lint JS/TS (root) | `npx eslint .` | |
| 38 |
| Lint JS/TS (packages) | `cd packages && npx eslint . --report-unused-disable-directives-severity error` | |
| 39 |
| Lint PHP | `vendor/bin/phpcs --extensions=php --standard=./ruleset.xml .` | |
| 40 |
| Jest (main) | `npm run test:jest` | |
| 41 |
| Jest (packages) | `npm run test:packages` | |
| 42 |
| All Jest | `npm run test` | |
| 43 |
| Fast DB-less PHPUnit (single/few files) | `tests/phpunit/run-unit.sh <test-file.php> [<test-file.php> ...] [--filter <pattern>]` | |
| 44 |
|
| 45 |
### Fast DB-less PHPUnit for local dev |
| 46 |
|
| 47 |
`tests/phpunit/run-unit.sh` runs a small set of PHPUnit files **without WordPress or MySQL** for a quick inner loop. It uses `tests/phpunit/unit-bootstrap.php`, which only defines `ABSPATH` and registers an `Elementor\` autoloader (same name->path transform as `includes/autoloader.php`), and ignores the project `phpunit.xml`. Pass any number of `test-*.php` files (added to a generated testsuite, which sidesteps PHPUnit's `test-*.php` ↔ `Test_*` filename/classname assumption) plus optional pass-through args like `--filter`. |
| 48 |
|
| 49 |
```bash |
| 50 |
tests/phpunit/run-unit.sh tests/phpunit/elementor/modules/atomic-widgets/css-converter/test-css-converter.php |
| 51 |
tests/phpunit/run-unit.sh tests/phpunit/.../test-css-converter.php --filter test_convert |
| 52 |
``` |
| 53 |
|
| 54 |
Only works for tests whose subjects don't touch WordPress at load/run time. Tests needing WordPress/MySQL (e.g. REST endpoints with `act_as_admin`/`WP_REST_Server`, or anything pulling `Style_Schema`) must use the full suite (`npm run test:setup:playwright` env, or the wp-lite-env setup below). |
| 55 |
|
| 56 |
## wp-lite-env (Docker): full setup |
| 57 |
|
| 58 |
Non-interactive one-shot (skips container cleanup prompt): |
| 59 |
|
| 60 |
```bash |
| 61 |
SKIP_CONFIRMATION=true npm run env:setup |
| 62 |
``` |
| 63 |
|
| 64 |
That script installs deps, builds, downloads Hello Elementor, runs `npm run start-local-server` (8888 **and** 8889), then `npm run test:setup:playwright`. Do not start only 8888 and then run `npm run test:setup:playwright` alone; [](package.jsonpackage.json](package.json](package.json) expects both ports. |
| 65 |
|
| 66 |
Manual equivalent: see [](tests/test-environment-setup.mdtests/test-environment-setup.md](tests/test-environment-setup.md](tests/test-environment-setup.md) (steps: `npm run start-local-server` then `npm run test:setup:playwright`). |
| 67 |
|
| 68 |
If Docker is not running on the VM yet, a typical pattern is `sudo dockerd &>/tmp/dockerd.log &` in the background, then ensure the Docker socket is usable for the agent user (for example `sudo chmod 666 /var/run/docker.sock` in **disposable** environments only). For a manual plugin tree under `./build/` without the setup script, flows often use `composer install --no-scripts --no-dev && composer dump-autoload && npx grunt copy`, then `npm run setup-templates`, then start **both** wp-lite-env instances (see `npm run start-local-server` in [](package.jsonpackage.json](package.json](package.json)). |
| 69 |
|
| 70 |
Admin: http://localhost:8888/wp-admin/ — user `admin`, password `password` (see test environment doc). |
| 71 |
|
| 72 |
## WP Playground CLI (no Docker) |
| 73 |
|
| 74 |
After `npm ci` (or full install per repo): |
| 75 |
|
| 76 |
```bash |
| 77 |
npm run wp-playground |
| 78 |
``` |
| 79 |
|
| 80 |
Wait until the CLI prints that WordPress is running, then open http://127.0.0.1:9400 . This flow was smoke-tested with the same CLI flags as [](package.jsonpackage.json](package.json](package.json) `wp-playground` in a clean agent-style environment without Docker. |
| 81 |
|
| 82 |
For CI-style mounted **build** output use `npm run wp-playground:ci` (expects `./build`). |
| 83 |
|
| 84 |
## Gotchas |
| 85 |
|
| 86 |
- `npm run lint` runs ESLint at the repo root and in the `elementor-packages` workspace (`npm run lint -w elementor-packages`); both must pass. |
| 87 |
- PHPCS may report warnings without errors on the current tree; treat policy from maintainers, not only the exit summary. |
| 88 |
- `composer install` post-install can run php-scoper (Twig prefixing); dev dependency `humbug/php-scoper` must be present for a full dev install. |
| 89 |
- For a production-like plugin tree under `./build`, many flows use `composer install --no-scripts --no-dev` first, then `npx grunt copy`. Dev dependencies must be restored afterward with `composer install`. |
| 90 |
- [](package.jsonpackage.json](package.json](package.json) `engines` and `.nvmrc` define the Node version; keep them aligned when troubleshooting. |
| 91 |
- Husky pre-commit runs `lint-staged` with `NODE_OPTIONS=--max-old-space-size=8192` (see [](.husky/pre-commit.husky/pre-commit](.husky/pre-commit](.husky/pre-commit)). |
| 92 |
|