|
3 | 3 | * |
4 | 4 | * Two claims in one cut. The board, scoped to the active sprint, now says |
5 | 5 | * what that sprint is in a line of its own: name, dates, days left, a |
6 | | - * progress bar counted over the whole sprint (GDK-1709), and the cards |
7 | | - * carry how many sprints they have already been through (GDK-1711). Then |
8 | | - * the retro, from the palette: the running bucket summarised above the |
9 | | - * table, a sparkline on every row, the cut switched to sprints, and one |
10 | | - * number clicked open into the issues behind it (GDK-1712, GDK-1693). |
| 6 | + * progress bar counted over the whole sprint (GDK-1709). Then the retro, |
| 7 | + * from the palette: the running bucket summarised above the table, a |
| 8 | + * sparkline on every row, the cut switched to sprints, and one number |
| 9 | + * clicked open into the issues behind it (GDK-1712, GDK-1693). |
| 10 | + * |
| 11 | + * No hover beats. Playwright's recording carries no cursor, so a beat |
| 12 | + * whose whole content is a tooltip records as a still — the first take |
| 13 | + * spent three seconds that way (vision pass, 2026-09-09). The carry-over |
| 14 | + * mark (GDK-1711) is in frame on the cards but not narrated for the same |
| 15 | + * reason. And the board stands on the whole sprint, not the open pool: the |
| 16 | + * strip counts done issues, so a Done column emptied by the open-only view |
| 17 | + * read as a contradiction beside "6 / 20 · 30%". |
11 | 18 | * |
12 | 19 | * No terminal, no CLI, no DOM caption. Gated by GADAK_MEDIA=1. Viewport and |
13 | 20 | * video size must stay 1280×800 (sprint-retro-hero.config.ts) or Playwright |
@@ -54,82 +61,64 @@ test.describe('sprint + retro hero', () => { |
54 | 61 | await expect(page.getByTestId('issue-layout')).toBeVisible({ timeout: 30_000 }) |
55 | 62 | await expect(page.getByTestId('issue-list-scroller')).toBeVisible() |
56 | 63 | await expect(page).toHaveURL(/[#?&]sc=/, { timeout: 30_000 }) |
57 | | - await beat(page, 600) |
58 | | - |
59 | | - // The team's whole open pool, not "My issues" — a sprint board is a |
60 | | - // team surface (same reason as sprint-demo.spec.ts). |
61 | | - await page |
62 | | - .getByRole('button', { name: new RegExp('^' + T['view.allOpen.name']) }) |
63 | | - .first() |
64 | | - .click() |
65 | | - await expect(page.getByTestId('issue-list-scroller')).toBeVisible() |
66 | | - await beat(page, 700) |
| 64 | + await beat(page, 900) |
67 | 65 |
|
68 | | - // Into the board the way a person does. |
69 | | - await page.getByTestId('view-settings').click() |
70 | | - await beat(page, 400) |
71 | | - await page.getByTestId('layout-board').click() |
72 | | - await expect(page.getByTestId('board')).toBeVisible() |
73 | | - await page.keyboard.press('Escape') |
| 66 | + // The whole pool as a board, not "My issues" — a sprint board is a team |
| 67 | + // surface, and the strip counts done issues, so the Done column has to |
| 68 | + // hold them. A built-in view's own filters are not chips (GDK-1336), so |
| 69 | + // there is nothing to clear; the view-less board is a route, and the |
| 70 | + // recording never shows the address bar. |
| 71 | + await page.goto('/#/?ly=board') |
| 72 | + await expect(page.getByTestId('board')).toBeVisible({ timeout: 30_000 }) |
74 | 73 | const scope = page.getByTestId('sprint-scope') |
75 | 74 | await expect(scope).toBeVisible() |
76 | 75 | await expect(scope).toContainText(T['board.scopeAxis']) |
77 | | - await beat(page, 1000) |
| 76 | + await beat(page, 1500) |
78 | 77 |
|
79 | 78 | // Beat 1 — the sprint gets its line. Scope to the active sprint and the |
80 | 79 | // strip stands between the toolbar and the columns: name, dates, days |
81 | | - // left, the bar. |
| 80 | + // left, the bar — and the Done column is full beside it. |
82 | 81 | await page.getByTestId('sprint-scope-active').click() |
83 | 82 | await expect(page).toHaveURL(/sst=active/) |
84 | 83 | const strip = page.getByTestId('sprint-strip') |
85 | 84 | await expect(strip).toBeVisible() |
86 | 85 | await expect(page.getByTestId('sprint-strip-name')).toHaveText(/\S/) |
87 | 86 | await expect(page.getByTestId('sprint-strip-count')).toHaveText(/\d+ \/ \d+ · \d+%/) |
88 | 87 | await expect(page.getByTestId('board-card').first()).toBeVisible() |
89 | | - await beat(page, 1800) |
90 | | - // The bar's basis, on hover (G7) — the cursor rests on it long enough to read. |
91 | | - await page.getByTestId('sprint-strip-bar').hover() |
92 | | - await beat(page, 1500) |
| 88 | + await expect(page.getByTestId('board-card-carryover').first()).toBeVisible() |
| 89 | + await beat(page, 2800) |
93 | 90 |
|
94 | | - // Beat 2 — a card that has been carried. The mark is the last thing on |
95 | | - // the card's meta line; hovering says how many sprints it has sat in. |
96 | | - const carried = page.getByTestId('board-card-carryover').first() |
97 | | - await expect(carried).toBeVisible() |
98 | | - await carried.hover() |
99 | | - await beat(page, 1600) |
100 | | - |
101 | | - // Beat 3 — the retro, from the palette, the way it is reached. |
| 91 | + // Beat 2 — the retro, from the palette, the way it is reached. |
102 | 92 | await page.keyboard.press('ControlOrMeta+k') |
103 | | - await beat(page, 500) |
| 93 | + await beat(page, 1000) |
104 | 94 | await page.getByTestId('palette-action-retro').click() |
105 | 95 | const view = page.getByTestId('retro-view') |
106 | 96 | await expect(view).toBeVisible() |
107 | 97 | await expect(view).toContainText(T['retro.title']) |
108 | 98 | await expect(page.getByTestId('retro-summary')).toBeVisible() |
109 | 99 | await expect(page.getByTestId('retro-table')).toBeVisible() |
110 | 100 | await expect(page.getByTestId('retro-sparkline').first()).toBeVisible() |
111 | | - await beat(page, 2400) |
| 101 | + await beat(page, 1600) |
112 | 102 |
|
113 | | - // Beat 4 — the same report cut by sprint: two named columns, the |
| 103 | + // Beat 3 — the same report cut by sprint: two named columns, the |
114 | 104 | // running one marked, the summary retitled to the sprint. |
115 | 105 | await page.getByTestId('retro-range').filter({ hasText: T['retro.bySprint'] }).click() |
116 | 106 | await expect(page.getByTestId('retro-week')).toHaveCount(2) |
117 | 107 | await expect(page.getByTestId('retro-week').last()).toContainText(T['retro.thisSprint']) |
118 | 108 | await expect(page.getByTestId('retro-summary-title')).toContainText(T['retro.thisSprint']) |
119 | | - await beat(page, 2400) |
| 109 | + await beat(page, 1800) |
120 | 110 |
|
121 | | - // Beat 5 — a number is a door. The closed cell of the running sprint |
122 | | - // opens the issues that closed in it, as a keys view. |
123 | | - const cell = page.locator('[data-testid="retro-cell"][data-metric="closed"]').last() |
| 111 | + // Beat 4 — a number is a door. The in-progress cell of the running |
| 112 | + // sprint opens the issues behind it, as a keys view (the fuller list of |
| 113 | + // the two doors in the demo mirror). |
| 114 | + const cell = page.locator('[data-testid="retro-cell"][data-metric="in progress"]').last() |
124 | 115 | await expect(cell).toBeVisible() |
125 | | - await cell.hover() |
126 | | - await beat(page, 800) |
127 | 116 | await cell.click() |
128 | 117 | await expect(view).toBeHidden() |
129 | 118 | await expect(page.getByTestId('issue-list-scroller')).toBeVisible() |
130 | 119 | await expect.poll(() => page.url()).toContain('ks=') |
131 | 120 | await expect(page.getByTestId('issue-row-trail').first()).toBeVisible() |
132 | | - await beat(page, 2200) |
| 121 | + await beat(page, 1800) |
133 | 122 |
|
134 | 123 | expect(errors.filter((e) => !e.includes('409') && !e.includes('502'))).toEqual([]) |
135 | 124 | }) |
|
0 commit comments