There are two wp-env environments, defined by separate config files:
| Environment | Config file | Port | npm scripts |
|---|---|---|---|
| Development | .wp-env.json |
8888 | npm run env, npm run env:start |
| Tests | .wp-env.tests.json |
8889 | npm run env:tests, npm run env:tests:start |
npm run env:start boots both environments. Use npm run env:tests:start if you only need the tests env (e.g. when developing locally).
To run an arbitrary wp-env command against a specific environment:
# dev (default)
npm run env -- run cli wp option get siteurl
# tests
npm run env:tests run cli wp option get siteurlThe tests environment has BEYONDWORDS_MOCK_API set to true by default in .wp-env.tests.json. To override anything per developer, create a .wp-env.override.json file (for example, using the config section). Restart with npm run env:tests:start after editing.
- Locate some published audio in your BeyondWords dashboard. If you haven't generated any audio yet, then generate your first audio using our TTS editor.
- Make a note of the Project ID and the Content ID for the audio - we need these for the automated PHPUnit and Cypress tests to pass.
- Also make a note of your API Key.
PHPUnit reads test secrets from .wp-env.tests.override.json (gitignored):
cp .wp-env.tests.override.json.example .wp-env.tests.override.jsonCypress reads them from cypress.env.json (also gitignored):
cp cypress.env.json.example cypress.env.jsonEdit both files, providing the API Key, Project ID and Content ID you noted earlier.
If you also want the dev environment to pick up the same constants (e.g. to
hit the BeyondWords API from a local browser session), copy the override into
.wp-env.override.json as well — it's a separate file applied only to the
dev env.
/tests/cypress/
To open the Cypress app:
npm run cypress:openOr to run all tests in terminal (like we do in CI):
npm run cypress:run/tests/phpunit/
Run the test suite (PHPUnit + coverage HTML report + 85% coverage gate):
npm run composer:tests -- testcomposer:tests dispatches into the tests wp-env (port 8889) — see the Environments section above. It does not disturb the dev env.
To view the coverage HTML report:
open tests/phpunit/_report/index.htmlTo run the coverage gate standalone (without re-running the suite):
npm run composer:tests -- test:coverage-check- AJAX handler tests extend
WP_Ajax_UnitTestCase, which pretendsDOING_AJAXis true, routeswp_die()to a handler that captures the JSON body into$this->_last_responseand throws aWPAjaxDie*Exception, and suppresses the "headers already sent" warning. Seetests/phpunit/posts-list/test-bulk-edit-ajax.php.
Hard-won details behind some non-obvious patterns in the Cypress suite:
cy.getEditorCanvasBody()(tests/cypress/support/commands.js) must not introduce a.then( cy.wrap )boundary. Pinning the resolved<body>subject breaks Cypress's retry-ability when the block-editor iframe re-renders during hydration — it fails as "subject is no longer attached to the DOM", seen mostly on slower PHP 8.0 CI runs. Whether the editor canvas is an iframe is stable for a given WordPress version, so it is detected once synchronously viaCypress.$instead.- Stubbing voices in the block editor doesn't work:
cy.intercepton the REST voices route stubs fine in the classic editor, but the block editor'swp.datastore ends up empty. Branches that depend on voice-list contents (e.g. the single-bucket Model/Voice case) are covered by the classic-editor spec plus Jest unit tests instead.