5.6 KiB
id, title, status, wave, depends_on, plan, spec
| id | title | status | wave | depends_on | plan | spec | |
|---|---|---|---|---|---|---|---|
| 09-e2e-coverage | E2E coverage | done | 5 |
|
plan.md | ../../specs/ui/requirements/agent-todo-list-panel.md |
Task 09: E2E coverage
Extend apps/web/e2e/tests/settings/todo-list-panel.spec.ts with the
Iteration 2 user-facing scenarios: sub-option visibility/inhibition with
state preservation, and the only-pin-when-not-empty runtime behavior against
both an empty-todo session and a session whose todos are already persisted in
message history.
- Acceptance:
- New E2E tests cover: sub-option switch absent with the main preference
off; visible after turning the main preference on; hidden again after
turning it off; previously saved
truevalue survives a page reload and shows checked when the main preference is re-enabled. - Runtime tests cover: main on + sub-option on + task with no todos →
no Todos tab; main on + sub-option on + task with persisted todos
(
e2e:planscript) → Todos tab auto-pinned. - The full spec file passes:
pnpm exec playwright test e2e/tests/settings/todo-list-panel.spec.ts(expect 6/6 with the 4 existing + 2 new tests, or the exact count reported).
- New E2E tests cover: sub-option switch absent with the main preference
off; visible after turning the main preference on; hidden again after
turning it off; previously saved
- Verification:
cd apps/web && pnpm exec playwright test e2e/tests/settings/todo-list-panel.spec.ts(requires the e2e backend harness; run via the repo's documented e2e flow fromapps/web/e2e/README.md). - Files likely touched:
apps/web/e2e/tests/settings/todo-list-panel.spec.tsapps/web/e2e/helpers/api-client.ts(only if Task 07 did not already add theshow_todo_list_panel_only_when_not_emptyresponse type)
- Dependencies: Task 08 (runtime behavior exists), Task 07 (settings UI exists).
- Parallelism:
sequential(E2E follows the frontend changes it covers). - Inputs: Spec Scenarios section
(
docs/specs/ui/requirements/agent-todo-list-panel.md); the existingtodo-list-panel.spec.tshelpers (createTaskWithSession,createTaskWithTodos,setTodoListPanelPreference,readTodosLayout,todosTabWrapper) as the base; the settings-page switch locator patterngetByRole("switch", { name: ... }).
Implementation notes:
- Settings-page test flow (reuse the existing second-tab pattern from the
"adds then removes the tab live" test, or a fresh page to
/settings/general/task-actions):- Assert the sub-option switch is absent while the main toggle is off.
- Click the main toggle ("Show agent todo list panel") → sub-option
appears; toggle it on; save; assert
apiClient.getUserSettings()reportsshow_todo_list_panel_only_when_not_empty: true. - Toggle the main preference off; save; assert the sub-option switch is
absent on the live page AND the persisted settings still report the
sub-option
true. - Reload the settings page; toggle the main preference on; assert the sub-option switch appears already checked (state preserved).
- Runtime tests:
- "does not pin for an empty todo list": set both preferences true via
rawRequest("PATCH", "/api/v1/user/settings", { show_todo_list_panel: true, show_todo_list_panel_only_when_not_empty: true }), open a task fromcreateTaskWithSession(no todos), asserttodosTabWrappercount 0 andreadTodosLayoutreportstodosExists: false(poll 15s). - "pins when the todo list is not empty": same preferences, open a task
from
createTaskWithTodos(persistede2e:planentries), asserttodosTabWrappervisible andtodosExists: truebeside Files/Changes.
- "does not pin for an empty todo list": set both preferences true via
- Keep
test.beforeEach/afterEachbaseline restore behavior correct for the new field: capture and restoreshow_todo_list_panel_only_when_not_emptyalongsideshow_todo_list_panel.
Results
Added three tests to apps/web/e2e/tests/settings/todo-list-panel.spec.ts:
- "inhibits the only-pin-when-not-empty sub-option while the main preference
is off, preserving its value" — settings page: sub-option absent with main
off; appears when main on; persists
show_todo_list_panel_only_when_not_empty: truevia API; hidden (inhibited) when main turned off while the saved value survives; survives a page reload; reappears checked when main is re-enabled. - "does not auto-pin the Todos tab for an empty todo list when
only-pin-when-not-empty is on" — both prefs true + task with no todos →
todosExists: falsebeside Files/Changes. - "auto-pins the Todos tab when the todo list is not empty and
only-pin-when-not-empty is on" — both prefs true + task with persisted
e2e:plantodos → tab pinned beside Files/Changes.
Also extended setTodoListPanelPreference helpers (new
setOnlyPinWhenNotEmptyPreference) and beforeEach/afterEach baseline
capture/restore for the new field.
Command:
cd apps/web && pnpm e2e:raw --project=chromium tests/settings/todo-list-panel.spec.ts
First run: 1 passed, 7 failed — every task-workbench test (including the
pre-existing v1 ones) hit "This page couldn't load." Trace inspection
(0-trace.trace) showed Minified React error #185 (maximum update depth
exceeded) in the desktop layout render. Root cause: my
useSyncTodoPanel selector state.sessionTodos.bySessionId[sessionId] ?? []
returned a fresh [] on every read, so zustand re-rendered infinitely.
Fixed by returning the stable stored array or undefined
((liveTodos?.length ?? 0) > 0), reran sync unit tests (23 passed) +
typecheck, rebuilt web (make build-web), and re-ran the spec.
Second run: 8 passed (1.3m) — all 5 v1 tests + 3 new tests green.
Prereqs built for the run: make -C apps/backend build, make -C apps/backend e2e-plugin-package, make build-web.
Blockers/risks: none.