Fix aser server-affinity expansion: keyword values, OOB wrapper, page helpers
Three bugs in aser-expand-component (adapter-sx.sx):
- Keyword values were eval'd (eval-expr can't handle <>, HTML tags);
now asered, matching the aser's rendering capabilities
- Missing default nil binding for unset &key params (caused
"Undefined symbol" errors for optional params like header-rows)
- aserCall string-quoted keyword values that were already serialized
SX — now inlines values starting with "(" directly
Server-affinity annotations for layout/nav shells:
- ~shared:layout/app-body, ~shared:layout/oob-sx — page structure
- ~layouts/nav-sibling-row, ~layouts/nav-children — server-side data
- ~layouts/doc already had :affinity :server
- ~cssx/flush marked :affinity :client (browser-only state)
Navigation fix: restore oob_page_sx wrapper for HTMX responses
so #main-panel section exists for sx-select/sx-swap targeting.
OCaml bridge: lazy page helper injection into kernel via IO proxy
(define name (fn (...) (helper "name" ...))) — enables aser_slot
to evaluate highlight/component-source etc. via coroutine bridge.
Playwright tests: added pageerror listener to test_no_console_errors,
new test_navigate_from_home_to_geography for HTMX nav regression.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@ def nav(page: Page, path: str):
|
||||
"""Navigate to an SX URL and wait for rendered content."""
|
||||
page.goto(f"{BASE}/sx/{path}", wait_until="networkidle")
|
||||
# Wait for SX to render — look for any heading or paragraph in main panel
|
||||
page.wait_for_selector("#main-panel h2, #main-panel p, #main-panel div", timeout=15000)
|
||||
page.wait_for_selector("#main-panel h2, #main-panel p, #main-panel div", timeout=30000)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -506,6 +506,37 @@ class TestSpecExplorer:
|
||||
# Key doc pages (smoke tests)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestHomePage:
|
||||
def test_home_loads(self, page: Page):
|
||||
nav(page, "")
|
||||
expect(page.locator("#main-panel")).to_contain_text("sx", timeout=10000)
|
||||
|
||||
def test_no_console_errors(self, page: Page):
|
||||
"""Home page should have no JS errors (console or uncaught)."""
|
||||
errors = []
|
||||
page.on("console", lambda msg: errors.append(msg.text) if msg.type == "error" else None)
|
||||
page.on("pageerror", lambda err: errors.append(f"UNCAUGHT: {err.message}"))
|
||||
page.goto(f"{BASE}/sx/", wait_until="networkidle")
|
||||
page.wait_for_timeout(3000)
|
||||
fatal = [e for e in errors if "Not callable" in e or "Undefined symbol" in e or "SES_UNCAUGHT" in e or "UNCAUGHT" in e]
|
||||
assert not fatal, f"JS errors on home page: {fatal}"
|
||||
|
||||
def test_navigate_from_home_to_geography(self, page: Page):
|
||||
"""Click Geography nav link from home — content must render."""
|
||||
errors = []
|
||||
page.on("pageerror", lambda err: errors.append(f"UNCAUGHT: {err.message}"))
|
||||
nav(page, "")
|
||||
# Click the Geography link in the nav children
|
||||
geo_link = page.locator("a[sx-push-url]:has-text('Geography')").first
|
||||
expect(geo_link).to_be_visible(timeout=10000)
|
||||
geo_link.click()
|
||||
page.wait_for_timeout(5000)
|
||||
# Content must still be visible after navigation
|
||||
expect(page.locator("#main-panel")).to_contain_text("Geography", timeout=10000)
|
||||
fatal = [e for e in errors if "Not callable" in e or "Undefined symbol" in e or "UNCAUGHT" in e]
|
||||
assert not fatal, f"JS errors after navigation: {fatal}"
|
||||
|
||||
|
||||
class TestDocPages:
|
||||
@pytest.mark.parametrize("path,expected", [
|
||||
("(geography.(reactive))", "Reactive Islands"),
|
||||
|
||||
Reference in New Issue
Block a user