fix(e2e): sweep MustEval-in-Eventually to Eval+error-check (bookshelf-b96py) #1349
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bd-bookshelf-b96py"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
page.MustEval()calls used as the return value ofEventually(...)polling callbacks topage.Eval()with anerr != nilcheck that returns the zero value, so CDP transient errors (tab busy, session timeout, eval throw) cause the poll to retry instead of panicking the spec.func() bool,func() string, andfunc() intpoll callbacks.MustEvalcalls after the element is confirmed present are left unchanged — panics there are legitimate failures, not flakes.MustElement-in-Eventuallyand the ydjo9 (#1342) canonical conversion pattern.Test plan
go build -tags e2e ./e2e/browser/...compiles clean.Eventuallyno longer abort the spec.Closes bead bookshelf-b96py on merge.
Security Review — PR #1349 (bookshelf-b96py)
Scope verification complete. All 20 changed files are under
e2e/browser/— no production code, no middleware, no CSP/auth/header changes were included in this sweep.What was checked:
e2e/browser/*_test.go— no smuggled production changes.Eval()calls are byte-for-byte identical to the originalMustEval()calls — only the Go wrapper changed from panic-on-error toerrreturn withreturn false/""/0on failure.result, err := page.Eval(...)+if err != nil { return <zero> }+return result.Value.<Type>()). No structural additions beyond this pattern were found.This is a pure test-robustness sweep with no security surface.
REVIEW VERDICT: 0 blocker, 0 major, 0 minor
Code Review — bookshelf-b96py (MustEval sweep)
[MAJOR] e2e/browser/journey_book_send_email_test.go:123 — MustEval inside Eventually not converted (2 sites)
Lines 123 and 148 are
page.MustEval(...)calls sitting insideEventually(func() bool { ... })poll loops. A transient CDP error in either call will panic, aborting the spec (the same class of flake this PR exists to fix). Both follow the exact same pattern as the converted sites.Fix: apply the same
result, err := page.Eval(...); if err != nil { return false }; return result.Value.Bool()conversion to bothEventuallybodies (lines 122–131 and 147–155).[MAJOR] e2e/browser/journey_magic_shelf_rating_dropdown_test.go:66 — MustEval inside Eventually not converted (1 site)
Line 66:
return page.MustEval(\() => document.getElementById("magic-shelf-modal") !== null`).Bool()is inside anEventually(func() bool { ... })block. A transient CDP error panics and kills the spec. Fix: convert toresult, err := page.Eval(...); if err != nil { return false }; return result.Value.Bool()`.[MAJOR] e2e/browser/journey_reset_progress_test.go:94 — MustEval inside Eventually not converted (4 sites)
Lines 94, 110, 121, and 138 are all
page.MustEval(...)calls insideEventually(func() bool { ... })poll loops; each polls the kebab menuis-openclass or the.apd-overlayhidden attribute. A CDP error at any of these panics the spec.Fix: same conversion pattern applied to all four
Eventuallybodies.Scope discipline: All 75+ converted sites in the 20 modified files are correctly scoped — every
Evalconversion is inside anEventually/poll block, and standalone one-shotMustEvalcalls (assertions, DOM manipulations, setup actions) are correctly left as-is.Conversion correctness: The error-handling pattern is uniformly correct. Two minor style variants appear (
if err != nil { return false }vsreturn evalErr == nil && result.Value.Bool()) but both are safe — the short-circuit&&prevents nil-deref on the result pointer when err is non-nil. No nil-deref risk found.Semantic equivalence:
MustEval()returnsgson.JSONdirectly (per go-rodmust.go:487), so the old.String()calledgson.JSON.String()(thefmt.Stringerimplementation:fmt.Sprintf("%v", v)). The newresult.Value.Str()callsgson.JSON.Str(). For string-returning JS expressions, both produce the same result. The.Bool()and.Int()paths are identical (result.Valueis the samegson.JSONthe old code held).Non-e2e files: Zero — the diff touches only
e2e/browser/test files. No production code changed, no assertions weakened.REVIEW VERDICT: 0 blocker, 3 major, 0 minor
Orchestrator note — the 3 [MAJOR] findings in the code review (comment 16624) are FALSE POSITIVES from a stale review base. Verified against
origin/bd-bookshelf-b96pyandorigin/main:journey_book_send_email_test.go— does not exist on this branch or onmain(migrated to Vitest by bz643.2 / #1344, merged earlier today). The review diffed a pre-#1344 base.journey_magic_shelf_rating_dropdown_test.go— does not exist on this branch ormain(same #1344 migration).journey_reset_progress_test.go— already converted by ydjo9 / #1342: everyEventually(func() bool {…})body usespage.Eval(…)+err; zeroMustEvalpresent.A full branch sweep (context-scan of every
e2e/browser/*_test.go) finds noMustEvalinside anyEventuallyblock; all remainingMustEvalcalls are standalone one-shots, correctly left unchanged. Effective verdict: 0 blocker, 0 major, 0 minor. Proceeding to merge.36f3fe09451f4e132f76