Repository navigation
test(shell): rule out two causes for #38, guard the reported sequence - #64
Merged
Merged
Conversation
#38 says Settings stays on screen after the version click and the next page is appended below it. Reported on Windows; not reproduced here, and this commit is the evidence rather than a fix. Two of the issue's three hypotheses are now ruled out by test: An exception during destroy does NOT produce that symptom. The intuition was that RouterOutlet.deactivate() aborts before clearing its reference, leaving the old DOM for the next activation to land under. On this Angular version the throw takes the whole navigation down instead and the outlet ends up EMPTY — a blank content area, not a stuck page. shell-routing.spec.ts measures both directions. And a destroyed view does not throw when refreshed. settings.component.ts carried a comment saying it does, which is what made "a pending await resolving into a destroyed view" look like a live lead. Measured on Angular 21: it is a no-op. The comment now says so, and points at the test, because that wrong sentence cost an investigation. What is left as a guard rather than a diagnosis: - A Playwright spec walking the exact reported sequence — version footer, every Settings tab, then two further navigations — asserting exactly one routed page in the DOM and no application errors. It passes on Linux/Chromium, so it cannot confirm the bug, but it fails if anyone introduces it here. - A second case for the issue's remaining hypothesis: clicking the version while already on Settings, which is the one path where the router reuses the component instead of recreating it. Also clean. - A Vitest spec driving the real router through the real shell for the same sequence, which is where a regression would show up first. What that leaves: the animation hypothesis, on WebView2. `provideAnimationsAsync()` loads a stub under Vitest and the real engine in a browser, and Chromium's engine is not WebView2's. Confirming or killing it needs the Windows build. Refs #38 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #38 — not a fix. The bug did not reproduce here; this is what the investigation found, so the next attempt starts further along.
Two of the three hypotheses are dead
"An exception thrown during destroy keeps the outgoing component attached." That was the most plausible one, and it is wrong on this Angular version. The guess was that
RouterOutlet.deactivate()aborts before clearing its reference, leaving the old DOM for the next activation to land underneath. Measured instead: the throw takes the whole navigation down and the outlet ends up empty. A blank content area and a stuck page are different bugs.shell-routing.spec.tsasserts both directions so nobody has to guess again."A pending
awaitresolving into a destroyed view."settings.component.tscarried the comment "refreshing a destroyed view throws", which is what made this look live —ngOnInitawaits five Wails calls before touching the view, and over the desktop bridge each is an IPC round trip. Measured on Angular 21:detectChanges()on a destroyed view is a no-op. The comment is corrected and now points at the test, because that one wrong sentence sent the investigation after a phantom. A test also drives the real race — leave Settings before its first Wails call answers — and nothing throws.That leaves the animation hypothesis, which is the one I cannot test here:
provideAnimationsAsync()loads a stub under Vitest and the real engine in a browser, and Chromium's engine is not WebView2's.What ships as a guard
ng serveresource 404s, which are the missing Wails bridge and not app errors.)What I tried and what it would take
Reproduced on Linux, headless Chromium, against
ng serve: the page always swaps. The report is Windows, WebView2, a dev build from PR #31. Confirming the animation hypothesis needs that combination — specifically whether a PrimeNG tab-panel:leaveanimation fails to complete under WebView2, which has precedent in this repo (the StepPanel wizard, see CLAUDE.md).Concretely, next step on a Windows box: run the sequence in
wails3 dev, and check whetherdocument.querySelectorAll('.settings-page').length > 1afterwards and whether any element still carries anng-animatingclass.Verification
npm test— 193 passed (13 files);npx tsc --noEmitclean;npm run buildcleannpx playwright test router-leave-settings— 2 passed locally, headless🤖 Generated with Claude Code