The 94 existing PHPUnit tests all dispatch in-process (WP_REST_Server::dispatch()) or call PHP directly. Nothing exercises a real browser: not the login/consent redirect flow, not wp_redirect() to the client, not bearer auth over real HTTP. That's exactly where interception and CSRF bugs live, and where PKCE (#1) needs to be proven end to end.
Proposed environment: WordPress Playground, not wp-env — no Docker, boots in seconds, blueprint-defined so CI and local match, and gives shareable PR preview links. It suits this plugin (post meta and user meta only, no custom tables, so SQLite is fine). wp-env stays the fallback if we hit something Playground can't do (real MySQL semantics, multisite, or a PHP version it doesn't ship) — the existing PHPUnit matrix already covers PHP/WP versions and multisite, so Playground doesn't need to.
Shape of the work:
package.json with @playwright/test and @wp-playground/cli; playwright.config.ts.
tests/e2e/blueprint.json — mount and activate the plugin, pretty permalinks, an admin and a subscriber user.
- A small test mu-plugin serving the OAuth2 client callback from inside Playground, so redirects land on an assertable local URL and the suite runs offline.
- Specs for the real flows: register/approve a client through the admin UI; full authorization_code + PKCE S256 through login and consent, then use the token; client_credentials; implicit; personal access tokens created and revoked from the profile page.
- A security-tagged spec for cases that must keep failing: wrong/missing PKCE verifier,
plain against a PKCE-required client, unsupported/wrongly-cased method, code replay, expired code, cross-client code use, redirect_uri mismatch, unapproved client, revoked token, bad consent nonce, implicit grant against a PKCE-required client, state round-tripped unchanged.
- An
e2e job in .github/workflows/tests.yml, with traces/HTML report as artifacts on failure.
- A PR-preview comment with a Playground blueprint link.
CONTRIBUTING.md covering how to run each test layer (currently only discoverable from the CI workflow or the PHPUnit bootstrap's error message), and a composer test script.
The 94 existing PHPUnit tests all dispatch in-process (
WP_REST_Server::dispatch()) or call PHP directly. Nothing exercises a real browser: not the login/consent redirect flow, notwp_redirect()to the client, not bearer auth over real HTTP. That's exactly where interception and CSRF bugs live, and where PKCE (#1) needs to be proven end to end.Proposed environment: WordPress Playground, not wp-env — no Docker, boots in seconds, blueprint-defined so CI and local match, and gives shareable PR preview links. It suits this plugin (post meta and user meta only, no custom tables, so SQLite is fine). wp-env stays the fallback if we hit something Playground can't do (real MySQL semantics, multisite, or a PHP version it doesn't ship) — the existing PHPUnit matrix already covers PHP/WP versions and multisite, so Playground doesn't need to.
Shape of the work:
package.jsonwith@playwright/testand@wp-playground/cli;playwright.config.ts.tests/e2e/blueprint.json— mount and activate the plugin, pretty permalinks, an admin and a subscriber user.plainagainst a PKCE-required client, unsupported/wrongly-cased method, code replay, expired code, cross-client code use,redirect_urimismatch, unapproved client, revoked token, bad consent nonce, implicit grant against a PKCE-required client,stateround-tripped unchanged.e2ejob in.github/workflows/tests.yml, with traces/HTML report as artifacts on failure.CONTRIBUTING.mdcovering how to run each test layer (currently only discoverable from the CI workflow or the PHPUnit bootstrap's error message), and acomposer testscript.