Repository navigation
E2E WelcomePortal entry remains nondeterministic across startup states #532
Description
Activity
- added 6 commits that reference this issue
on Aug 27, 2026 qnbs commented
on Aug 31, 2026 OwnerAuthorMore actionsRelated startup-authority update from PR #546 — 2026-08-31
One candidate observation documented in this issue has now been resolved independently by the S2/#531-A work in PR #546:
settings restored project absentis no longer treated as sufficient evidence that a real persisted project exists for initial metadata-seed authority. The boot path now derives that authority from an actually hydratable/normalized persisted project payload, so a settings-only state remains eligible to initialize the synthetic fresh project.
This removes the previously noted
const isNewUser = !preloadedState/ settings-only conflation as an outstanding candidate for this class of startup behavior.It does not close #532.
The core unresolved question here remains the separate startup-state/double-boot mechanism that can result in a real project being present before an E2E test expects WelcomePortal. The existing supported-UI
ensureWelcomePortalEntry()harness fix remains the correct deterministic test precondition; #546 should not be interpreted as proving or fixing the underlying Service Worker reload / autosave / other startup-state cause.Recommended current classification:
- settings-only seed-authority ambiguity: RESOLVED by fix: preserve intentionally cleared project metadata (#531-A) #546 once merged;
- E2E WelcomePortal precondition: already hardened;
- underlying double-boot / unexpected early persisted-project root cause: still OPEN / evidence-only investigation.
qnbs commented
on Sep 1, 2026 OwnerAuthorMore actionsRecurrence on unrelated docs-only PR #564 — 2026-09-01
New evidence materially strengthens this issue's classification as an independent startup-state / WelcomePortal-entry determinism problem rather than a regression caused by the current feature work.
Exact recurrence
On PR #564 (
docs(core): define R-15 secure storage contract (#445)), exact head:bf684034afe82d838dcd9bc62bfd9de0aecafbe6CI/CD run
33478269659/ Playwright job99764976401failed while the PR itself changes only the R-15 design contract / migration-ledger documentation and no application, onboarding, export, storage-runtime, or E2E source.Playwright result:
117 passed 9 skipped 2 failed 2 flakyThe failures/flakes again converge on the existing
ensureWelcomePortalEntry()/ WelcomePortal startup precondition path:onboarding-entry-precondition.spec.tsfailed in both Chromium and Mobile Chrome waiting for[data-tour="nav-mobile"]→More;export.spec.tswas flaky waiting forgetByTestId('welcome-portal')afterensureWelcomePortalEntry();- the second onboarding precondition case was likewise flaky waiting for
welcome-portal.
This recurrence is especially useful because PR #564 is semantically unrelated documentation-only work. It therefore provides additional evidence against treating this class as an R-15/S5 regression.
Current interpretation
The existing issue ownership remains correct:
S5 / PR #564 relation = NONE demonstrated startup/harness owner = #532 settings-only seed ambiguity = already resolved by #546 underlying double-boot / unexpected startup-state root cause = still OPENThe prior
ensureWelcomePortalEntry()supported-UI hardening remains useful, but this recurrence shows that it has not fully eliminated the nondeterministic startup/navigation failure class under CI.Anti-cascade / next evidence rule
Do not fix this inside PR #564 and do not reopen #527. Preserve the first-attempt failure. A single same-head targeted rerun is useful only to distinguish intermittent CI/startup behavior from a consistently reproducible gate failure. Repeated retry loops should not substitute for root-cause evidence.
If the same-head rerun passes, retain this recurrence as flake evidence and continue investigating #532 separately. If it fails again with the same path, treat that as stronger reproducibility evidence for a dedicated #532 remediation rather than absorbing onboarding/export changes into unrelated PRs.
- changed the title
[-]export.spec.ts E2E precondition assumes WelcomePortal unconditionally (startup-state determinism)[/-][+]E2E WelcomePortal entry remains nondeterministic across startup states[/+]on Sep 1, 2026 qnbs commented
on Sep 1, 2026 OwnerAuthorMore actionsFresh recurrence on PR #564 exact head
0865895f2c3070b8923556f61134013a0d077eba, CI/CD #2571, Playwright job99798975581:onboarding-entry-precondition.spec.tsagain traversedensureWelcomePortalEntry()and failed to reachwelcome-portalafter navigating to#/settings. In this run Playwright ultimately classified that test as flaky; 119 tests passed, 9 skipped. This remains separate from the run's final blocking failure, which was a reproducible Axe contrast defect now tracked in #565. No #564/S5 source ownership is inferred.Another recurrence on PR #564 (still docs-only:
docs/native/R15-SECURE-STORAGE-CONTRACT.md+docs/native/CORE-MIGRATION-LEDGER.md), this time at head1212d4bb4b1f...(verify via PR), CI/CD run33588480169.Identical signature across all 3 attempts in this run:
[Mobile Chrome] › tests/e2e/onboarding-entry-precondition.spec.ts:18:3 › ... reaches the entry point when a non-English language is already persistedError: expect(locator).toBeVisible() failed/element(s) not foundatonboarding-entry-precondition.spec.ts:24:5- 120 passed / 1 failed each time, same test, same project, all 3 in-run Playwright retries also failed identically
No demonstrated relationship to this PR's content (2 markdown files only). Consistent with this issue's existing classification. Continuing with additional reruns per the existing "same-head targeted rerun to classify intermittent behavior" guidance rather than treating this as a PR #564 blocker.
- added a commit that references this issue
on Sep 2, 2026 Tracked a plausible additional contributing mechanism separately in #585 (SW
clients.claim()causes an unconditional reload on a brand-new browser context's first page load) — found while verifying PR #583's fixes. Not folded into #583/#532's own fix, since it's a distinct production service-worker behavior question needing its own review, not a test-harness fix.- added a commit that references this issue
on Sep 3, 2026 18 remaining items
qnbs commented
on Sep 12, 2026 OwnerAuthorMore actionsIntegration note — #736 required-gate hardening must preserve #532 failure evidence
#736 now defines the lean required Playwright product spine and includes startup/Onboarding → Blank Project as a protected critical journey.
This does not supersede #532. The WelcomePortal/double-boot/startup-state nondeterminism here remains its own source/harness correctness owner.
When #736 refactors or isolates required E2E setup:
- do not mask E2E WelcomePortal entry remains nondeterministic across startup states #532 with broader retries, arbitrary sleeps, timeout inflation,
.catch(() => {}), conditional skips, or raw storage surgery; - preserve first-attempt failure evidence;
- distinguish
PRODUCT_UI_PRECONDITIONfrom deterministic supported seeding for tests that are not themselves testing onboarding; - avoid forcing every Writer/Settings/Export spec through WelcomePortal setup, because that turns one startup failure into a cascade and obscures independent evidence;
- retain at least one genuine supported-UI startup/Onboarding contract in the required lane.
A better-isolated suite may reduce cascading failures without reducing #532's visibility. If #736 changes test topology and the same startup failure still reproduces, keep the evidence here rather than reclassifying it as generic E2E flakiness.
- do not mask E2E WelcomePortal entry remains nondeterministic across startup states #532 with broader retries, arbitrary sleeps, timeout inflation,
qnbs commented
on Sep 23, 2026 OwnerAuthorMore actionsHousekeeping closure — successor PR #596 landed the deferred root-cause work (2026-09-23)
This issue was deliberately reopened after #590 because #590 only extracted the locale-independent recovery-navigation slice. The reopening comment stated the intended closure condition clearly: close again once the broader #583 reset/startup work lands and post-merge evidence is green.
That broader work did land via #583's authoritative successor PR #596, merged as:
a8131b624433bd79c818bb6780050c5cb2f7fec4PR #596 implemented the async generation/epoch-based IDB reset-quiescence and open-admission contract across the long-lived stores, fixed the confirmed WelcomePortal recovery/harness mechanisms, hardened Factory Reset deletion ownership/blocked/error behavior, and added focused regression coverage.
Since that merge:
- no later E2E WelcomePortal entry remains nondeterministic across startup states #532-specific recurrence has been recorded;
- multiple subsequent main/release/feature/dependency waves have exercised the repository;
- current resulting-main CI/CD #3463 on
2de980db...is green; - both
🎭 E2E Tests (Playwright)and🔬 E2E Deep Coverage (feature-flag matrix)are SUCCESS on that current main.
The remaining distinct Service Worker / multi-context lifecycle risks are not reason to keep #532 open; they already have specialist owners (#480/#485/#614 and related lifecycle work). If the exact WelcomePortal/startup signature reappears after #596 on a future head, open/reopen from fresh evidence rather than preserving this historical P0 indefinitely.
Closing as completed.
- added 9 commits that reference this issue
on Oct 10, 2026
Current status — 2026-09-01
This issue remains OPEN. The supported-UI
ensureWelcomePortalEntry()harness hardening reduced the original precondition problem but has not fully eliminated this nondeterministic startup/navigation failure class.A recurrence was observed on unrelated docs-only PR #564 at exact head
bf684034afe82d838dcd9bc62bfd9de0aecafbe6in CI/CD run33478269659/ Playwright job99764976401:The failures/flakes again converged on
ensureWelcomePortalEntry()/ WelcomePortal startup navigation inonboarding-entry-precondition.spec.tsandexport.spec.ts, across Chromium and Mobile Chrome. PR #564 changes only the R-15 design contract / migration-ledger documentation, so there is no demonstrated S5/R-15 source relationship.Current classification:
Preserve first-attempt failures as evidence. A same-head targeted rerun may classify intermittent behavior, but repeated retries must not substitute for root-cause analysis.
Summary
export.spec.ts'sbeforeEachoriginally assumedwaitForSpaReady(page)always resolves via WelcomePortal, and clicked "Start a New Project" unconditionally.waitForSpaReady()actually races three success conditions (#sidebar,[data-tour="nav-mobile"], or the "Start a New Project" button) and succeeds on any of them — it does not distinguish a fresh boot from a returning-user boot. On themainpost-merge run for PR #530 (run33088546994, job98579015311), all 3 Playwright retries of this test failed identically (byte-identical screenshot/error-context hashes) waiting on that locator, because the app had already booted into the main shell (Outline Generator view) instead of WelcomePortal. A same-SHA rerun (job98582879363) passed cleanly, establishing a startup-state determinism gap rather than the already-fixed #527 portal-activation auto-seed race.This is not a regression of #527/#530. Do not reopen #527 unless its exact mechanism is independently reproduced.
Evidence gathered from the original failure
From the failed job's attached Playwright trace (
retry 1,chromium):waitForSpaReady()'s internal action log shows the#sidebarwait resolving successfully before the "Start a New Project" wait ever got its own resolution — i.e. the race resolved via the main-chrome branch, not WelcomePortal.http://127.0.0.1:3000/WorldScript-Studio/with no hash, then ~700ms later the hash became#/outlineand stayed there for the remainder of the 20s timeout — i.e. the app's own in-app router (deepLinkService.pushHash) navigated to Outline Generator on its own, which peruseApp.ts'sreadInitialView()priority (URL hash →?view=→localStorage['worldscript-last-view']→ dashboard) only happens when one of the first three sources was already non-empty.Using IndexedDB storage backend, SW registration, WorkerBus init) occurring twice within this single trace, with[WorldScript:DEBUG:app] Hydrating flat project state into Redux-Undo envelope.appearing only on the second occurrence. Perindex.tsx'sbootApp(), this log line only fires whenpreloadedState.projectis truthy and in flat (non-envelope) format — i.e. a real, non-blank persisted project existed in IndexedDB by the second boot cycle, not merely a default/blank placeholder.export.spec.tsis a single-test file using Playwright's stock, fully-isolated per-test browser context (no custom fixtures, nostorageState, noglobalSetupinplaywright.config.ts) — cross-test-file storage leakage is ruled out as the mechanism.Open root cause
The exact trigger for the double-boot cycle and/or unexpected WelcomePortal-entry state is not yet pinned down.
Candidate mechanisms requiring evidence include:
register-sw.ts's unconditionalcontrollerchange→location.reload()(the existing DA-02 finding), which can explain a mid-boot reload but does not by itself explain every persisted-state observation.nav-mobileorwelcome-portal.The previously noted settings-only
isNewUserambiguity is no longer an outstanding candidate: PR #546 changed seed authority to depend on an actually hydratable/normalized persisted project rather than any truthy preloaded state. That correction does not explain or close the remaining double-boot / startup-navigation behavior.Harness hardening already landed
ensureWelcomePortalEntry()intests/e2e/helpers.tsestablishes the WelcomePortal entry through supported UI: if "Start a New Project" is not visible afterwaitForSpaReady(), it uses Settings → Data & Backups → Factory Reset rather than touching storage/React internals directly.tests/e2e/onboarding-entry-precondition.spec.tsregression-tests multiple startup shapes.This remains the correct direction for deterministic preconditions, but the #564 recurrence proves the current helper is not yet a complete closure of the startup/navigation failure class. Any further remediation should be performed in a dedicated #532 scope, not opportunistically inside unrelated PRs.
Recommended investigation / acceptance criteria
A dedicated #532 remediation should establish which of these is authoritative:
Before closing #532, require evidence that:
ensureWelcomePortalEntry()reliably reaches its target from each supported startup shape used by CI;nav-mobile/welcome-portalnever becomes reachable;Non-goals