Branch-Aware Playwright Test Rig for an SME Banking Web App
A leading Romanian retail bank
Overview
A standalone Playwright harness for the bank’s SME (small-business) web application. A single CLI (node e2e.mjs) builds any branch of the Angular front end, serves it locally, proxies its API calls either to the bank’s real test environment or to a developer-run mock, and runs the browser specs, without touching the app repository or committing anything into it.
Why It Exists
The app’s test API sits behind corporate SSO with phone-based second-factor approval, so only one machine with an authenticated session can reach it; developers on their own Macs cannot. At the same time, feature branches needed regression checks before merge, and shared test data must never be mutated by accident. The rig solves all three: it reuses one authenticated session transparently, lets the same specs run against a zero-dependency mock on any machine, and gates write operations behind an explicit tag.
What We Built
e2e.mjsCLI withlogin,status,pull,run <branch>,serve,openandcapturescommands.lib/build.mjs:git archive <sha>of the requested branch into a per-sha build cache, dependencies cached per lockfile hash,ng build --configuration productionrun once per commit. A--hubflag builds developer branches not yet on the main remote; on the Mac the app clone’snode_modulesare reused when the lockfile matches (the npm registry is private).lib/server.mjs: local server on:4400that serves the build, rewritesassets/config/env.jsonso the app’s API base path points to/__api, and forwards/__api/*either to the real test API with the stored proxy cookies or to the mock (--mock <url>). The bearer token is seeded intolocalStoragebefore boot, so the SSO login is skipped.lib/session.mjs: gitignored, mode-600 session file (bearer token + proxy cookies), silent refresh while the SSO session is alive, otherwise a headed Edge window for the second-factor approval.tests/fixtures.ts: a pre-logged-inpage,openClient(page, cui), anapi(path)helper that goes through the same proxy, atargetvalue ('test' | 'mock') for conditional skips, and UI helpers for the lead modal, card-acceptance pages, POS terminal configuration, steppers and dropdowns.tests/fixes.json+buildIncludes(sha): the runner decides once, with git, whether each listed fix commit is in the build and passes the verdicts to the specs viaE2E_FIXES; specs for unmerged PRs are markedtest.fail(...)so they stay green on develop and turn real on the PR branch. No git runs inside the test runner.- Seven spec files covering prospect vs. existing-client flows: company name/CUI prefill in the lead modal, sidebar client-type labels, a contract-date modal for POS clients, deep-link buttons on POS and e-commerce summaries (the only
@writesspecs, asserting POST bodies and success toasts), a product-eligibility criteria modal, an offer-validity period on the summary, and a table-driven pass over the known test CUIs checking feed fields. captures/<run>/*.json: every API call of a run (method, path, status, request, response), packable and sent to the developer to make the mock more faithful.
The mock-API sibling repo (related_repos) is a zero-dependency Node server that answers every route the app calls, including a fake identity-provider redirect, and can bundle the whole front end plus mock into a single shareable HTML demo.
Technologies & Approach
Playwright Test with workers: 1, no retries, 90 s test timeout, ro-RO locale, 1600x1000 viewport, screenshot and trace only on failure, list + HTML reporters per run. The browser channel defaults to Microsoft Edge (where the corporate session lives) and switches to bundled Chromium via E2E_CHANNEL=chromium on machines without Edge. Against the test API the runner adds --grep-invert @writes automatically unless @writes is requested explicitly; the mock runs everything. The design keeps the harness fully outside the app repo, caches builds per commit, and treats the authenticated session as a local secret that never leaves the machine.
Outcome / Impact
Gives the team a repeatable way to verify any front-end branch in a real browser against real test data from the one machine that can reach it, while developers run the identical specs against the mock on their own laptops before pushing. Expected-failure specs tied to fix commits let regression coverage be written ahead of the merge. Work is ongoing (five commits in October 2026, each adding specs for a ticket under review).
Capabilities Demonstrated
- Playwright end-to-end testing of an Angular banking app in a real browser
- Per-branch build-serve-test pipeline with per-sha build caching
- Transparent proxying through SSO/2FA-protected corporate reverse proxies with session reuse
- Same test suite running against a real environment or a mock, with target-aware skips
- Safety gating of mutating tests on shared test environments (
@writes) - Fix-commit-aware expected failures for pre-merge regression specs
- API traffic capture to feed and improve a mock backend