mobile.spec.js's card-dialog test needs a tagged card it never creates #125

Closed
opened 2026-08-19 17:41:13 +00:00 by claude-bot · 3 comments
Collaborator

tests/e2e/mobile.spec.jsthe card dialog fills the phone, and only its pickable chips are targets opens with

await page.waitForSelector('.card .tag-chip-static', { timeout: 10000 });

Nothing in the file creates a card, a tag, or the link between them — the assertion depends on the dev stack already holding a card that wears a tag. On a stack brought up with down -v (or any stack whose hand-made content the suite's teardown has since reclaimed — teardown deletes what was created after the run mark, and on a brand-new stack that is everything) the selector never resolves and the test fails on the waitForSelector, ten seconds before it asserts anything it is actually about.

Seen on a freshly recreated docker-compose.yml + docker-compose.test.yml stack: Tags and CardTags were both empty, so the two chip measurements (a static chip on a card must stay small, a picker chip must keep its 44px target) were never taken.

The fixture rule in docs/testing.md says a test that needs a card creates its own, because teardown can only remove rows. This one needs a tag as well — filter.spec.js already mints tags and reclaims them by the id high-water mark taken in global-setup.js, so the machinery exists to copy.

Worth deciding at the same time whether the phone suite should be runnable against an empty stack at all, since that is the state a --force-recreate after a code change leaves behind.


Filed by Claude while working on #112 (run).

`tests/e2e/mobile.spec.js` → *the card dialog fills the phone, and only its pickable chips are targets* opens with ```js await page.waitForSelector('.card .tag-chip-static', { timeout: 10000 }); ``` Nothing in the file creates a card, a tag, or the link between them — the assertion depends on the dev stack already holding a card that wears a tag. On a stack brought up with `down -v` (or any stack whose hand-made content the suite's teardown has since reclaimed — teardown deletes what was created after the run mark, and on a brand-new stack that is everything) the selector never resolves and the test fails on the `waitForSelector`, ten seconds before it asserts anything it is actually about. Seen on a freshly recreated `docker-compose.yml + docker-compose.test.yml` stack: `Tags` and `CardTags` were both empty, so the two chip measurements (a static chip on a card must stay small, a picker chip must keep its 44px target) were never taken. The fixture rule in [`docs/testing.md`](docs/testing.md) says a test that needs a card creates its own, because teardown can only remove rows. This one needs a tag as well — `filter.spec.js` already mints tags and reclaims them by the id high-water mark taken in `global-setup.js`, so the machinery exists to copy. Worth deciding at the same time whether the phone suite should be runnable against an empty stack at all, since that is the state a `--force-recreate` after a code change leaves behind. --- _Filed by Claude while working on #112 ([run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/302))._
Author
Collaborator

🤖 On it — follow along in the action run; the reply will link the full session transcript.

📜 Live transcript — updating every ~5 minutes while the task runs.

🤖 On it — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/342); the reply will link the full session transcript. <!-- claude-run:comment --> 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/issue-125/run-342.md) — updating every ~5 minutes while the task runs.
Author
Collaborator

🤖 On it — follow along in the action run; the reply will link the full session transcript.

📜 Live transcript — updating every ~5 minutes while the task runs.

🤖 On it — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/342); the reply will link the full session transcript. <!-- claude-run:comment --> 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/issue-125/run-342.md) — updating every ~5 minutes while the task runs.
Author
Collaborator

Pushed claude/issue-125.

What was wrong

Confirmed on a stack brought up fresh (up --build --force-recreate on an empty volume — Tags, CardTags and Cards all at 0, three seeded columns, one board). The unmodified test fails exactly as reported:

TimeoutError: page.waitForSelector: Timeout 10000ms exceeded.
  waiting for locator('.card .tag-chip-static') to be visible
  > 147 |     await page.waitForSelector('.card .tag-chip-static', { timeout: 10000 });

What I changed

tests/e2e/mobile.spec.js

  • Added a createTag helper — the same /admin/tags route filter.spec.js uses, so the tag is reclaimed by the PONENTE_RUN_START_TAG_ID high-water mark global-setup.js already takes. It confirms the write by row count rather than by matching the row: Blazor sets those inputs' values as a DOM property, so there is nothing there to select on.
  • addCard takes an optional tag name and clicks it in the composer's picker (and switched the title selector to .composer-title, matching the rest of the suite).
  • The card-dialog test now mints Phone <stamp> and a card wearing it, then measures that card's static chip and that tag's picker chip — not .first(), which on a board with other tags would measure somebody else's and on an empty one measures nothing.

The second question the issue raised — should the phone suite run against an empty stack at all — yes, and one more test was quietly failing that bar. The touch-drag test needs the first column to overflow and did test.skip when it didn't, so on a recreated stack the only test that exercises the interop's reimplemented scroll never ran (I saw it skip). It now adds filler cards until the column scrolls, then its own card last (new cards land at the bottom, which is where the gesture starts), and expects the overflow instead of skipping. On a board that already has cards the loop mints none — verified: with six cards pre-existing, teardown reported the run removing 3 cards, i.e. the drag test added only its own.

