Skip to content

Commit df30ade

Browse files
committed
Recover static-only local login fallback and missing script dependency handling - PR_26158_030-static-server-login-fallback
1 parent 8a6ea6d commit df30ade

7 files changed

Lines changed: 280 additions & 33 deletions

File tree

assets/theme-v2/js/login-session.js

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,27 @@ const modeStatus = document.querySelector("[data-login-mode-status]");
1313
const userControls = document.querySelector("[data-login-user-controls]");
1414
const userStatus = document.querySelector("[data-login-user-status]");
1515
const continueLink = document.querySelector("[data-login-continue]");
16+
const staticModeDetails = {
17+
"local-mem": {
18+
description: "Uses MockDbAdapter backed by in-memory lists when the API-backed local server is running.",
19+
diagnostic: "Static-only server detected. Local Mem selection remains available, but local users and persistence require the API-backed local server.",
20+
environment: "Local Mem",
21+
id: "local-mem",
22+
label: "Local Mem",
23+
persistence: "Memory",
24+
},
25+
"local-db": {
26+
description: "Uses LocalDbAdapter backed by server SQLite storage.",
27+
diagnostic: "Static-only server detected. Local DB requires the API-backed local server; start the local server API to use SQLite-backed Local DB.",
28+
environment: "Local DB",
29+
id: "local-db",
30+
label: "Local DB",
31+
persistence: "Local DB",
32+
},
33+
};
34+
let staticApiUnavailable = false;
35+
let staticModeId = "local-mem";
36+
let staticApiDiagnostic = "";
1637

1738
function currentReturnTo() {
1839
const params = new URLSearchParams(window.location.search);
@@ -91,8 +112,46 @@ function renderModeButtons(mode) {
91112
});
92113
}
93114

