SxExpr aser wire format fix + Playwright test infrastructure + blob protocol
Aser serialization: aser-call/fragment now return SxExpr instead of String. serialize/inspect passes SxExpr through unquoted, preventing the double- escaping (\" → \\\" ) that broke client-side parsing when aser wire format was output via raw! into <script> tags. Added make-sx-expr + sx-expr-source primitives to OCaml and JS hosts. Binary blob protocol: eval, aser, aser-slot, and sx-page-full now send SX source as length-prefixed blobs instead of escaped strings. Eliminates pipe desync from concurrent requests and removes all string-escape round-trips between Python and OCaml. Bridge safety: re-entrancy guard (_in_io_handler) raises immediately if an IO handler tries to call the bridge, preventing silent deadlocks. Fetch error logging: orchestration.sx error callback now logs method + URL via log-warn. Platform catches (fetchAndRestore, fetchPreload, bindBoostForm) also log errors instead of silently swallowing them. Transpiler fixes: makeEnv, scopePeek, scopeEmit, makeSxExpr added as platform function definitions + transpiler mappings — were referenced in transpiled code but never defined as JS functions. Playwright test infrastructure: - nav() captures JS errors and fails fast with the actual error message - Checks for [object Object] rendering artifacts - New tests: delete-row interaction, full page refresh, back button, direct load with fresh context, code block content verification - Default base URL changed to localhost:8013 (standalone dev server) - docker-compose.dev-sx.yml: port 8013 exposed for local testing - test-sx-build.sh: build + unit tests + Playwright smoke tests Geography content: index page component written (sx/sx/geography/index.sx) describing OCaml evaluator, wire formats, rendering pipeline, and topic links. Wiring blocked by aser-expand-component children passing issue. Tests: 1080/1080 JS, 952/952 OCaml, 66/66 Playwright Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
93
test-sx-build.sh
Executable file
93
test-sx-build.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
# test-sx-build.sh — Build sx-browser.js and run all tests.
|
||||
#
|
||||
# Usage:
|
||||
# ./test-sx-build.sh # build + unit tests + playwright smoke
|
||||
# ./test-sx-build.sh --unit-only # build + unit tests only (no server needed)
|
||||
# ./test-sx-build.sh --no-build # skip build, run tests only
|
||||
#
|
||||
# Requires:
|
||||
# - Python 3 with hosts/javascript/cli.py deps
|
||||
# - Node.js for unit tests
|
||||
# - pytest-playwright for browser tests (pip install pytest-playwright)
|
||||
#
|
||||
# Environment:
|
||||
# SX_TEST_BASE — override test server URL (default: https://sx.rose-ash.com)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
UNIT_ONLY=false
|
||||
NO_BUILD=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--unit-only) UNIT_ONLY=true ;;
|
||||
--no-build) NO_BUILD=true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# --- Step 1: Build ---
|
||||
if [ "$NO_BUILD" = false ]; then
|
||||
echo -e "${YELLOW}[1/3] Building sx-browser.js...${NC}"
|
||||
python3 hosts/javascript/cli.py --output shared/static/scripts/sx-browser.js
|
||||
echo -e "${GREEN}Build OK${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}[1/3] Skipping build (--no-build)${NC}"
|
||||
fi
|
||||
|
||||
# --- Step 2: Unit tests ---
|
||||
echo -e "${YELLOW}[2/3] Running JS unit tests...${NC}"
|
||||
UNIT_RESULT=$(node hosts/javascript/run_tests.js --full 2>&1)
|
||||
UNIT_LAST=$(echo "$UNIT_RESULT" | tail -1)
|
||||
if echo "$UNIT_LAST" | grep -q "0 failed"; then
|
||||
echo -e "${GREEN}$UNIT_LAST${NC}"
|
||||
else
|
||||
echo -e "${RED}$UNIT_LAST${NC}"
|
||||
echo "$UNIT_RESULT" | grep "FAIL:" | head -20
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Also run aser tests
|
||||
echo -e "${YELLOW} Running aser tests...${NC}"
|
||||
ASER_RESULT=$(node hosts/javascript/run_tests.js test-aser 2>&1)
|
||||
ASER_LAST=$(echo "$ASER_RESULT" | tail -1)
|
||||
ASER_PASS=$(echo "$ASER_LAST" | grep -oP '\d+ passed' || echo "0 passed")
|
||||
ASER_FAIL=$(echo "$ASER_LAST" | grep -oP '\d+ failed' || echo "0 failed")
|
||||
echo -e "${GREEN} Aser: $ASER_PASS, $ASER_FAIL${NC}"
|
||||
|
||||
# --- Step 3: Playwright smoke tests ---
|
||||
if [ "$UNIT_ONLY" = true ]; then
|
||||
echo -e "${YELLOW}[3/3] Skipping Playwright tests (--unit-only)${NC}"
|
||||
echo -e "${GREEN}All done.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[3/3] Running Playwright smoke tests...${NC}"
|
||||
|
||||
BASE="${SX_TEST_BASE:-http://localhost:8013}"
|
||||
|
||||
# Quick connectivity check
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/sx/" 2>/dev/null || echo "000")
|
||||
if [ "$HTTP_CODE" = "000" ]; then
|
||||
echo -e "${RED}Server unreachable at $BASE — skipping Playwright tests${NC}"
|
||||
echo -e "${YELLOW}Run with SX_TEST_BASE=http://localhost:PORT to test locally${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python3 -m pytest sx/tests/test_demos.py -v -x -k "test_page_loads" --tb=short 2>&1 | tail -20
|
||||
PW_EXIT=${PIPESTATUS[0]}
|
||||
|
||||
if [ "$PW_EXIT" -eq 0 ]; then
|
||||
echo -e "${GREEN}Playwright smoke tests passed${NC}"
|
||||
else
|
||||
echo -e "${RED}Playwright smoke tests failed (exit $PW_EXIT)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}All tests passed.${NC}"
|
||||
Reference in New Issue
Block a user