diff --git a/check-linuxcnc-browser-app-source-map.sh b/check-linuxcnc-browser-app-source-map.sh index bb54b39..d13a684 100755 --- a/check-linuxcnc-browser-app-source-map.sh +++ b/check-linuxcnc-browser-app-source-map.sh @@ -66,6 +66,8 @@ grep -F 'app frame did not persist LinuxCNC parameter backup into OPFS' \ grep -F 'OPFS PROGRAM RESTORED' web/test-browser-wasm-smoke-app-sections.js >/dev/null grep -F 'app frame did not reload LinuxCNC parameter state from OPFS after reload' \ web/test-browser-wasm-smoke-app-sections.js >/dev/null +grep -F 'runSection("browser app opfs save"' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("browser app opfs restore"' test-web-wasm-browser-smoke.sh >/dev/null if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|showDirectoryPicker|webkitRequestFileSystem|FileReader' web/src; then echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 diff --git a/check-linuxcnc-opfs-source-map.sh b/check-linuxcnc-opfs-source-map.sh index cbe5301..2c58418 100755 --- a/check-linuxcnc-opfs-source-map.sh +++ b/check-linuxcnc-opfs-source-map.sh @@ -44,6 +44,9 @@ grep -F 'OPFS cannot be disabled in browser contexts with OPFS support' web/src/ grep -F 'const events = await simulator.parseFileWithParameterFile(programPath, parameterPath, "linuxcnc", parseOptions);' \ web/src/app.js >/dev/null grep -F 'OPFS workspace is required for browser program parsing' web/src/app.js >/dev/null +grep -F 'runSection("opfs parameter restore in new instance"' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("opfs invalid parameter restore failures"' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("opfs stale parameter state cleanup"' test-web-wasm-browser-smoke.sh >/dev/null if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|showDirectoryPicker|webkitRequestFileSystem|FileReader' web/src; then echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 diff --git a/check-linuxcnc-wasm-smoke-source-map.sh b/check-linuxcnc-wasm-smoke-source-map.sh index 55ae506..4fbd002 100755 --- a/check-linuxcnc-wasm-smoke-source-map.sh +++ b/check-linuxcnc-wasm-smoke-source-map.sh @@ -81,6 +81,10 @@ grep -F 'minimum_sections=${BROWSER_SMOKE_MIN_SECTIONS:-50}' test-web-wasm-brows grep -F 'BROWSER_SMOKE_MIN_SECTIONS must be a positive integer' test-web-wasm-browser-smoke.sh >/dev/null grep -F 'browser WASM smoke covered $passed_sections sections, expected at least $minimum_sections' \ test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'required_browser_sections = {' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("linuxcnc generated switchkins cases load"' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("opfs parameter restore in new instance"' test-web-wasm-browser-smoke.sh >/dev/null +grep -F 'runSection("browser app opfs restore"' test-web-wasm-browser-smoke.sh >/dev/null grep -F 'runLinuxCncBrowserSections(context, simulator)' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runBrowserOpfsWorkspaceSections(context, simulator)' web/test-browser-wasm-smoke-sections.js >/dev/null grep -F 'runBrowserAppOpfsSections(context)' web/test-browser-wasm-smoke-sections.js >/dev/null @@ -140,6 +144,7 @@ required_phrases = [ "persistence OPFS-only", "Node smoke must leave OPFS disabled", "Generated switchkins config smoke cases", + "browser smoke shell guard also pins required section names", "./check-linuxcnc-wasm-smoke-source-map.sh", ] for phrase in required_phrases: diff --git a/docs/linuxcnc-wasm-smoke-source-map.md b/docs/linuxcnc-wasm-smoke-source-map.md index b8bd582..2c9d636 100644 --- a/docs/linuxcnc-wasm-smoke-source-map.md +++ b/docs/linuxcnc-wasm-smoke-source-map.md @@ -42,6 +42,9 @@ OPFS-only is the required boundary. `.new` files, and `.bak` backups under OPFS-backed storage. - Generated switchkins config smoke cases must continue to come from `web/public/linuxcnc_switchkins_remap_config_cases.json`. +- The browser smoke shell guard also pins required section names for LinuxCNC + browser parsing, OPFS parameter restore/save failure handling, and browser + app OPFS reload coverage. - Smoke wrappers must keep positive minimum coverage thresholds so accidental section loss is visible. diff --git a/test-web-wasm-browser-smoke.sh b/test-web-wasm-browser-smoke.sh index 31d3477..986e27d 100755 --- a/test-web-wasm-browser-smoke.sh +++ b/test-web-wasm-browser-smoke.sh @@ -160,6 +160,32 @@ for imported_module in ( if f'from "{imported_module}"' not in opfs_workspace: print(f"browser smoke OPFS workspace module must import {imported_module}", file=sys.stderr) sys.exit(1) +required_browser_sections = { + "web/test-browser-wasm-smoke-linuxcnc-sections.js": ( + 'runSection("linuxcnc browser basic parse"', + 'runSection("linuxcnc generated switchkins cases load"', + 'runSection("linuxcnc browser parse parameter scratch cleanup"', + ), + "web/test-browser-wasm-smoke-opfs-basic-sections.js": ( + 'runSection("opfs program parse and restore"', + ), + "web/test-browser-wasm-smoke-opfs-parameter-sections.js": ( + 'runSection("opfs parameter restore in new instance"', + 'runSection("opfs default parameter backup"', + 'runSection("opfs invalid parameter restore failures"', + 'runSection("opfs stale parameter state cleanup"', + ), + "web/test-browser-wasm-smoke-app-sections.js": ( + 'runSection("browser app opfs save"', + 'runSection("browser app opfs restore"', + ), +} +for section_module, required_sections in required_browser_sections.items(): + section_text = Path(section_module).read_text(encoding="utf-8") + for required_section in required_sections: + if required_section not in section_text: + print(f"browser smoke module {section_module} missing required section {required_section}", file=sys.stderr) + sys.exit(1) app_html = Path("web/index.html").read_text(encoding="utf-8") if '' not in app_html: print("browser app HTML must load /styles.css", file=sys.stderr)