Repository navigation
Run the e2e suite against the containers, as a second mode - #13
Merged
Merged
Conversation
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.
e2e-tests/drives a real browser through the payment against every example. Until now it startedeach app natively, which is why it needs nine toolchains installed and why
dotnet-aspnetcore-jsis
onRequestOnly— a missing SDK is a hard failure, not a skip.docker-compose.ymlalready builds and runs all nine behind one nginx. This adds a second way torun the same specs against those containers, so checking an example locally needs Docker and
nothing else. The native mode is untouched.
The constraint that shapes it
API_URLandSDK_URLmust name one origin — every app builds its CSP fromSDK_URLand thecard fields are iframes from that host. And the emulator does not read the request's
Host: itrebuilds the signed URL from its own
EMULATOR_ORIGIN, so a signature verifies only if the appsigned the very same string.
One address therefore has to be true in three places at once: what the app signs, what the
emulator computes, and what the browser can reach. The shared network namespace the compose file
already uses gives that for free provided the published port equals the internal one.
127.0.0.1:4020127.0.0.1:4020127.0.0.1:4010127.0.0.1:4010The emulator stays on its own port rather than behind the same nginx: the cross-origin boundary is
what
checkout.spec.ts's field-state test and everyframe-srcrule exist to exercise.The three commits
feat(docker): make the nginx port one variable—docker/nginx/nginx.confbecomesdefault.conf.templatewithlisten ${NGINX_PORT};, and oneHTTP_PORTnow drives the publishedport, the internal listen port and
PUBLIC_URL, so the three can no longer disagree. The ninemounted snippets are not templates and keep their
$hostand$proxy_add_x_forwarded_forintact.test(e2e): run the suite against the containers as a second mode— a newdocker-compose.e2e.ymlread on top of the base file, so the nine services and the nine mounteddeploy/nginx.confare reused rather than restated. It adds anemulatorservice (plainnode:22, no Dockerfile, because it imports nothing but Node builtins), publishes 4020/4010, givesevery app the e2e settings through
environment:and re-points the key mount ate2e-tests/.tmp/private_key.pem. It carries its own project name, so a demo stack already up isleft alone; the base file's
env_fileis dropped, so a root.envwith real credentials cannotreach a test run.
On the suite side the whole one-app-per-port assumption lived in
appOrigin().E2E_TARGET=dockerswitches it to the nginx origin, and no spec or fixture needed an edit. The stack comes up as
Playwright's
webServerand goes down in aglobalTeardownwhatever happened.docs: document the two ways to run the e2e suite—e2e-tests/README.md, the rootREADME.mdandCLAUDE.md.Verified locally
threeds.spec.tspassing is the same-origin argument holding up end to end: the ACS page isfetched from
127.0.0.1:4010, posts the signed return toPUBLIC_URLon127.0.0.1:4020, andwaitForURLmatches — alocalhost/127.0.0.1slip anywhere would fail exactly there.result-signature.spec.tspassing means the app signed the same origin string the emulatorcomputed.
Afterwards the stack was gone, 4010/4020 were free, and
docker compose up -d --force-recreateonthe demo still served all nine through the templated nginx.
No CI change — the suite is local-only, as before.