aser_slot migration: single-pass expansion, pipe desync fix, _render_to_sx
Three fixes completing the aser_slot migration: 1. Single-pass full-page rendering: eval_sx_url builds layout+content AST and aser_slots it in ONE call — avoids double-aser where re-parsed content hits "Undefined symbol: title/deref" errors. 2. Pipe desync fix: _inject_helpers_locked runs INSIDE the aser_slot lock acquisition (not as a separate lock). Prevents interleaved commands from other coroutines between injection and aser-slot. 3. _render_to_sx uses aser_slot (not aser): layout wrappers like oob_page_sx contain re-parsed content from earlier aser_slot calls. Regular aser fails on symbols that were bound during the earlier expansion. aser_slot handles them correctly. HTMX path: aser_slot the content, then oob_page_sx wraps it. Full page path: build (~shared:layout/app-body :content wrapped_ast), aser_slot in one pass, pass directly to sx_page. New Playwright tests: test_navigate_geography_to_reactive, test_direct_load_reactive_page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -537,6 +537,32 @@ class TestHomePage:
|
||||
assert not fatal, f"JS errors after navigation: {fatal}"
|
||||
|
||||
|
||||
def test_navigate_geography_to_reactive(self, page: Page):
|
||||
"""Click Reactive Islands from Geography — content must render."""
|
||||
errors = []
|
||||
page.on("pageerror", lambda err: errors.append(f"UNCAUGHT: {err.message}"))
|
||||
nav(page, "(geography)")
|
||||
ri_link = page.locator("a[sx-push-url]:has-text('Reactive Islands')").first
|
||||
expect(ri_link).to_be_visible(timeout=10000)
|
||||
ri_link.click()
|
||||
page.wait_for_timeout(5000)
|
||||
expect(page.locator("#main-panel")).to_contain_text("Reactive Islands", 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}"
|
||||
|
||||
def test_direct_load_reactive_page(self, page: Page):
|
||||
"""Direct load of reactive islands page — no errors, content renders."""
|
||||
errors = []
|
||||
page.on("pageerror", lambda err: errors.append(f"UNCAUGHT: {err.message}"))
|
||||
page.on("console", lambda msg: errors.append(msg.text) if msg.type == "error" else None)
|
||||
page.goto(f"{BASE}/sx/(geography.(reactive))", wait_until="networkidle")
|
||||
# aser_slot may take several seconds on first load — wait for render
|
||||
page.wait_for_selector("#main-panel", timeout=30000)
|
||||
expect(page.locator("#main-panel")).to_contain_text("Reactive Islands", timeout=10000)
|
||||
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 reactive page: {fatal}"
|
||||
|
||||
|
||||
class TestDocPages:
|
||||
@pytest.mark.parametrize("path,expected", [
|
||||
("(geography.(reactive))", "Reactive Islands"),
|
||||
|
||||
Reference in New Issue
Block a user