E2E: fix brittle Anvil wallet-writes ETH test (stale selectors + parallel workers)
## Summary
`bash scripts/e2e-anvil.sh` can fail on **`frontend/e2e/anvil-wallet-writes.spec.ts`** — **“TimeCurve ETH route: quote, swap, and buy”** — even when unrelated frontend changes are fine. Two separate problems show up in practice.
## Findings
### 1. Stale selector vs current Simple UI
The spec waits for:
```ts
buyPanel.locator('input[name="timecurve-pay-with"][value="eth"]')
```
**TimeCurve Simple** chooses pay mode (CL8Y / ETH / USDM) with **toggle buttons** (e.g. `.timecurve-simple__rate-paywith-btn`), `aria-pressed`, and `aria-label` like “Show price in ETH” — not `<input type="radio" name="timecurve-pay-with">`. So the locator can **never resolve**, and the test hits the **180s timeout** waiting for a non-existent control.
**Evidence:** `frontend/src/pages/TimeCurveSimplePage.tsx` (`rateBoardPayOptions` — `button` elements per asset).
### 2. Parallel workers vs one Anvil
With **`ANVIL_E2E=1`**, `frontend/playwright.config.ts` uses **multiple workers** (`workers: 5` when `CI` or `ANVIL_E2E` is set). `scripts/e2e-anvil.sh` starts **one** Anvil + one preview server, then runs **`e2e/anvil-*.spec.ts`** across workers **in parallel**.
Different files (`anvil-referrals.spec.ts`, `anvil-wallet-writes.spec.ts`, etc.) share the **same chain and default mock account**. Even where a file uses `test.describe.configure({ mode: "serial" })`, that only serializes **within** that file — not **across** files. That creates **race risk** (nonces, sale state, registration state) unrelated to the feature under test.
## Acceptance criteria
- [ ] **ETH route test** targets the **actual** TimeCurve Simple pay-mode UI (e.g. role/name within the buy panel, or a dedicated `data-testid` agreed in code + spec). The step that selects **ETH** must not depend on removed `input[name="timecurve-pay-with"]` unless that markup is deliberately reintroduced.
- [ ] **`bash scripts/e2e-anvil.sh`** completes green **reliably** with the default worker policy (either by fixing isolation, or by documenting and implementing a supported mode: e.g. `--workers=1` for Anvil in the script, `fullyParallel: false` for `anvil-*` only, or global setup that serializes Anvil mutating tests).
- [ ] **`docs/testing/e2e-anvil.md`** (or `docs/testing/strategy.md` / Playwright config comment) briefly states **why** Anvil E2E concurrency is limited the chosen way, so future agents do not reintroduce parallel races.
## Related
- Playwright config: `frontend/playwright.config.ts` (`workers` when `ANVIL_E2E=1`).
- Anvil entrypoint: `scripts/e2e-anvil.sh`.
issue