docs/testing.md gains the rule next to the teardown one: a spec has to pass against a stack with nothing on it, because --force-recreate and down -v are how these are normally run; "the board already has one" is never a fixture, and a test.skip on an empty board is a test that never runs.

Verified

  • npx playwright test mobile.spec.js against a genuinely empty stack: 7 passed, 0 skipped (was 6 passed / 1 skipped, plus the card-dialog failure before the fix).
  • Same file against a board pre-filled with six cards: 7 passed, three consecutive runs.
  • dotnet test Ponente.sln: 380 passed (includes DocumentationTests).
  • Teardown reported removed 3 card(s), 1 tag(s) after each run — the new fixtures reclaim cleanly and leave nothing on the board.

One unrelated flake appeared in a single full-file run (Tablet (768px) › two columns fit); it passed on immediate re-run and in three subsequent full runs. That is the prerender race docs/testing.md already documents as why the e2e suite isn't wired into CI, in a test I didn't touch — not enough signal to file. The test stack I brought up on the runner host was torn down with down -v.

No changelog entry: this is test and docs only, nothing a member would notice.


⏱ 8m 16s · 50 turns · tokens: 81.7k in / 24.6k out (+3202.1k cache-read)
📜 Full session transcript
→ Opened PR: #139

Pushed `claude/issue-125`. ## What was wrong Confirmed on a stack brought up fresh (`up --build --force-recreate` on an empty volume — `Tags`, `CardTags` and `Cards` all at 0, three seeded columns, one board). The unmodified test fails exactly as reported: ``` TimeoutError: page.waitForSelector: Timeout 10000ms exceeded. waiting for locator('.card .tag-chip-static') to be visible > 147 | await page.waitForSelector('.card .tag-chip-static', { timeout: 10000 }); ``` ## What I changed **`tests/e2e/mobile.spec.js`** - Added a `createTag` helper — the same `/admin/tags` route `filter.spec.js` uses, so the tag is reclaimed by the `PONENTE_RUN_START_TAG_ID` high-water mark `global-setup.js` already takes. It confirms the write by row count rather than by matching the row: Blazor sets those inputs' values as a DOM property, so there is nothing there to select on. - `addCard` takes an optional tag name and clicks it in the composer's picker (and switched the title selector to `.composer-title`, matching the rest of the suite). - The card-dialog test now mints `Phone <stamp>` and a card wearing it, then measures *that* card's static chip and *that* tag's picker chip — not `.first()`, which on a board with other tags would measure somebody else's and on an empty one measures nothing. **The second question the issue raised — should the phone suite run against an empty stack at all — yes, and one more test was quietly failing that bar.** The touch-drag test needs the first column to overflow and did `test.skip` when it didn't, so on a recreated stack the only test that exercises the interop's reimplemented scroll never ran (I saw it skip). It now adds filler cards until the column scrolls, then its own card last (new cards land at the bottom, which is where the gesture starts), and `expect`s the overflow instead of skipping. On a board that already has cards the loop mints none — verified: with six cards pre-existing, teardown reported the run removing 3 cards, i.e. the drag test added only its own. **`docs/testing.md`** gains the rule next to the teardown one: a spec has to pass against a stack with nothing on it, because `--force-recreate` and `down -v` are how these are normally run; "the board already has one" is never a fixture, and a `test.skip` on an empty board is a test that never runs. ## Verified - `npx playwright test mobile.spec.js` against a genuinely empty stack: **7 passed, 0 skipped** (was 6 passed / 1 skipped, plus the card-dialog failure before the fix). - Same file against a board pre-filled with six cards: 7 passed, three consecutive runs. - `dotnet test Ponente.sln`: **380 passed** (includes `DocumentationTests`). - Teardown reported `removed 3 card(s), 1 tag(s)` after each run — the new fixtures reclaim cleanly and leave nothing on the board. One unrelated flake appeared in a single full-file run (`Tablet (768px) › two columns fit`); it passed on immediate re-run and in three subsequent full runs. That is the prerender race `docs/testing.md` already documents as why the e2e suite isn't wired into CI, in a test I didn't touch — not enough signal to file. The test stack I brought up on the runner host was torn down with `down -v`. No changelog entry: this is test and docs only, nothing a member would notice. --- ⏱ 8m 16s · 50 turns · tokens: 81.7k in / 24.6k out (+3202.1k cache-read) 📜 [Full session transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/issue-125/run-342.md) → Opened PR: https://git.grandiras.net/Grandiras/Ponente/pulls/139
Sign in to join this conversation.
No labels
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
Grandiras/Ponente#125
No description provided.