Skip to content

Commit 96926ec

Browse files
committed
Fix repeated static login API errors and root-cause ShowOneChild crash - PR_26158_031-console-root-cause-fix
1 parent df30ade commit 96926ec

7 files changed

Lines changed: 173 additions & 37 deletions

File tree

assets/theme-v2/js/gamefoundry-partials.js

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110

111111
const currentScript = document.currentScript || document.querySelector("script[src*='gamefoundry-partials.js']");
112112
const assetRoot = currentScript ? new URL("../", currentScript.src) : null;
113+
const staticApiDiagnosticKey = "GameFoundryStaticApiUnavailableDiagnostic";
113114

114115
function assetUrl(path) {
115116
if (!assetRoot) return rootPrefix() + path;
@@ -142,6 +143,24 @@
142143
return "Local server API route unavailable for " + method + " " + url + " (" + status + "). Start the API-backed local server route instead of a static-only server.";
143144
}
144145

146+
function cachedStaticApiDiagnostic() {
147+
return String(window[staticApiDiagnosticKey] || "");
148+
}
149+
150+
function cacheStaticApiDiagnostic(message) {
151+
window[staticApiDiagnosticKey] = message;
152+
}
153+
154+
function missingSessionApiLoginState(diagnostic) {
155+
return {
156+
authenticated: false,
157+
diagnostic: diagnostic || "Server session API is unavailable. Start the local server API before using protected pages.",
158+
displayName: "Login",
159+
mode: "missing-api",
160+
roleSlugs: []
161+
};
162+
}
163+
145164
function rewriteRootedPaths(root) {
146165
root.querySelectorAll("[data-route]").forEach(function (link) {
147166
link.setAttribute("href", routeHref(link.dataset.route));
@@ -153,6 +172,10 @@
153172
}
154173

155174
function localDevLoginState() {
175+
const cachedDiagnostic = cachedStaticApiDiagnostic();
176+
if (cachedDiagnostic) {
177+
return missingSessionApiLoginState(cachedDiagnostic);
178+
}
156179
try {
157180
const request = new XMLHttpRequest();
158181
request.open("GET", "/api/session/current", false);
@@ -161,7 +184,9 @@
161184
const payload = request.responseText ? JSON.parse(request.responseText) : null;
162185
if (request.status < 200 || request.status >= 300 || payload?.ok === false) {
163186
if (request.status === 404 || request.status === 405) {
164-
throw new Error(localRouteUnavailableDiagnostic("GET", "/api/session/current", request.status));
187+
const diagnostic = localRouteUnavailableDiagnostic("GET", "/api/session/current", request.status);
188+
cacheStaticApiDiagnostic(diagnostic);
189+
throw new Error(diagnostic);
165190
}
166191
throw new Error(payload?.error || "Session API did not return a valid current session.");
167192
}
@@ -174,13 +199,7 @@
174199
roleSlugs: Array.isArray(session.roleSlugs) ? session.roleSlugs : []
175200
};
176201
} catch (error) {
177-
return {
178-
authenticated: false,
179-
diagnostic: "Server session API is unavailable. Start the local server API before using protected pages.",
180-
displayName: "Login",
181-
mode: "missing-api",
182-
roleSlugs: []
183-
};
202+
return missingSessionApiLoginState(error instanceof Error ? error.message : "");
184203
}
185204
}
186205

@@ -312,6 +331,17 @@
312331
function enforcePageProtection() {
313332
const pagePath = currentPagePath() || "index.html";
314333
const requirement = protectedPageRequirement(pagePath);
334+
if (!requirement) {
335+
const diagnostic = cachedStaticApiDiagnostic();
336+
window.GameFoundrySessionGuard = {
337+
blocked: false,
338+
diagnostic,
339+
mode: diagnostic ? "missing-api" : "",
340+
pagePath,
341+
requirement: ""
342+
};
343+
return false;
344+
}
315345
const loginState = localDevLoginState();
316346
const allowed = canUseProtectedPage(requirement, loginState);
317347
window.GameFoundrySessionGuard = {
@@ -321,7 +351,7 @@
321351
pagePath,
322352
requirement: requirement?.role || ""
323353
};
324-
if (!requirement || allowed) {
354+
if (allowed) {
325355
return false;
326356
}
327357

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# PR_26158_031 Console Root Cause Fix Report
2+
3+
## Executive Summary
4+
5+
Root cause was split:
6+
7+
- `ShowOneChild.js` / `ActionableCoachmark` is not repo-owned and is not loaded by repo HTML/JS. Repo references are limited to test guards and historical reports. No global `ActionableCoachmark` shim was added.
8+
- Repeated static-only `/api/session/current` 404s were repo-owned. `gamefoundry-partials.js` and the module session API client could independently probe the same missing endpoint while rendering login/header state. The fix shares one visible static API diagnostic and prevents later session reads from repeating the network miss.
9+
10+
## Implementation
11+
12+
| Area | Change | Evidence |
13+
| --- | --- | --- |
14+
| Header/session partials | Added shared `GameFoundryStaticApiUnavailableDiagnostic` handling, returned a visible unauthenticated diagnostic from cache, and stopped unprotected pages from calling the session API through page-protection enforcement. | `assets/theme-v2/js/gamefoundry-partials.js` |
15+
| Server API client | Added session-route static API diagnostic caching, deduped repeated diagnostic entries, and shared the same browser diagnostic key with the header partial. | `src/engine/api/server-api-client.js` |
16+
| Static-only Playwright | Added assertions for exactly one `/api/session/current` failure, no follow-up session API failures after mode clicks, and no repo-owned `ShowOneChild` / `ActionableCoachmark` error text. | `tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` |
17+
18+
## ShowOneChild / ActionableCoachmark Audit
19+
20+
| Audit | Evidence | Result |
21+
| --- | --- | --- |
22+
| Locate every repo reference to `ShowOneChild`, `showOneChild`, and `ActionableCoachmark`. | `rg -n "ShowOneChild\|showOneChild\|ActionableCoachmark" .` found only `tests/helpers/browserExtensionNoise.mjs`, `tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs`, the new static-only assertion, and historical reports. | PASS |
23+
| Locate any repo-owned `ShowOneChild.js` file. | `Get-ChildItem -Path . -Recurse -Filter ShowOneChild.js -File` returned no files. | PASS |
24+
| Check active HTML/JS loads. | Scoped active HTML/JS `rg` found only test helper/spec references, no active runtime HTML or JS script load. | PASS |
25+
| Determine source. | Exact repo source is none: there is no repo file and no active repo load path for `ShowOneChild.js`. Any runtime `ShowOneChild.js` console message is therefore external to the repo, such as an extension-injected script. | PASS |
26+
| Avoid masking repo-owned errors. | `tests/helpers/browserExtensionNoise.mjs` only treats named scripts as extension noise when an extension URL scheme is present; the new static-only test also fails on bare `ShowOneChild` / `ActionableCoachmark` errors. | PASS |
27+
28+
## Requirement Checklist
29+
30+
| Requirement | Evidence | Status |
31+
| --- | --- | --- |
32+
| Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` first. | Read before implementation. | PASS |
33+
| Root-cause and fix repeated console errors instead of fallback-only patch. | Root cause identified as duplicated static session probes; fixed shared diagnostic/cache and public-page guard behavior. | PASS |
34+
| Locate every repo reference to `ShowOneChild`, `showOneChild`, and `ActionableCoachmark`. | Full `rg` plus scoped active HTML/JS `rg` documented above. | PASS |
35+
| If `ShowOneChild.js` is repo-owned or loaded by repo HTML, fix dependency or remove load. | Not repo-owned and not loaded by repo HTML/JS. | PASS |
36+
| If `ShowOneChild.js` is not repo-owned, prove exact source in report. | Proof is repo-negative: no file, no active load path, only tests/reports. Runtime occurrence cannot be served by this repo and is external. | PASS |
37+
| Fix `gamefoundry-partials.js` so static-only `127.0.0.1:5500` does not repeatedly call `/api/session/current`. | Partial now skips session calls for unprotected pages and reuses shared static diagnostic after first miss. | PASS |
38+
| Fix `server-api-client` / `session-api-client` behavior so missing static API is handled once with visible diagnostics. | `server-api-client.js` caches session-route 404/405 diagnostics. `session-api-client.js` already routes through that client. Static test asserts one `/api/session/current` failure only. | PASS |
39+
| Preserve Local Mem clickability without API. | Static-only Playwright verifies Local Mem is enabled/clickable after missing API. | PASS |
40+
| Preserve Local DB API-required diagnostic when API unavailable. | Static-only Playwright verifies Local DB diagnostic says API-backed server and SQLite-backed Local DB are required. | PASS |
41+
| Preserve SQLite-backed Local DB when API server is running. | `LoginSessionMode.spec.mjs` passed Local DB login/session behavior. | PASS |
42+
| Do not add UAT/Prod behavior. | No UAT/Prod login options or adapter behavior changed. | PASS |
43+
| Do not modify `start_of_day` folders. | `git status --short` shows no `start_of_day` files. | PASS |
44+
| Run changed-file syntax checks. | `node --check` passed for changed JS/spec files. | PASS |
45+
| Run LoginSessionMode Playwright. | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` passed 5/5 on serialized rerun. | PASS |
46+
| Run static-only login Playwright. | `npx playwright test tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` passed 1/1. | PASS |
47+
| Run ToolboxRoutePages Playwright. | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` passed 1/1. | PASS |
48+
| Add console-error assertion proving no repo-owned ShowOneChild/ActionableCoachmark error and no repeated `/api/session/current` spam. | `StaticOnlyLoginFallback.spec.mjs` asserts no matching page/console error text and exactly one `/api/session/current` failure. | PASS |
49+
| Do not run full samples smoke unless directly impacted. | Full samples smoke skipped; samples were not touched. | PASS |
50+
51+
## Validation Commands
52+
53+
| Command | Result |
54+
| --- | --- |
55+
| `node --check assets/theme-v2/js/gamefoundry-partials.js` | PASS |
56+
| `node --check src/engine/api/server-api-client.js` | PASS |
57+
| `node --check tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS |
58+
| `npx playwright test tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS, 1/1 |
59+
| `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS, 5/5 on serialized rerun |
60+
| `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 |
61+
| `git diff --check` | PASS, with Git line-ending warnings only |
62+
63+
## Skipped Lanes
64+
65+
| Lane | Decision | Reason |
66+
| --- | --- | --- |
67+
| AdminDbViewer Playwright | SKIP | DB Viewer routes and rendering were not changed. |
68+
| Full samples smoke | SKIP | No sample files, sample loader, or shared sample framework changed. |
69+
| Full Playwright suite | SKIP | Requested targeted lanes cover the changed static login, API-backed login, and toolbox route behavior. |
70+
71+
## Remaining Notes
72+
73+
- The first parallel validation attempt ran `LoginSessionMode` and `ToolboxRoutePages` at the same time and produced a Playwright trace artifact `ENOENT` in the login lane. `LoginSessionMode` passed 5/5 when rerun alone, so the final lane evidence is the serialized PASS.
74+
- Playwright emitted Node SQLite experimental warnings from the existing Local DB path. They are not introduced by this PR and did not fail validation.

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ Missing changed runtime JS files are WARN, not FAIL.
66
Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

88
Changed runtime JS files considered:
9-
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
10-
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
9+
(55%) src/engine/api/server-api-client.js - executed lines 186/186; executed functions 12/22
1110

1211
Guardrail warnings:
13-
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only
12+
(100%) none - no changed runtime JS coverage warnings

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,30 @@ Note: coverage entries are aggregated across every page/tool where coverageRepor
1414
Exercised tool entry points detected:
1515
(61%) Toolbox Index - exercised 3 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
17-
(79%) Theme V2 Shared JS - exercised 3 runtime JS files
17+
(77%) Theme V2 Shared JS - exercised 3 runtime JS files
1818

1919
Changed runtime JS files covered:
20-
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file was not collected by Playwright V8 coverage; advisory only
21-
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
20+
(55%) src/engine/api/server-api-client.js - executed lines 186/186; executed functions 12/22
2221

2322
Files with executed line/function counts where available:
24-
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
23+
(55%) src/engine/api/server-api-client.js - executed lines 186/186; executed functions 12/22
2524
(55%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 54/99
2625
(60%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 3/5
2726
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 201/201; executed functions 9/14
2827
(67%) admin/db-viewer.js - executed lines 53/53; executed functions 4/6
2928
(79%) assets/theme-v2/js/login-session.js - executed lines 227/227; executed functions 15/19
29+
(80%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 448/448; executed functions 33/41
3030
(81%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 22/27
31-
(84%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 421/421; executed functions 32/38
3231
(85%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 82/96
3332
(88%) src/engine/api/session-api-client.js - executed lines 34/34; executed functions 7/8
3433
(100%) toolbox/project-journey/project-journey-api-client.js - executed lines 12/12; executed functions 2/2
3534

3635
Uncovered or low-coverage changed JS files:
37-
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: uncovered changed runtime JS file; advisory only
36+
(100%) none - no low-coverage changed runtime JS files
3837

3938
Changed JS files considered:
40-
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
4139
(0%) tests/helpers/browserExtensionNoise.mjs - changed JS file not collected as browser runtime coverage
42-
(0%) tests/playwright/tools/AdminDbViewer.spec.mjs - changed JS file not collected as browser runtime coverage
43-
(0%) tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs - changed JS file not collected as browser runtime coverage
44-
(0%) tests/playwright/tools/LoginSessionMode.spec.mjs - changed JS file not collected as browser runtime coverage
4540
(0%) tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs - changed JS file not collected as browser runtime coverage
46-
(0%) tests/playwright/tools/ToolboxRoutePages.spec.mjs - changed JS file not collected as browser runtime coverage
47-
(53%) src/engine/api/server-api-client.js - changed JS file with browser V8 coverage
41+
(55%) src/engine/api/server-api-client.js - changed JS file with browser V8 coverage
4842
(79%) assets/theme-v2/js/login-session.js - changed JS file with browser V8 coverage
49-
(84%) assets/theme-v2/js/gamefoundry-partials.js - changed JS file with browser V8 coverage
43+
(80%) assets/theme-v2/js/gamefoundry-partials.js - changed JS file with browser V8 coverage

0 commit comments

Comments
 (0)