B-MNIZ-goto-in-e2e-defeats-unmount-assertions
A Playwright page.goto is a real document load. Every useState in the app is rebuilt from its
initializer, every store is fresh, and the component tree is new. So a spec that navigates with
goto and then asserts something about what a component did ON THE WAY OUT is asserting against a
blank slate: it passes whether or not the teardown behaviour it means to pin exists at all.
Found while pinning the find-bar fix in
#1719. The claim was “opening another note closes the
find bar instead of greeting the reader with one” — real behaviour, backed by
MdSurface emitting update:findOpen(false) from onBeforeUnmount. The first version of the test
reached the second note with open() (a goto) and passed. It also passed with the fix reverted,
because useState("notes:find") had been rebuilt by the reload either way.
The correct idiom, and how to confirm it
Section titled “The correct idiom, and how to confirm it”Navigate IN-APP. pages/apps/notes/[...path].vue keys <NotesNoteView :key="noteKey(address)">, so
a router navigation genuinely unmounts the old surface and mounts a new one against one live flag —
which is the thing under test. In the notes suite that means clicking the tab strip:
await page.getByTestId("notes-tab-strip").getByRole("tab", { name: title }).click()solutions/determined/tests/ui/notes/scroll-memory.e2e.ts:326 already uses this deliberately and
comments on why (“an in-app navigation, no reload”), so the pattern is established in the codebase.
To confirm a navigation really was in-app, set a marker on window before it and read it after:
await page.evaluate(() => { (window as any).__probeMark = "set-on-A" })// …navigate…await page.evaluate(() => (window as any).__probeMark) // survives an in-app nav, gone after a reloadThat is the check that distinguished the two cases here: absent after open(), "set-on-A" after
the tab click.
What to do
Section titled “What to do”Sweep the existing e2e specs for assertions about cross-navigation or post-unmount state that are
reached through goto, and convert the ones that need a live app to in-app navigation. The tell is
a spec that navigates and then asserts an ABSENCE — no bar, no dialog, no leftover selection —
since an absence is exactly what a fresh page gives you for free. Not every goto is wrong: a spec
whose subject is the cold-load path should keep it.
The class is not notes-specific. Any app-frame product with shared useState or a store that
outlives a keyed component has the same hole.