test(e2e): consolidate reader + filter-drawer browser journeys (bookshelf-bz643.7) #1394

Merged
zombor merged 1 commit from bd-bookshelf-bz643.7 into main 2026-08-08 15:28:22 +00:00
Owner

Final slice of the bz643 browser e2e budget epic.

Summary

  • Folds journey_read_book_test.go, journey_reader_peripherals_test.go, journey_annotations_test.go, and journey_reset_progress_test.go into a single top-level Ordered journey (journey_reader_test.go) with nested Ordered Describes per flow (mirrors the journey_content_manage_test.go pattern from bz643.5). Dropped 2 pure-selector annotation Its ("renders the panel element" / "renders the Highlights button") — static server-rendered HTML with no Chromium interaction, already covered by Journey-11 in e2e/api/.
  • Folds the 6 journey_filter_drawer_test.go top-level Describes into 1, keeping each sub-journey's own BeforeAll/page/library seeding as a nested Ordered Describe.
  • Folds in the 3 deferred slice-2 review minors:
    • journey_11_reader_html_structure_test.go: makeCBZ panic() -> Expect(werr).NotTo(HaveOccurred())
    • journey_a11y_guardrails_test.go: drop the redundant BeforeEach(refreshPageTimeout) (every It already resets the timeout itself)
    • journey_11: tighten the nav[aria-label] check to scope inside <aside class="sidebar"> rather than matching any <nav> on the page

Final budget check

Browser e2e top-level Describes: 40 -> 32; Its: 203 -> 201.

Full-suite convergence to the ~12/~45 CLAUDE.md budget is not complete after this slice — several files outside bz643.1-.7's named scope (content_restrictions, duplicates, author_edit/author_split, bulk_*, etc.) remain unconsolidated. These were not part of the reader/filter-drawer scope of this bead; flagging for a follow-up bead if further reduction is wanted.

Test plan

  • make e2e-policy-check — green
  • make lint — green (includes e2e-policy-check, test-policy-check, etc.)
  • make test — green
  • go build -tags e2e ./e2e/... — compiles clean

Closes bead bookshelf-bz643.7 on merge.

Final slice of the bz643 browser e2e budget epic. ## Summary - Folds `journey_read_book_test.go`, `journey_reader_peripherals_test.go`, `journey_annotations_test.go`, and `journey_reset_progress_test.go` into a single top-level Ordered journey (`journey_reader_test.go`) with nested Ordered Describes per flow (mirrors the `journey_content_manage_test.go` pattern from bz643.5). Dropped 2 pure-selector annotation Its ("renders the panel element" / "renders the Highlights button") — static server-rendered HTML with no Chromium interaction, already covered by Journey-11 in e2e/api/. - Folds the 6 `journey_filter_drawer_test.go` top-level Describes into 1, keeping each sub-journey's own BeforeAll/page/library seeding as a nested Ordered Describe. - Folds in the 3 deferred slice-2 review minors: - `journey_11_reader_html_structure_test.go`: `makeCBZ` `panic()` -> `Expect(werr).NotTo(HaveOccurred())` - `journey_a11y_guardrails_test.go`: drop the redundant `BeforeEach(refreshPageTimeout)` (every `It` already resets the timeout itself) - `journey_11`: tighten the `nav[aria-label]` check to scope inside `<aside class="sidebar">` rather than matching any `<nav>` on the page ## Final budget check Browser e2e top-level Describes: 40 -> 32; Its: 203 -> 201. Full-suite convergence to the ~12/~45 CLAUDE.md budget is **not** complete after this slice — several files outside bz643.1-.7's named scope (`content_restrictions`, `duplicates`, `author_edit`/`author_split`, `bulk_*`, etc.) remain unconsolidated. These were not part of the reader/filter-drawer scope of this bead; flagging for a follow-up bead if further reduction is wanted. ## Test plan - `make e2e-policy-check` — green - `make lint` — green (includes e2e-policy-check, test-policy-check, etc.) - `make test` — green - `go build -tags e2e ./e2e/...` — compiles clean Closes bead bookshelf-bz643.7 on merge.
test(e2e): consolidate reader + filter-drawer browser journeys (bookshelf-bz643.7)
All checks were successful
/ Test Race (pull_request) Successful in 2m17s
/ Lint (pull_request) Successful in 2m48s
/ E2E API (pull_request) Successful in 1m45s
/ JS Unit Tests (pull_request) Successful in 1m11s
/ Coverage (pull_request) Successful in 2m55s
/ Integration (pull_request) Successful in 3m0s
/ E2E Browser (pull_request) Successful in 4m57s
500c7104b1
Final slice of the bz643 browser e2e budget epic:

