e2e-testing: no way to register per-navigation page state on the shared Page #49

Open
opened 2026-09-03 10:39:19 +00:00 by mph · 0 comments
Owner

Found while reviewing an E2E readiness wait in medeca-modul-poptavky (MEDECA-444 Phase 4).

The shape of the problem

PlaywrightTestContext creates one Page in initialize() and getPage() returns that same
instance for the entire Cucumber run
(e2e-testing/src/main/scala/works/iterative/testing/e2e/PlaywrightTestContext.scala:30,57,60-66).
Per-scenario recycling happens only when a video recording directory is configured, which most
suites leave unset.

Playwright has no API to remove an init script. So page.addInitScript() called from a Cucumber
step body registers for the lifetime of the Page, not for the current navigation. A step used by
N scenarios stacks N identical scripts, and every one of them then re-runs before every later
navigation in the suite — including pages that have nothing to do with the step that registered it.

Concrete instance: a navigation step backing 14 scenarios across 5 feature files registers an init
script that installs a DOM event listener used as a readiness signal. By the end of the run, 14
copies run before every navigation. It happens to be idempotent there (each copy sets the same flag
false, each listener sets it true), so it is untidy rather than wrong — but the next use of the
pattern need not be idempotent.

Why the consumer cannot fix it

A correct one-shot registration needs Page-keyed state, and a Cucumber step class cannot hold it:
Cucumber instantiates a fresh step instance per scenario. The fix belongs in this module.

Suggested direction

Give e2e-testing a way to register Page-scoped setup exactly once — a Page-keyed registry, or
a hook that runs registrations at Page creation. Then document the rule for consumers: register
per-navigation state with page.evaluate after navigating, and reserve addInitScript for
listeners that must exist before the page's own scripts run, registered once per Page.

Reference: medeca-modul-poptavky, project-management/issues/MEDECA-444/LESSONS.md, entry
2026-09-03 "page.addInitScript accumulates for the whole run on the suite's single shared Page".

Found while reviewing an E2E readiness wait in `medeca-modul-poptavky` (MEDECA-444 Phase 4). ## The shape of the problem `PlaywrightTestContext` creates **one** `Page` in `initialize()` and `getPage()` returns that same instance for the entire Cucumber run (`e2e-testing/src/main/scala/works/iterative/testing/e2e/PlaywrightTestContext.scala:30,57,60-66`). Per-scenario recycling happens only when a video recording directory is configured, which most suites leave unset. Playwright has no API to remove an init script. So `page.addInitScript()` called from a Cucumber step body registers for the lifetime of the `Page`, not for the current navigation. A step used by N scenarios stacks N identical scripts, and every one of them then re-runs before **every** later navigation in the suite — including pages that have nothing to do with the step that registered it. Concrete instance: a navigation step backing 14 scenarios across 5 feature files registers an init script that installs a DOM event listener used as a readiness signal. By the end of the run, 14 copies run before every navigation. It happens to be idempotent there (each copy sets the same flag false, each listener sets it true), so it is untidy rather than wrong — but the next use of the pattern need not be idempotent. ## Why the consumer cannot fix it A correct one-shot registration needs `Page`-keyed state, and a Cucumber step class cannot hold it: Cucumber instantiates a fresh step instance per scenario. The fix belongs in this module. ## Suggested direction Give `e2e-testing` a way to register `Page`-scoped setup exactly once — a `Page`-keyed registry, or a hook that runs registrations at `Page` creation. Then document the rule for consumers: register per-navigation state with `page.evaluate` **after** navigating, and reserve `addInitScript` for listeners that must exist before the page's own scripts run, registered once per `Page`. Reference: `medeca-modul-poptavky`, `project-management/issues/MEDECA-444/LESSONS.md`, entry 2026-09-03 "`page.addInitScript` accumulates for the whole run on the suite's single shared `Page`".
Sign in to join this conversation.
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
iterative-works/support#49
No description provided.