115+
function errorMessage(error) {
116+
return error instanceof Error ? error.message : String(error || "Session API unavailable.");
117+
}
118+
119+
function isStaticApiUnavailable(message) {
120+
return message.includes("Local server API route unavailable") ||
121+
message.includes("/api/session") && message.includes("(404)");
122+
}
123+
124+
function renderStaticApiUnavailable(modeId, error) {
125+
const mode = staticModeDetails[modeId] || staticModeDetails["local-mem"];
126+
staticApiUnavailable = true;
127+
staticModeId = mode.id;
128+
staticApiDiagnostic = errorMessage(error);
129+
renderModeButtons(mode);
130+
if (userControls) {
131+
userControls.replaceChildren();
132+
userControls.hidden = true;
133+
}
134+
if (modeTitle) {
135+
modeTitle.textContent = mode.label;
136+
}
137+
if (modeDescription) {
138+
modeDescription.textContent = mode.description;
139+
}
140+
if (modeStatus) {
141+
modeStatus.textContent = `Environment: ${mode.environment}. Persistence: ${mode.persistence}. Diagnostic: ${mode.diagnostic} ${staticApiDiagnostic}`;
142+
}
143+
if (userStatus) {
144+
userStatus.textContent = "No local users are available because the API-backed local server is unavailable.";
145+
}
146+
updateContinueLink();
147+
}
148+
94149
function renderError(error) {
95-
const message = error instanceof Error ? error.message : String(error || "Session API unavailable.");
150+
const message = errorMessage(error);
151+
if (isStaticApiUnavailable(message)) {
152+
renderStaticApiUnavailable(staticModeId, error);
153+
return;
154+
}
96155
modeButtons.forEach((button) => {
97156
button.disabled = false;
98157
button.removeAttribute("aria-disabled");
@@ -119,6 +178,7 @@ function renderError(error) {
119178
function render() {
120179
try {
121180
const session = getSessionCurrent();
181+
staticApiUnavailable = false;
122182
const mode = getSessionModes().find((item) => item.id === session.mode) || {
123183
description: "",
124184
id: session.mode,
@@ -152,11 +212,17 @@ function render() {
152212

153213
modeButtons.forEach((button) => {
154214
button.addEventListener("click", () => {
215+
const modeId = button.dataset.loginMode || "local-mem";
216+
if (staticApiUnavailable) {
217+
renderStaticApiUnavailable(modeId, staticApiDiagnostic);
218+
return;
219+
}
155220
try {
156-
setSessionMode(button.dataset.loginMode || "local-mem");
221+
setSessionMode(modeId);
157222
dispatchModeChanged();
158223
render();
159224
} catch (error) {
225+
staticModeId = modeId;
160226
renderError(error);
161227
}
162228
});

docs_build/dev/reports/coverage_changed_js_guardrail.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Source: Playwright/Chromium built-in V8 coverage from the active Playwright run.
77

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

1212
Guardrail warnings:
1313
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: changed runtime JS file missing from coverage; advisory only

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,38 @@ Note: entry percentages use function coverage when available, otherwise line cov
1212
Note: coverage entries are aggregated across every page/tool where coverageReporter.start(page) and coverageReporter.stop(page) ran.
1313

1414
Exercised tool entry points detected:
15-
(77%) Toolbox Index - exercised 7 runtime JS files
15+
(61%) Toolbox Index - exercised 3 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
17-
(73%) Theme V2 Shared JS - exercised 2 runtime JS files
17+
(79%) Theme V2 Shared JS - exercised 3 runtime JS files
1818

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

2323
Files with executed line/function counts where available:
24-
(63%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 12/19
24+
(53%) src/engine/api/server-api-client.js - executed lines 159/159; executed functions 10/19
25+
(55%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 54/99
26+
(60%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 3/5
2527
(64%) assets/theme-v2/js/tool-display-mode.js - executed lines 201/201; executed functions 9/14
2628
(67%) admin/db-viewer.js - executed lines 53/53; executed functions 4/6
27-
(69%) toolbox/colors/colors.js - executed lines 877/877; executed functions 62/90
28-
(75%) toolbox/project-journey/project-journey.js - executed lines 1003/1003; executed functions 74/99
29-
(76%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 421/421; executed functions 29/38
29+
(79%) assets/theme-v2/js/login-session.js - executed lines 227/227; executed functions 15/19
3030
(81%) toolbox/tool-registry-api-client.js - executed lines 148/148; executed functions 22/27
31-
(88%) toolbox/assets/assets.js - executed lines 519/519; executed functions 53/60
32-
(96%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 92/96
33-
(100%) src/engine/api/mock-db-api-client.js - executed lines 19/19; executed functions 5/5
34-
(100%) toolbox/assets/assets-api-client.js - executed lines 17/17; executed functions 3/3
35-
(100%) toolbox/colors/palette-api-client.js - executed lines 19/19; executed functions 4/4
31+
(84%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 421/421; executed functions 32/38
32+
(85%) src/engine/api/mock-db-viewer-ui.js - executed lines 510/510; executed functions 82/96
33+
(88%) src/engine/api/session-api-client.js - executed lines 34/34; executed functions 7/8
3634
(100%) toolbox/project-journey/project-journey-api-client.js - executed lines 12/12; executed functions 2/2
3735

3836
Uncovered or low-coverage changed JS files:
3937
(0%) src/dev-runtime/server/mock-api-router.mjs - WARNING: uncovered changed runtime JS file; advisory only
4038

4139
Changed JS files considered:
42-
(0%) assets/theme-v2/js/login-session.js - changed JS file not collected as browser runtime coverage
4340
(0%) src/dev-runtime/server/mock-api-router.mjs - changed JS file not collected as browser runtime coverage
4441
(0%) tests/helpers/browserExtensionNoise.mjs - changed JS file not collected as browser runtime coverage
45-
(0%) tests/helpers/playwrightRepoServer.mjs - changed JS file not collected as browser runtime coverage
4642
(0%) tests/playwright/tools/AdminDbViewer.spec.mjs - changed JS file not collected as browser runtime coverage
4743
(0%) tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs - changed JS file not collected as browser runtime coverage
4844
(0%) tests/playwright/tools/LoginSessionMode.spec.mjs - changed JS file not collected as browser runtime coverage
45+
(0%) tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs - changed JS file not collected as browser runtime coverage
4946
(0%) tests/playwright/tools/ToolboxRoutePages.spec.mjs - changed JS file not collected as browser runtime coverage
50-
(63%) src/engine/api/server-api-client.js - changed JS file with browser V8 coverage
51-
(76%) assets/theme-v2/js/gamefoundry-partials.js - changed JS file with browser V8 coverage
47+
(53%) src/engine/api/server-api-client.js - changed JS file with browser V8 coverage
48+
(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
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# PR_26158_030 Static Server Login Fallback Report
2+
3+
## Summary
4+
5+
Added a UI-only static-server login fallback so `127.0.0.1:5500`-style static serving keeps Local Mem selectable while showing Local DB as API-required.
6+
7+
## Artifact
8+
9+
- Delta ZIP: `tmp/PR_26158_030-static-server-login-fallback_delta.zip`
10+
11+
## Requirement Checklist
12+
13+
| Requirement | Status | Evidence |
14+
| --- | --- | --- |
15+
| Read `docs_build/dev/PROJECT_INSTRUCTIONS.md` first. | PASS | Read before edits. |
16+
| Fix static-only local serving from `127.0.0.1:5500` so `/api/session/current` 404 does not leave login modes disabled. | PASS | `assets/theme-v2/js/login-session.js` renders a static API-unavailable mode state, and `StaticOnlyLoginFallback.spec.mjs` verifies both mode buttons are enabled on a static-only `127.0.0.1` server with missing `/api`. |
17+
| Local Mem remains enabled and clickable when the API server is unavailable. | PASS | Static-only Playwright clicks Local Mem and verifies it remains selected with an actionable API-backed server diagnostic. |
18+
| Local DB shows a visible actionable diagnostic when API server is unavailable. | PASS | Static-only Playwright clicks Local DB and verifies the status says Local DB requires the API-backed local server for SQLite-backed Local DB. |
19+
| Fix or remove repo-owned dependency causing `ShowOneChild.js` to throw `ActionableCoachmark is not defined`. | PASS | No active repo runtime dependency was found. No global was added. |
20+
| If `ShowOneChild.js` is not repo-owned, prove that in report and do not mask repo-owned errors. | PASS | Focused search over active runtime roots found no `ShowOneChild` or `ActionableCoachmark`. `tests/helpers/browserExtensionNoise.mjs` now requires extension URL schemes before ignoring named script noise. |
21+
| Preserve SQLite-backed Local DB behind API boundary when API server is running. | PASS | `LoginSessionMode.spec.mjs` passed 5/5 in API-backed mode; Local DB still resolves through API routes. |
22+
| Do not add UAT/Prod API adapter behavior. | PASS | No adapter behavior was added. |
23+
| Do not expose UAT or Prod as local login choices. | PASS | LoginSessionMode and static-only login coverage assert UAT/Prod controls are absent. |
24+
| Do not modify `start_of_day` folders. | PASS | Changed-file list contains no `start_of_day` paths. |
25+
| Run changed-file syntax checks. | PASS | `node --check` passed for changed JS/spec files. |
26+
| Run LoginSessionMode Playwright in API-backed mode. | PASS | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` passed 5/5. |
27+
| Add/run static-only login Playwright coverage for `127.0.0.1:5500`-style behavior with missing API. | PASS | `npx playwright test tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` passed 1/1. |
28+
| Run ToolboxRoutePages Playwright. | PASS | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` passed 1/1. |
29+
| Do not run full samples smoke unless directly impacted. | PASS | Full samples smoke skipped because no samples or shared sample loader/framework changed. |
30+
31+
## Files Changed
32+
33+
- `assets/theme-v2/js/login-session.js`
34+
- `tests/helpers/browserExtensionNoise.mjs`
35+
- `tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs`
36+
- `docs_build/dev/reports/testing_lane_execution_report.md`
37+
- `docs_build/dev/reports/static-server-login-fallback-report.md`
38+
- `docs_build/dev/reports/playwright_v8_coverage_report.txt`
39+
- `docs_build/dev/reports/coverage_changed_js_guardrail.txt`
40+
- `docs_build/dev/reports/codex_review.diff`
41+
- `docs_build/dev/reports/codex_changed_files.txt`
42+
43+
## Validation Commands
44+
45+
| Command | Result |
46+
| --- | --- |
47+
| `node --check assets/theme-v2/js/login-session.js` | PASS |
48+
| `node --check tests/helpers/browserExtensionNoise.mjs` | PASS |
49+
| `node --check tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS |
50+
| `npx playwright test tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS, 1/1 |
51+
| `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS, 5/5 |
52+
| `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 |
53+
| `git diff --check` | PASS, with Git line-ending warnings only |
54+
55+
## Notes
56+
57+
- The static fallback is intentionally UI-only. It does not create local users, authenticate Guest, or persist data without the API-backed local server.
58+
- Node emitted the standard experimental warning for `node:sqlite` during API-backed Playwright lanes; validation passed.
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
# PR_26158_029 Testing Lane Execution Report
1+
# PR_26158_030 Testing Lane Execution Report
22

33
## Lanes Run
44

55
| Lane | Command | Result |
66
| --- | --- | --- |
7-
| Changed-file syntax | `node --check assets/theme-v2/js/gamefoundry-partials.js`; `node --check src/engine/api/server-api-client.js`; `node --check src/dev-runtime/server/mock-api-router.mjs`; `node --check tests/helpers/browserExtensionNoise.mjs`; `node --check tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs`; `node --check tests/playwright/tools/LoginSessionMode.spec.mjs`; `node --check tests/playwright/tools/ToolboxRoutePages.spec.mjs`; `node --check tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS |
8-
| Local API route validation | `npx playwright test tests/playwright/tools/ApiStaticRouteRecovery.spec.mjs` | PASS, 1/1 |
7+
| Changed-file syntax | `node --check assets/theme-v2/js/login-session.js`; `node --check tests/helpers/browserExtensionNoise.mjs`; `node --check tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS |
8+
| Static-only login Playwright | `npx playwright test tests/playwright/tools/StaticOnlyLoginFallback.spec.mjs` | PASS, 1/1 |
99
| LoginSessionMode Playwright | `npx playwright test tests/playwright/tools/LoginSessionMode.spec.mjs` | PASS, 5/5 |
1010
| ToolboxRoutePages Playwright | `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs` | PASS, 1/1 |
11-
| AdminDbViewer Playwright | `npx playwright test tests/playwright/tools/AdminDbViewer.spec.mjs` | PASS, 7/7 |
1211
| Changed-file/static validation | `git diff --check` | PASS, with Git line-ending warnings only |
13-
| Runtime JS V8 coverage | Playwright coverage generated by targeted runs | PASS/WARN; `docs_build/dev/reports/playwright_v8_coverage_report.txt` lists changed runtime JS coverage. `src/dev-runtime/server/mock-api-router.mjs` is server-side and reported as advisory WARN. |
12+
| Runtime JS V8 coverage | Playwright coverage generated by targeted runs | PASS/WARN; `docs_build/dev/reports/playwright_v8_coverage_report.txt` lists `assets/theme-v2/js/login-session.js` runtime coverage. |
1413

1514
## Validation Notes
1615

1716
| Check | Evidence | Result |
1817
| --- | --- | --- |
19-
| Login/session local API routes avoid 404/405 on supported local server calls. | `ApiStaticRouteRecovery.spec.mjs` validates `HEAD /api/session/current`, `OPTIONS /api/session/mode`, GET current/modes/users, and POST mode/user/logout. | PASS |
20-
| Local Mem and Local DB remain enabled/clickable. | LoginSessionMode and ApiStaticRouteRecovery assert Local Mem/Local DB controls are enabled. | PASS |
21-
| SQLite-backed Local DB remains behind the API boundary. | LoginSessionMode Local DB flow and AdminDbViewer Local DB readonly/diagnostic tests passed. | PASS |
22-
| `/tools/.../index.html` route pages still render content. | ToolboxRoutePages opens Project Journey, Colors, and Assets aliases with no failed requests. | PASS |
23-
| Extension script noise is ignored without masking repo global pollution. | Active runtime search found no `ShowOneChild` or `ActionableCoachmark`; Playwright filters only known extension script names and does not ignore bare `ActionableCoachmark` repo errors. | PASS |
24-
| UAT/Prod remain absent from local login choices. | LoginSessionMode and ApiStaticRouteRecovery assert UAT/Prod buttons are absent. | PASS |
18+
| Static-only login keeps Local Mem enabled and clickable when `/api/session/current` 404s. | `StaticOnlyLoginFallback.spec.mjs` serves `login.html` from a static-only `127.0.0.1` server and verifies Local Mem remains enabled, selected, and clickable after API 404s. | PASS |
19+
| Static-only Local DB shows visible actionable diagnostic. | `StaticOnlyLoginFallback.spec.mjs` clicks Local DB and verifies the status text says Local DB requires the API-backed local server for SQLite-backed Local DB. | PASS |
20+
| API-backed Local Mem and Local DB behavior still works. | `LoginSessionMode.spec.mjs` passed 5/5. | PASS |
21+
| Toolbox route pages still render. | `ToolboxRoutePages.spec.mjs` passed 1/1 for Project Journey, Colors, and Assets `/tools/...` aliases. | PASS |
22+
| `ShowOneChild.js` is not active repo-owned runtime. | Focused `rg` over active `assets`, `src`, `toolbox`, and `admin` runtime files found no `ShowOneChild` or `ActionableCoachmark` dependency. | PASS |
23+
| Extension-noise filter does not mask repo-owned errors. | `tests/helpers/browserExtensionNoise.mjs` now ignores named scripts only when the error text includes an extension URL scheme. Bare repo-owned `ShowOneChild.js` errors still fail tests. | PASS |
2524

2625
## Skipped Lanes
2726

2827
| Lane | Decision | Reason |
2928
| --- | --- | --- |
29+
| AdminDbViewer Playwright | SKIP | DB route behavior was not changed in this PR; API-backed LoginSessionMode covers Local DB login behavior. |
3030
| Full samples smoke | SKIP | No samples, shared sample loader, or sample framework files changed. |
31-
| Full Playwright suite | SKIP | Targeted API route, login/session, toolbox route, AdminDbViewer, syntax, and static checks cover the changed surfaces. |
31+
| Full Playwright suite | SKIP | Static-only login, API-backed login, toolbox route, syntax, static, and V8 coverage checks cover the changed surfaces. |

tests/helpers/browserExtensionNoise.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@ export function isBrowserExtensionNoise(value) {
1212
}
1313
return text.includes("chrome-extension://") ||
1414
text.includes("moz-extension://") ||
15-
text.includes("extension://") ||
16-
hasKnownScriptName;
15+
text.includes("extension://");
1716
}

0 commit comments

Comments
 (0)