Stricter isomorphic test: exact DOM structure + text comparison
Test 2 now compares JSON.stringify of the full DOM tree structure (tags, ids, classes, island markers, lake markers) and exact text content between JS-disabled and JS-enabled renders. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,37 +85,29 @@ test.describe('Isomorphic SSR', () => {
|
|||||||
await context.close();
|
await context.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('page renders with JavaScript and matches SSR structure', async ({ browser }) => {
|
test('JS and no-JS render the same DOM structure and styles', async ({ browser }) => {
|
||||||
// First: get SSR content (no JS)
|
// Get SSR DOM (no JS)
|
||||||
const noJsContext = await browser.newContext({ javaScriptEnabled: false });
|
const noJsContext = await browser.newContext({ javaScriptEnabled: false });
|
||||||
const noJsPage = await noJsContext.newPage();
|
const noJsPage = await noJsContext.newPage();
|
||||||
await noJsPage.goto(BASE_URL + TEST_PAGE, { waitUntil: 'domcontentloaded' });
|
await noJsPage.goto(BASE_URL + TEST_PAGE, { waitUntil: 'domcontentloaded' });
|
||||||
const ssrText = await getSxRootText(noJsPage);
|
|
||||||
const ssrStructure = await getSxRootStructure(noJsPage);
|
const ssrStructure = await getSxRootStructure(noJsPage);
|
||||||
|
const ssrText = await getSxRootText(noJsPage);
|
||||||
await noJsContext.close();
|
await noJsContext.close();
|
||||||
|
|
||||||
// Then: get client-rendered content (with JS)
|
// Get client DOM (with JS)
|
||||||
const jsContext = await browser.newContext({ javaScriptEnabled: true });
|
const jsContext = await browser.newContext({ javaScriptEnabled: true });
|
||||||
const jsPage = await jsContext.newPage();
|
const jsPage = await jsContext.newPage();
|
||||||
await jsPage.goto(BASE_URL + TEST_PAGE, { waitUntil: 'networkidle' });
|
await jsPage.goto(BASE_URL + TEST_PAGE, { waitUntil: 'networkidle' });
|
||||||
// Wait for islands to hydrate
|
await jsPage.waitForTimeout(2000); // wait for hydration
|
||||||
await jsPage.waitForSelector('[data-sx-island].sx-processed', { timeout: 10000 }).catch(() => {});
|
const clientStructure = await getSxRootStructure(jsPage);
|
||||||
await jsPage.waitForTimeout(500); // settle
|
|
||||||
|
|
||||||
const clientText = await getSxRootText(jsPage);
|
const clientText = await getSxRootText(jsPage);
|
||||||
await jsContext.close();
|
await jsContext.close();
|
||||||
|
|
||||||
// Text content should be the same (article text, headings, etc)
|
// Text content must match
|
||||||
expect(ssrText.length).toBeGreaterThan(100);
|
expect(ssrText).toBe(clientText);
|
||||||
expect(clientText.length).toBeGreaterThan(100);
|
|
||||||
|
|
||||||
// The core content should match — both should have the article headings
|
// Structure must match — same tags, ids, classes
|
||||||
expect(clientText).toContain('Language games');
|
expect(JSON.stringify(ssrStructure)).toBe(JSON.stringify(clientStructure));
|
||||||
expect(clientText).toContain('The limits of my language');
|
|
||||||
|
|
||||||
// SSR should also have these
|
|
||||||
expect(ssrText).toContain('Language games');
|
|
||||||
expect(ssrText).toContain('The limits of my language');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('header island has CSSX styling without JavaScript', async ({ browser }) => {
|
test('header island has CSSX styling without JavaScript', async ({ browser }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user