Fix stepper default: show full "the joy of sx" on load
Root cause: default step-idx was 9, but the expression has 16 steps. At step 9, only "the joy" + empty emerald span renders. Changed default to 16 so all four words display after hydration. Reverted mutable-list changes — (list) already creates ListRef in the OCaml kernel, so append! works correctly with plain (list). Added spec/tests/test-stepper.sx (7 tests) proving the split-tag + steps-to-preview pipeline works correctly at each step boundary. Updated Playwright stepper.spec.js with four tests: - no raw SX visible after hydration - default view shows all four words - all spans inside h1 - stepping forward renders styled text Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,31 +1,81 @@
|
||||
const { test, expect } = require('playwright/test');
|
||||
const { loadPage, trackErrors } = require('./helpers');
|
||||
|
||||
test('home page stepper: no raw SX component calls visible', async ({ page }) => {
|
||||
test('stepper: no raw SX component calls visible after hydration', async ({ page }) => {
|
||||
const t = trackErrors(page);
|
||||
await loadPage(page, '');
|
||||
|
||||
const stepper = page.locator('[data-sx-island="home/stepper"]');
|
||||
await expect(stepper).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// The lake (rendered preview) should NOT show raw component calls
|
||||
const lake = stepper.locator('[data-sx-lake]');
|
||||
await expect(lake).toBeVisible({ timeout: 5000 });
|
||||
const lakeText = await lake.textContent();
|
||||
expect(lakeText).not.toContain('~cssx/tw');
|
||||
expect(lakeText).not.toContain('~tw');
|
||||
expect(lakeText).not.toContain(':tokens');
|
||||
|
||||
// Should show rendered content (colored text)
|
||||
expect(lakeText.length).toBeGreaterThan(5);
|
||||
|
||||
// Stepper navigation should work
|
||||
const buttons = stepper.locator('button');
|
||||
await expect(buttons).toHaveCount(2);
|
||||
const textBefore = await stepper.textContent();
|
||||
await buttons.last().click();
|
||||
await page.waitForTimeout(300);
|
||||
const textAfter = await stepper.textContent();
|
||||
expect(textAfter).not.toBe(textBefore);
|
||||
|
||||
expect(t.errors()).toEqual([]);
|
||||
});
|
||||
|
||||
test('stepper: default view shows all four words', async ({ page }) => {
|
||||
// Clear stepper cookie
|
||||
await page.context().clearCookies();
|
||||
await loadPage(page, '');
|
||||
|
||||
const lake = page.locator('[data-sx-lake="home-preview"]');
|
||||
await expect(lake).toBeVisible({ timeout: 10000 });
|
||||
// Wait for hydration
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const text = await lake.textContent();
|
||||
// All four words should be present after hydration
|
||||
expect(text).toContain('the');
|
||||
expect(text).toContain('joy');
|
||||
expect(text).toContain('of');
|
||||
expect(text).toContain('sx');
|
||||
});
|
||||
|
||||
test('stepper: all spans inside h1 with correct structure', async ({ page }) => {
|
||||
await page.context().clearCookies();
|
||||
await loadPage(page, '');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const lake = page.locator('[data-sx-lake="home-preview"]');
|
||||
const h1 = lake.locator('h1');
|
||||
await expect(h1).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// All colored spans should be inside the h1
|
||||
const spans = h1.locator('span');
|
||||
const count = await spans.count();
|
||||
expect(count).toBeGreaterThanOrEqual(4);
|
||||
});
|
||||
|
||||
test('stepper: stepping forward renders styled text', async ({ page }) => {
|
||||
// Start from step 0
|
||||
await page.context().addCookies([{
|
||||
name: 'sx-home-stepper',
|
||||
value: '0',
|
||||
url: 'http://localhost:8013'
|
||||
}]);
|
||||
await loadPage(page, '');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const fwdBtn = page.locator('button:has-text("▶")');
|
||||
await expect(fwdBtn).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Step forward 10 times to get through "of"
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await fwdBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
}
|
||||
|
||||
const lake = page.locator('[data-sx-lake="home-preview"]');
|
||||
const text = await lake.textContent();
|
||||
expect(text).toContain('of');
|
||||
|
||||
// The "of" text should be in a styled span (with sx- or data-tw class)
|
||||
const styledSpan = lake.locator('span[data-tw]').filter({ hasText: 'of' });
|
||||
const count = await styledSpan.count();
|
||||
expect(count).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user