CodeFlow / smoke-test.sh
Rishi-Jain-27's picture
Completed HTML frontend
42bbd85
#!/usr/bin/env bash
# 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"