import { test, expect } from '@playwright/test'; /** * LiveComponents: Swap Strategies Tests * * Tests different swap strategies (innerHTML, outerHTML, beforebegin, afterbegin, afterend, beforeend, none) */ test.describe('LiveComponents Swap Strategies', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); }); test('should support innerHTML swap (default)', async ({ page }) => { // This test assumes there's a component with a button that uses innerHTML swap // Since we don't have a test page yet, we'll skip if no components found const components = page.locator('[data-live-component]'); const count = await components.count(); if (count === 0) { test.skip(); return; } // Find a button with data-live-action const actionButton = page.locator('[data-live-action]').first(); const buttonCount = await actionButton.count(); if (buttonCount === 0) { test.skip(); return; } // Get initial HTML const component = components.first(); const initialHtml = await component.innerHTML(); // Click button (should use innerHTML by default) await actionButton.click(); // Wait for update await page.waitForTimeout(1000); // HTML should have changed (or stayed same if no update) const newHtml = await component.innerHTML(); // At minimum, the action should have executed expect(component).toBeVisible(); }); test('should support outerHTML swap', async ({ page }) => { // This test requires a component with data-lc-swap="outerHTML" const swapButton = page.locator('[data-lc-swap="outerHTML"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const targetElement = swapButton.first(); const initialTag = await targetElement.evaluate(el => el.tagName); // Click to trigger swap await targetElement.click(); // Wait for update await page.waitForTimeout(1000); // Element should be replaced (tag might change) const newElement = page.locator(swapButton.first().locator('xpath=..')).first(); expect(newElement).toBeVisible(); }); test('should support beforebegin swap', async ({ page }) => { const swapButton = page.locator('[data-lc-swap="beforebegin"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const button = swapButton.first(); const parent = button.locator('xpath=..'); // Get initial child count const initialChildCount = await parent.evaluate(el => el.children.length); // Click to trigger swap await button.click(); // Wait for update await page.waitForTimeout(1000); // Should have more children (content inserted before button) const newChildCount = await parent.evaluate(el => el.children.length); expect(newChildCount).toBeGreaterThanOrEqual(initialChildCount); }); test('should support afterbegin swap', async ({ page }) => { const swapButton = page.locator('[data-lc-swap="afterbegin"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const button = swapButton.first(); const target = page.locator(button.getAttribute('data-lc-target') || '[data-live-component]').first(); // Get initial first child const initialFirstChild = await target.evaluate(el => el.firstElementChild?.tagName); // Click to trigger swap await button.click(); // Wait for update await page.waitForTimeout(1000); // First child should have changed or new content added const newFirstChild = await target.evaluate(el => el.firstElementChild?.tagName); expect(target).toBeVisible(); }); test('should support afterend swap', async ({ page }) => { const swapButton = page.locator('[data-lc-swap="afterend"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const button = swapButton.first(); const parent = button.locator('xpath=..'); // Get initial child count const initialChildCount = await parent.evaluate(el => el.children.length); // Click to trigger swap await button.click(); // Wait for update await page.waitForTimeout(1000); // Should have more children (content inserted after button) const newChildCount = await parent.evaluate(el => el.children.length); expect(newChildCount).toBeGreaterThanOrEqual(initialChildCount); }); test('should support beforeend swap', async ({ page }) => { const swapButton = page.locator('[data-lc-swap="beforeend"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const button = swapButton.first(); const target = page.locator(button.getAttribute('data-lc-target') || '[data-live-component]').first(); // Get initial last child const initialLastChild = await target.evaluate(el => el.lastElementChild?.tagName); // Click to trigger swap await button.click(); // Wait for update await page.waitForTimeout(1000); // Last child should have changed or new content added const newLastChild = await target.evaluate(el => el.lastElementChild?.tagName); expect(target).toBeVisible(); }); test('should support none swap (no DOM update)', async ({ page }) => { const swapButton = page.locator('[data-lc-swap="none"]'); const count = await swapButton.count(); if (count === 0) { test.skip(); return; } const button = swapButton.first(); const target = page.locator(button.getAttribute('data-lc-target') || '[data-live-component]').first(); // Get initial HTML const initialHtml = await target.innerHTML(); // Click to trigger action (should not update DOM) await button.click(); // Wait a bit await page.waitForTimeout(1000); // HTML should remain the same (no DOM update) const newHtml = await target.innerHTML(); expect(newHtml).toBe(initialHtml); }); });