Spaces:
Running
Running
| # Headless-Chrome smoke test for frontend.html. | |
| # | |
| # Two kinds of checks: | |
| # β’ STATIC β markup that's in the file regardless of rendering (buttons, | |
| # controls). Grepped straight from frontend.html β 100% reliable. | |
| # β’ DYNAMIC β proof the page actually rendered: CodeMirror mounted (its CDN/ESM | |
| # imports ran), the editor wrap was revealed and the textarea fallback hidden. | |
| # These need a real browser, so we render with headless Chrome. | |
| # | |
| # Only the dynamic half can flake (CDN timing), so the headless dump is retried | |
| # until it's complete. Static checks never touch the browser. | |
| # | |
| # Usage: ./smoke-test.sh (exit 0 = pass, 1 = fail) | |
| set -euo pipefail | |
| cd "$(dirname "$0")" | |
| FILE="frontend.html" | |
| src="$(cat "$FILE")" | |
| CHROME="${CHROME:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}" | |
| [ -x "$CHROME" ] || { echo "β Chrome not found at: $CHROME (set \$CHROME)"; exit 1; } | |
| # Retry the dump until it's a COMPLETE render (has </html> AND the CodeMirror | |
| # mount), up to 5 attempts β guards against partial/pre-render dumps. | |
| dom="" | |
| for attempt in 1 2 3 4 5; do | |
| dom="$("$CHROME" --headless --disable-gpu --no-sandbox \ | |
| --virtual-time-budget=25000 \ | |
| --dump-dom "file://$PWD/$FILE" 2>/dev/null)" | |
| if grep -q '</html>' <<<"$dom" && grep -q 'class="cm-editor' <<<"$dom"; then | |
| break | |
| fi | |
| [ "$attempt" -lt 5 ] && { echo "β¦ incomplete render (attempt $attempt), retrying"; sleep 1; } | |
| done | |
| fail=0 | |
| chk() { # chk "<haystack>" "<label>" "<grep -E pattern>" "<want: yes|no>" | |
| # here-string (not echo|grep): with `set -o pipefail`, grep -q matching closes | |
| # the pipe early β echo gets SIGPIPE β the pipeline falsely reports failure. | |
| if grep -qE "$3" <<<"$1"; then found=yes; else found=no; fi | |
| if [ "$found" = "$4" ]; then echo "β $2"; else echo "β $2 (wanted match=$4, got=$found)"; fail=1; fi | |
| } | |
| static() { chk "$src" "$1" "$2" "$3"; } # grep the source file | |
| dynamic(){ chk "$dom" "$1" "$2" "$3"; } # grep the rendered DOM | |
| echo "β dynamic (needs a real render) β" | |
| dynamic "editor mounted (.cm-editor present)" 'class="cm-editor' yes | |
| dynamic "line-number gutter rendered" 'class="cm-gutterElement' yes | |
| dynamic "editor-wrap revealed by JS (not hidden)" '<div id="editor-wrap" class="editor-wrap">' yes | |
| dynamic "textarea fallback hidden by JS" '<textarea id="code-fallback"[^>]*hidden' yes | |
| echo "β static (markup in the file) β" | |
| static "language selector present" 'id="lang-select"' yes | |
| static "Copy / Clear buttons present" 'id="copy-btn".*|id="clear-btn"' yes | |
| static "Generate is compact (in action bar)" '<button id="submit-btn" class="btn-primary"' yes | |
| static "output toolbar present (Copy Mermaid)" 'id="copy-mmd-btn"' yes | |
| static "SVG / PNG export buttons present" 'id="svg-btn".*|id="png-btn"' yes | |
| static "export buttons disabled until a render" '<button id="svg-btn"[^>]*disabled' yes | |
| static "theme toggle present" 'id="theme-toggle"' yes | |
| static "zoom controls present" 'id="zoom-ctrl"' yes | |
| static "flow-arrow cue present" 'class="flow-arrow"' yes | |
| echo | |
| [ "$fail" -eq 0 ] && echo "PASS" || echo "FAIL" | |
| exit "$fail" | |