test(playwright): stabilize flaky full-flow E2E — root-cause 3 races (ClickUp 86caj0zzq)#130
Merged
Merged
Conversation
…Up 86caj0zzq) Make the full-flow browser suite a reliable gate by replacing timing-fragile waits/setup with condition-based waits on the real signals. No app-code changes. - Step 13 (async settlement): replace fixed waitForTimeout(5000) + single-shot fetchCompletedInboundStroops read with a bounded expect.poll on the real projection (>0, 150s/2s). /pay/instant/execute writes the merchant's IN/COMPLETED row only after on-chain settlement, well after Step 12's mid-flight POS status — the old read raced it. - Step 5 (nav handoff): Step 4's Next registers the PP then navigates to /setup/join; wait for the join view's #council-url to render instead of a flaky networkidle, so Step 5 starts deterministically on the join view rather than racing the in-flight nav onto the fragile /home fallback. - Step 4 (fee-payer funding): fund the PP root account (bundle fee-payer) with 500 XLM instead of 10. provider-platform's pre-flight requires the fee-payer hold >= NETWORK_FEE (100 XLM); 10 XLM deterministically failed every bundle with InsufficientFees (masked before by the old loose Step 13 assertion). The green e2e/pos-instant suites fund the PP via friendbot (~10k XLM). Verified: 10/10 consecutive green runs of ./test.sh playwright, 0 flakes.
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.
What
Stabilize the flaky
full-flowPlaywright browser E2E (playwright/tests/full-flow.spec.ts) so it's a reliable gate. The flakes moved between steps per run (observed 13, 5, 12); each is root-caused to a specific race/setup bug and replaced with a condition-based wait on the real signal. No app/product code changes — the diff is the spec only, plus a harness version bump.ClickUp
86caj0zzq.Race inventory + fixes
Step 13 — async settlement read race. The POS
#pay-instant-btncalls/pay/instant/execute, which writes the merchant'sIN/COMPLETEDtransaction row only after the bundle settles on chain (provider-platform executor 5s + verifier 10s ticks; the endpoint polls up to 120s). Step 12 returns in ~5s because it reads#pos-statusmid-flight ("Processing payment…", non-error) — it never waits for settlement. The old Step 13 did a fixedwaitForTimeout(5000)+ a single-shotfetchCompletedInboundStroopsread, which raced the projection and saw 0 stroops.→ Replaced with a bounded
expect.poll(fetchCompletedInboundStroops › 0)(150s timeout / 2s interval — just above the endpoint's own 120s cap). UI smoke made condition-based (expect(#balance-display,#tx-list).toBeVisible).Step 5 — post-Step-4 navigation handoff race. Step 4's "Next" runs
registerPp(network) thennavigate("/setup/join"). Step 4 ended on a flakywaitForLoadState("networkidle"), which can resolve mid-navigation; under load the nav outran Step 5's 5sisVisiblecheck, so Step 5 fell back to the fragile/homepath (listPps()→badge→modal#jc-urlasync chain) and timed out. Trace confirmed the provider page went/setup/fund → /setup/join → /home; DB confirmed registration succeeded (pure nav-timing).→ Step 4 now waits for the join view's
#council-urlto render (the real post-condition), so Step 5 deterministically starts on the join view.Step 4 — under-funded bundle fee-payer (deterministic, was masked). The PP root account is the fee-payer for every bundle (
executor.process.ts:feePayerPubkey = ppPublicKey). provider-platform's pre-flight requires the fee-payer to hold ≥NETWORK_FEE(1_000_000_000 stroops = 100 XLM, canonical across all docker suites) + resource fee after reserves. Step 4 funded it with only 10 XLM, so every bundle terminal-FAILed withInsufficient fees on fee-payer accountand the payment never settled — previously hidden by Step 13's old loose UI-text assertion. The greene2e/pos-instantsuites fund the PP via friendbot (~10k XLM).→ Step 4 funds the PP with 500 XLM (well above the 100 XLM floor).
NETWORK_FEEleft canonical; no product/config change.No masking
No
test.retries,test.skip/quarantine,.only, or blankettimeout:inflation used as the fix — grep-clean. Each fix waits on an actual condition/signal.Stability evidence
./test.sh playwrightrun 10/10 consecutive green, 0 flakes (each ~6.3–6.9m, all 16/16 including Steps 13b + 14 which were previously blocked by the Step 13 failure).Notes
playwright/tests/full-flow.spec.tsonly +playwright/package.jsonversion bump (0.1.0 → 0.1.1). No app-code files touched.deno fmt/deno lintdon't apply toplaywright/(Node/Playwright TS project, extensionless imports, excluded from thefmt-lintCI matrix); the suite is compiled by Playwright's own tooling.