Add a Playground e2e check for the PKCE flow - #19
Draft
roborourke wants to merge 4 commits into
Draft
roborourke wants to merge 4 commits into
roborourke wants to merge 4 commits into
Conversation
The PHPUnit tests call the grant types and token endpoint directly, so they never cover a real browser-style round trip: cookie login, the consent form and its nonce, the redirect back to the client, the token exchange over HTTP, and using the token on the REST API. This adds a harness that does exactly that against WordPress Playground. tests/e2e/run.sh starts Playground with the plugin mounted and a blueprint that activates it and creates two clients, one with PKCE required and one without. setup.php writes their IDs to a JSON file in the web root so the checks can read them over HTTP. pkce.py then runs 23 checks: the S256 happy path end to end, wrong, missing and URL-only verifiers, code reuse and cross-client redemption, the downgrade case of a verifier sent for a non-PKCE code, malformed authorize parameters, the implicit grant refusal, and cancel on the consent screen. pkce.py uses only the Python standard library, so the CI job needs nothing beyond the Node and Python that ubuntu-latest already ships. Playwright was the other option, but none of these checks need a browser engine, and plain HTTP lets every redirect be inspected without following it. run.sh waits for Playground's "Ready!" log line as well as the clients file. Playground answers some requests while it is still booting, so polling the file alone let the checks start against a server that then stopped responding. The code-reuse checks accept 400 or 404, since an unknown code is currently a 404 and WP-API#89 changes it to the 400 that RFC 6749 expects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first version mixed a bash script, a Python script, a PHP setup file and a JSON blueprint, with its own pass/fail bookkeeping. Playwright Test gives a real test runner instead: named tests, per-test failure reports, and the usual CLI filters. It is also the approach the Playground handbook documents for plugin e2e tests. The spec starts Playground in beforeAll through runCLI() from @wp-playground/cli, with the plugin mounted and activated by an inline blueprint. The OAuth clients are created with playground.run(), which returns the PHP output directly. That removes setup.php and the client-ID JSON file that had to be served from the web root. All requests go through Playwright's APIRequestContext with maxRedirects: 0, so every Location header is still checked. One context holds the logged-in user's cookies and a second, empty one acts as the OAuth client at the token endpoint. The specs never drive a page, so CI skips "playwright install" and needs only npm ci. The tests do not depend on each other, so they are not in serial mode. With one worker, a failure starts a fresh worker and Playground, and the remaining tests still run and report. Serial mode skipped everything after the first failure. The wait-for-"Ready!" workaround in run.sh is gone: runCLI() resolves only once the server and blueprint are done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each test now has a docblock naming the RFC rule it checks, with a @see link to that section, matching the PHPUnit tests. The test that sends the verifier in a JSON body and the optional-client test without PKCE have none, since they check plugin behaviour rather than an RFC rule. Two tests are added to match gaps found in the PHPUnit suite: - RFC 7636 section 4.6: sending the S256 challenge itself as the verifier is refused with invalid_grant. - RFC 6749 section 4.1.2.1: a PKCE error on a request with an unregistered redirect_uri shows an error page and sends no Location header. Moving the PKCE check ahead of the redirect URI check makes this test fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds end-to-end tests that run the PKCE flow over real HTTP against WordPress Playground.
It is based on the PKCE branch from WP-API#85, so the diff only shows the e2e work. Once WP-API#85 merges, this needs a new PR against WP-API/OAuth2
main.The tests use Playwright Test.
tests/e2e/pkce.spec.tsstarts Playground withrunCLI(), mounts the plugin and creates two clients: one that requires PKCE and one that does not. The tests then log in with a password, submit the consent form, exchange the code for a token, and call/wp/v2/users/mewith the token. They use Playwright's request API and never follow redirects, so they check every redirect target.There are 22 tests. They cover the S256 flow from start to finish, wrong, missing and URL-only verifiers, the challenge sent as the verifier, code reuse, and a verifier sent for a code without PKCE. They also cover bad authorize parameters, an unregistered redirect URI, the implicit grant refusal and the cancel button. Each test links to the RFC section it checks.
The tests do not open a browser, so no browser install is needed. Run them with
npm ciand thennpm run test:e2e. A newE2E (Playground)job runs them in CI.🤖 Generated with Claude Code