Test: anvil-wallet-writes ETH route test races against re-quote after slider change (#41 follow-up) #52

Closed
opened 2026-04-23 05:50:48 +00:00 by Brouie · 5 comments
Brouie commented 2026-04-23 05:50:48 +00:00 (Migrated from gitlab.com)

Finding from #41 Kumbaya E2E verification session (4/23).

Summary

frontend/e2e/anvil-wallet-writes.spec.ts test TimeCurve ETH route: quote, swap, and buy times out with Buy button disabled, because the slider-change step re-triggers a quote and the click happens before the new quote resolves.

Confirmed feature is correct; test needs a post-slider-change wait.

Test output excerpt

locator resolved to <button disabled tabindex="0" type="button" class="btn-primary timecurve-simple__cta">Buy CHARM</button>
attempting click action
335 × retrying click action
  - element is not enabled

Ran bash scripts/e2e-anvil.sh — 3/4 Anvil Playwright tests pass, this one fails.

Root cause analysis

TimeCurveSimplePage.tsx L160-170:

const nonCl8yBlocked =
  session.payWith !== "cl8y" &&
  (session.kumbayaRoutingBlocker !== null ||
    session.swapQuoteFailed ||
    session.quotedPayInWei === undefined ||
    session.swapQuoteLoading);

Test flow:

  1. Wait for Quote: spend text (initial quote succeeds)
  2. Set slider value to 1 + dispatch input/change — triggers useEffect chain that re-fetches quote, sets swapQuoteLoading: true
  3. Click Buy immediately — button still disabled because swapQuoteLoading === true
  4. 180s timeout elapses with button never enabling (probably did enable briefly, but Playwright’s click retry is on stale element ref)

Fix (test-side)

After the slider change, re-wait for Quote: spend (or specifically wait for swapQuoteLoading to clear) before clicking buy. Example:

await buyPanel.locator('input[type="range"]').evaluate(...);
await expect(buyPanel.getByText("Quote: spend")).toBeVisible({ timeout: 60_000 }); // re-wait
await buyPanel.getByRole("button", { name: /buy/i }).click();

CL8Y sibling test doesn’t need this because CL8Y route has no swap quote (path === "0x").

UX observation (not a blocker)

A real user changing the slider then clicking Buy fast may see a briefly-disabled button with no explicit "re-quoting" affordance. Current behavior is safe (prevents buying at stale quote) but could benefit from a subtle loading indicator on the button or a "Refreshing quote…" label to explain why it’s momentarily disabled. Worth considering if this turns out to be a common real-user friction point.

Environment

  • QA server 5.223.69.18, scripts/e2e-anvil.sh on main 92c5a9f
  • Chromium headless, Playwright 180s test timeout
  • Related #41 backend verification (kumbayaRoutes.test.ts 9/9, forge 177/177, on-chain quote math correct) earlier this morning

cc @PlasticDigits

**Finding from #41 Kumbaya E2E verification session (4/23).** ## Summary `frontend/e2e/anvil-wallet-writes.spec.ts` test `TimeCurve ETH route: quote, swap, and buy` times out with Buy button disabled, because the slider-change step re-triggers a quote and the click happens before the new quote resolves. Confirmed feature is correct; test needs a post-slider-change wait. ## Test output excerpt ``` locator resolved to <button disabled tabindex="0" type="button" class="btn-primary timecurve-simple__cta">Buy CHARM</button> attempting click action 335 × retrying click action - element is not enabled ``` Ran `bash scripts/e2e-anvil.sh` — 3/4 Anvil Playwright tests pass, this one fails. ## Root cause analysis `TimeCurveSimplePage.tsx` L160-170: ```ts const nonCl8yBlocked = session.payWith !== "cl8y" && (session.kumbayaRoutingBlocker !== null || session.swapQuoteFailed || session.quotedPayInWei === undefined || session.swapQuoteLoading); ``` Test flow: 1. Wait for `Quote: spend` text (initial quote succeeds) 2. Set slider value to 1 + dispatch input/change — triggers useEffect chain that re-fetches quote, sets `swapQuoteLoading: true` 3. Click Buy immediately — button still disabled because `swapQuoteLoading === true` 4. 180s timeout elapses with button never enabling (probably did enable briefly, but Playwright’s click retry is on stale element ref) ## Fix (test-side) After the slider change, re-wait for `Quote: spend` (or specifically wait for `swapQuoteLoading` to clear) before clicking buy. Example: ```ts await buyPanel.locator('input[type="range"]').evaluate(...); await expect(buyPanel.getByText("Quote: spend")).toBeVisible({ timeout: 60_000 }); // re-wait await buyPanel.getByRole("button", { name: /buy/i }).click(); ``` CL8Y sibling test doesn’t need this because CL8Y route has no swap quote (`path === "0x"`). ## UX observation (not a blocker) A real user changing the slider then clicking Buy fast may see a briefly-disabled button with no explicit "re-quoting" affordance. Current behavior is safe (prevents buying at stale quote) but could benefit from a subtle loading indicator on the button or a "Refreshing quote…" label to explain why it’s momentarily disabled. Worth considering if this turns out to be a common real-user friction point. ## Environment - QA server 5.223.69.18, scripts/e2e-anvil.sh on main `92c5a9f` - Chromium headless, Playwright 180s test timeout - Related #41 backend verification (kumbayaRoutes.test.ts 9/9, forge 177/177, on-chain quote math correct) earlier this morning cc @PlasticDigits
Brouie commented 2026-04-23 05:51:24 +00:00 (Migrated from gitlab.com)

mentioned in issue #41

mentioned in issue #41
Brouie commented 2026-04-23 06:24:53 +00:00 (Migrated from gitlab.com)

mentioned in issue #42

mentioned in issue #42
PlasticDigits commented 2026-04-23 08:04:25 +00:00 (Migrated from gitlab.com)

@Brouie The clicking buy fast is issue with brief disabling and the recommendated refreshign quote label is a good idea. Please open an issue for this ux discovery

@Brouie The clicking buy fast is issue with brief disabling and the recommendated refreshign quote label is a good idea. Please open an issue for this ux discovery
Brouie commented 2026-04-24 02:46:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #56

mentioned in issue #56
Brouie commented 2026-04-24 02:51:46 +00:00 (Migrated from gitlab.com)

@PlasticDigits new issue #56 filed for the 'Refreshing quote…' Buy button label UX, per your request. That covers the re-quote state visibility part of this discovery.

For this issue itself: agreed the test-side race is the right framing — the Playwright anvil-wallet-writes ETH route test was racing against the re-quote after slider change. Dev can close this one now since the follow-up UX improvement is tracked under #56.

Leaving open for your triage decision on whether to close as duplicate-of-#56 or keep open until the Playwright spec is stabilized (could use waitForSelector on a stable quote indicator once #56 lands).

@PlasticDigits new issue #56 filed for the 'Refreshing quote…' Buy button label UX, per your request. That covers the re-quote state visibility part of this discovery. For this issue itself: agreed the test-side race is the right framing — the Playwright anvil-wallet-writes ETH route test was racing against the re-quote after slider change. Dev can close this one now since the follow-up UX improvement is tracked under #56. Leaving open for your triage decision on whether to close as duplicate-of-#56 or keep open until the Playwright spec is stabilized (could use `waitForSelector` on a stable quote indicator once #56 lands).
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-04-24 03:09:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#52
No description provided.