- Fold journey_read_book_test.go, journey_reader_peripherals_test.go,
  journey_annotations_test.go, and journey_reset_progress_test.go into a
  single top-level Ordered journey (journey_reader_test.go) with nested
  Ordered Describes per flow, mirroring the journey_content_manage_test.go
  pattern from bz643.5. Dropped 2 pure-selector annotation Its ("renders
  the panel element" / "renders the Highlights button") that assert only
  static server-rendered HTML with no Chromium interaction — already
  covered by Journey-11 in e2e/api/.
- Fold the 6 filter_drawer top-level Describes into 1
  (journey_filter_drawer_test.go), keeping each sub-journey's own
  BeforeAll/page/library seeding as a nested Ordered Describe.
- Fold in the 3 deferred slice-2 review minors:
  - journey_11_reader_html_structure_test.go: makeCBZ panic() ->
    Expect(werr).NotTo(HaveOccurred())
  - journey_a11y_guardrails_test.go: drop the redundant BeforeEach
    refreshPageTimeout (every It already resets the timeout itself)
  - journey_11: tighten the nav[aria-label] check to scope inside
    <aside class="sidebar"> rather than matching any <nav> on the page

Browser e2e top-level Describes: 40 -> 32; Its: 203 -> 201 (this slice's
own scope). Full-suite convergence to the ~12/~45 CLAUDE.md budget is not
complete after this slice — several files outside bz643.1-.7's named scope
(content_restrictions, duplicates, author_edit/split, bulk_*, etc.) remain
unconsolidated; tracked as a follow-up if further reduction is wanted.

make e2e-policy-check, make lint, make test all green.

Closes bead bookshelf-bz643.7 on merge.
Author
Owner

Security review (PR #1394, bookshelf-bz643.7) — adversarial pass over git diff origin/main...origin/bd-bookshelf-bz643.7.

Scope check: confirmed diff touches ONLY e2e/api/*_test.go and e2e/browser/*_test.go (8 files, all under e2e/). No internal/, cmd/, or production code changed.

Dropped-assertion audit: compared each deleted spec file against the new consolidated journey_reader_test.go:

  • journey_annotations_test.go (deleted) → per-user annotation isolation test ("does not show user 2's annotations to user 1") is preserved verbatim in journey_reader_test.go (~line 797).
  • journey_reader_peripherals_test.go (deleted) → per-user bookmark isolation test ("does not show another user's bookmarks") is preserved in journey_reader_test.go (~line 387-427).
  • journey_reset_progress_test.go (deleted) → full kebab-menu → confirm-dialog → DELETE → reload flow folded into journey_reader_test.go "Reset Reading Progress" Describe block (~line 840+); no ownership/security assertions in the original to lose.
  • journey_read_book_test.go (deleted) → no ownership/authz assertions present in the original; content folded into the new journey.

No 403/404 → 200 relaxations found; no status-code assertions were weakened anywhere in the diff.

journey_11_reader_html_structure_test.go: the sidebar nav[aria-label] check was tightened, not weakened — it now scopes the regex match to inside <aside class="sidebar">…</aside> instead of matching anywhere in the page body (previously a page-wide MatchRegexp, now correctly scoped like the original browser e2e selector).

Secrets/tokens: no hardcoded secrets added. CSRF token handling (X-CSRF-Token) is read dynamically from the DOM in both old and new code — this is pre-existing test infra, not a new credential.

No BLOCKER, MAJOR, or MINOR findings.

REVIEW VERDICT: 0 blocker, 0 major, 0 minor

Security review (PR #1394, bookshelf-bz643.7) — adversarial pass over `git diff origin/main...origin/bd-bookshelf-bz643.7`. **Scope check:** confirmed diff touches ONLY `e2e/api/*_test.go` and `e2e/browser/*_test.go` (8 files, all under `e2e/`). No `internal/`, `cmd/`, or production code changed. **Dropped-assertion audit:** compared each deleted spec file against the new consolidated `journey_reader_test.go`: - `journey_annotations_test.go` (deleted) → per-user annotation isolation test ("does not show user 2's annotations to user 1") is preserved verbatim in `journey_reader_test.go` (~line 797). - `journey_reader_peripherals_test.go` (deleted) → per-user bookmark isolation test ("does not show another user's bookmarks") is preserved in `journey_reader_test.go` (~line 387-427). - `journey_reset_progress_test.go` (deleted) → full kebab-menu → confirm-dialog → DELETE → reload flow folded into `journey_reader_test.go` "Reset Reading Progress" `Describe` block (~line 840+); no ownership/security assertions in the original to lose. - `journey_read_book_test.go` (deleted) → no ownership/authz assertions present in the original; content folded into the new journey. No 403/404 → 200 relaxations found; no status-code assertions were weakened anywhere in the diff. **`journey_11_reader_html_structure_test.go`:** the sidebar `nav[aria-label]` check was tightened, not weakened — it now scopes the regex match to inside `<aside class="sidebar">…</aside>` instead of matching anywhere in the page body (previously a page-wide `MatchRegexp`, now correctly scoped like the original browser e2e selector). **Secrets/tokens:** no hardcoded secrets added. CSRF token handling (`X-CSRF-Token`) is read dynamically from the DOM in both old and new code — this is pre-existing test infra, not a new credential. No BLOCKER, MAJOR, or MINOR findings. REVIEW VERDICT: 0 blocker, 0 major, 0 minor
Author
Owner

Code review — bookshelf-bz643.7 (PR #1394)

Reviewed the diff (origin/main...origin/bd-bookshelf-bz643.7), cross-checked every deleted file's It list against the new consolidated journeys, and traced the two claimed "already covered" drops.

Coverage preservation (top risk) — verified clean.

  • journey_read_book_test.go (4 Its) and journey_reader_peripherals_test.go (4 Its) -> all 8 Its survive verbatim (title + body) inside journey_reader_test.go's "Read a Book" / "Reader Peripherals" nested Describes.
  • journey_reset_progress_test.go (4 Its incl. the DB-verified progress reset + flash-message wait) -> all 4 survive verbatim under "Reset Reading Progress".
  • journey_annotations_test.go (7 Its) -> 5 survive verbatim; 2 dropped (see MINOR below). The dropped two ("renders the annotations panel element", "renders the Highlights toolbar button") are pure page.MustHas(selector) static-presence checks with no interaction — correctly droppable in principle since the very next It (page.MustElement(...).MustClick()) would itself fail if either element were absent. Functional coverage is preserved implicitly.
  • journey_filter_drawer_test.go: diff is a mechanical re-indent/nest (6 former top-level Describes -> 6 nested Describes under one top-level wrapper). Expect( count is unchanged (58/58) and a full-hunk read of the first sub-journey confirms pure code motion, no logic change.
  • page.Timeout/refreshPageTimeout gotcha: every nested Describe that reuses a page across Its carries its own BeforeEach(refreshPageTimeout) or in-It refreshPageTimeout call (verified in journey_reader_test.go all 4 sub-journeys and journey_filter_drawer_test.go all 6 sub-journeys). No missing-reset regression found.
  • The 3 deferred minors: makeCBZ panic->Expect conversion in journey_11_reader_html_structure_test.go is correct (closure is invoked from inside an It, so Expect's Gomega fail handler is reachable); the a11y BeforeEach removal is correct — every It in that file already calls refreshPageTimeout as its first statement, confirmed by grep; the nav aria-label scoping to aside.sidebar correctly narrows to mirror the original browser-e2e selector (aside.sidebar nav[aria-label]) instead of a page-wide MatchRegexp, and does not lose coverage.

Policy check. journey_reader_test.go and journey_filter_drawer_test.go each have exactly one top-level var _ = Describe(..., Ordered, ...); all nested Describes are also Ordered. This matches make e2e-policy-check's AST rule (only top-level Describes are checked) and mirrors the precedent already on main in journey_content_manage_test.go / journey_bookdrop_test.go (multiple nested Describe+BeforeAll pairs under one top-level wrapper) — not a novel pattern introduced by this PR.


[MINOR] e2e/browser/journey_reader_test.go:14-17 — stale/incorrect cross-reference in the drop-justification comment
The header comment (and the identical inline comment at line ~719) claims the two dropped annotation selector Its ("renders the annotations panel element", "renders the Highlights toolbar button") are "already covered by Journey-11 in e2e/api/". They are not: git grep -n "annotation" e2e/api/journey_11_reader_html_structure_test.go returns zero matches — that file never asserts .reader-annotations-panel or [data-action*="annotations#togglePanel"] render server-side. Actual coverage is still fine (the very next It in this same file fails fast via MustElement(...).MustClick()/the Eventually panel-open poll if either element is missing), so this is not a coverage-loss finding — but the comment asserts a false fact that a future reader (or a future consolidation pass) will trust at face value. Fix: reword to "implicitly covered by the interaction Its below (click/open would fail if either element were absent)" or actually add a one-line static-HTML assertion for these two selectors to Journey-11 so the comment becomes true.

[MINOR] Budget methodology note (not blocking) — nested-Describe consolidation reduces the reported top-level-Describe count (40->32) without reducing the number of independent BeforeAll/fresh-DB-boot/browser-page-boot units (journey_reader_test.go still boots 4 separate DB resets + browser contexts; journey_filter_drawer_test.go still boots 6). This is consistent with the established epic precedent (journey_content_manage_test.go, journey_bookdrop_test.go on main) so it's not a regression introduced here, but worth flagging for the epic owner: if the real goal of the bz643 budget epic is CI wall-clock/duplication reduction (not just the Describe-count metric in CLAUDE.md), this slice's "Its 203->201" delta shows most of the win here is organizational, not a cost reduction. Consider a follow-up bead to actually merge boot state where sub-journeys are independent, or explicitly note in CLAUDE.md that the Describe-count budget is a readability/policy metric, not a CI-cost proxy.

REVIEW VERDICT: 0 blocker, 0 major, 2 minor

## Code review — bookshelf-bz643.7 (PR #1394) Reviewed the diff (`origin/main...origin/bd-bookshelf-bz643.7`), cross-checked every deleted file's `It` list against the new consolidated journeys, and traced the two claimed "already covered" drops. **Coverage preservation (top risk) — verified clean.** - `journey_read_book_test.go` (4 Its) and `journey_reader_peripherals_test.go` (4 Its) -> all 8 Its survive verbatim (title + body) inside `journey_reader_test.go`'s "Read a Book" / "Reader Peripherals" nested Describes. - `journey_reset_progress_test.go` (4 Its incl. the DB-verified progress reset + flash-message wait) -> all 4 survive verbatim under "Reset Reading Progress". - `journey_annotations_test.go` (7 Its) -> 5 survive verbatim; 2 dropped (see MINOR below). The dropped two ("renders the annotations panel element", "renders the Highlights toolbar button") are pure `page.MustHas(selector)` static-presence checks with no interaction — correctly droppable in principle since the very next It (`page.MustElement(...).MustClick()`) would itself fail if either element were absent. Functional coverage is preserved implicitly. - `journey_filter_drawer_test.go`: diff is a mechanical re-indent/nest (6 former top-level `Describe`s -> 6 nested `Describe`s under one top-level wrapper). `Expect(` count is unchanged (58/58) and a full-hunk read of the first sub-journey confirms pure code motion, no logic change. - `page.Timeout`/`refreshPageTimeout` gotcha: every nested `Describe` that reuses a page across `It`s carries its own `BeforeEach(refreshPageTimeout)` or in-It `refreshPageTimeout` call (verified in `journey_reader_test.go` all 4 sub-journeys and `journey_filter_drawer_test.go` all 6 sub-journeys). No missing-reset regression found. - The 3 deferred minors: `makeCBZ` panic->`Expect` conversion in `journey_11_reader_html_structure_test.go` is correct (closure is invoked from inside an `It`, so `Expect`'s Gomega fail handler is reachable); the `a11y` `BeforeEach` removal is correct — every `It` in that file already calls `refreshPageTimeout` as its first statement, confirmed by grep; the nav `aria-label` scoping to `aside.sidebar` correctly narrows to mirror the original browser-e2e selector (`aside.sidebar nav[aria-label]`) instead of a page-wide `MatchRegexp`, and does not lose coverage. **Policy check.** `journey_reader_test.go` and `journey_filter_drawer_test.go` each have exactly one top-level `var _ = Describe(..., Ordered, ...)`; all nested `Describe`s are also `Ordered`. This matches `make e2e-policy-check`'s AST rule (only top-level Describes are checked) and mirrors the precedent already on `main` in `journey_content_manage_test.go` / `journey_bookdrop_test.go` (multiple nested `Describe`+`BeforeAll` pairs under one top-level wrapper) — not a novel pattern introduced by this PR. --- [MINOR] e2e/browser/journey_reader_test.go:14-17 — stale/incorrect cross-reference in the drop-justification comment The header comment (and the identical inline comment at line ~719) claims the two dropped annotation selector Its ("renders the annotations panel element", "renders the Highlights toolbar button") are "already covered by Journey-11 in e2e/api/". They are not: `git grep -n "annotation" e2e/api/journey_11_reader_html_structure_test.go` returns zero matches — that file never asserts `.reader-annotations-panel` or `[data-action*="annotations#togglePanel"]` render server-side. Actual coverage is still fine (the very next `It` in this same file fails fast via `MustElement(...).MustClick()`/the `Eventually` panel-open poll if either element is missing), so this is not a coverage-loss finding — but the comment asserts a false fact that a future reader (or a future consolidation pass) will trust at face value. Fix: reword to "implicitly covered by the interaction Its below (click/open would fail if either element were absent)" or actually add a one-line static-HTML assertion for these two selectors to Journey-11 so the comment becomes true. [MINOR] Budget methodology note (not blocking) — nested-Describe consolidation reduces the reported top-level-Describe count (40->32) without reducing the number of independent `BeforeAll`/fresh-DB-boot/browser-page-boot units (`journey_reader_test.go` still boots 4 separate DB resets + browser contexts; `journey_filter_drawer_test.go` still boots 6). This is consistent with the established epic precedent (`journey_content_manage_test.go`, `journey_bookdrop_test.go` on `main`) so it's not a regression introduced here, but worth flagging for the epic owner: if the real goal of the bz643 budget epic is CI wall-clock/duplication reduction (not just the Describe-count metric in CLAUDE.md), this slice's "Its 203->201" delta shows most of the win here is organizational, not a cost reduction. Consider a follow-up bead to actually merge boot state where sub-journeys are independent, or explicitly note in CLAUDE.md that the Describe-count budget is a readability/policy metric, not a CI-cost proxy. REVIEW VERDICT: 0 blocker, 0 major, 2 minor
zombor force-pushed bd-bookshelf-bz643.7 from 500c7104b1
All checks were successful
/ Test Race (pull_request) Successful in 2m17s
/ Lint (pull_request) Successful in 2m48s
/ E2E API (pull_request) Successful in 1m45s
/ JS Unit Tests (pull_request) Successful in 1m11s
/ Coverage (pull_request) Successful in 2m55s
/ Integration (pull_request) Successful in 3m0s
/ E2E Browser (pull_request) Successful in 4m57s
to db32f0404a
All checks were successful
/ Test Race (pull_request) Successful in 2m3s
/ E2E API (pull_request) Successful in 1m26s
/ Lint (pull_request) Successful in 3m0s
/ JS Unit Tests (pull_request) Successful in 1m15s
/ Coverage (pull_request) Successful in 2m30s
/ Integration (pull_request) Successful in 2m45s
/ E2E Browser (pull_request) Successful in 4m41s
2026-08-08 15:17:10 +00:00
Compare
zombor merged commit 7939b7026b into main 2026-08-08 15:28:22 +00:00
Sign in to join this conversation.
No reviewers
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
zombor/pergamum!1394
No description provided.