Some checks failed
Deploy Application / deploy (push) Has been cancelled
229 lines
6.4 KiB
TypeScript
229 lines
6.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
/**
|
|
* LiveComponents: Target Support Tests
|
|
*
|
|
* Tests data-lc-target attribute for updating elements outside the component
|
|
*/
|
|
test.describe('LiveComponents Target Support', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/');
|
|
});
|
|
|
|
test('should update target element within component', async ({ page }) => {
|
|
// Find a component with a button that has data-lc-target
|
|
const targetButton = page.locator('[data-lc-target]').first();
|
|
const count = await targetButton.count();
|
|
|
|
if (count === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Get target selector
|
|
const targetSelector = await targetButton.getAttribute('data-lc-target');
|
|
if (!targetSelector) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Find target element
|
|
const targetElement = page.locator(targetSelector).first();
|
|
const targetExists = await targetElement.count() > 0;
|
|
|
|
if (!targetExists) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Get initial content
|
|
const initialContent = await targetElement.textContent();
|
|
|
|
// Click button
|
|
await targetButton.click();
|
|
|
|
// Wait for update
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Target should still exist and be visible
|
|
expect(targetElement).toBeVisible();
|
|
});
|
|
|
|
test('should update target element outside component', async ({ page }) => {
|
|
// This test requires a component that updates an element outside itself
|
|
// Look for a component with data-lc-target pointing to an element outside
|
|
const components = page.locator('[data-live-component]');
|
|
const componentCount = await components.count();
|
|
|
|
if (componentCount === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Find a button with data-lc-target that points outside its component
|
|
const buttons = page.locator('[data-live-action][data-lc-target]');
|
|
const buttonCount = await buttons.count();
|
|
|
|
if (buttonCount === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Test first button
|
|
const button = buttons.first();
|
|
const targetSelector = await button.getAttribute('data-lc-target');
|
|
|
|
if (!targetSelector) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Find target element (should exist in document)
|
|
const targetElement = page.locator(targetSelector).first();
|
|
const targetExists = await targetElement.count() > 0;
|
|
|
|
if (!targetExists) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Get component element
|
|
const component = button.locator('xpath=ancestor::*[@data-live-component][1]').first();
|
|
const componentExists = await component.count() > 0;
|
|
|
|
// Check if target is outside component (if component found)
|
|
if (componentExists) {
|
|
const targetInComponent = await component.locator(targetSelector).count() > 0;
|
|
|
|
// If target is inside component, skip this test (tested in previous test)
|
|
if (targetInComponent) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Get initial content
|
|
const initialContent = await targetElement.textContent();
|
|
|
|
// Click button
|
|
await button.click();
|
|
|
|
// Wait for update
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Target should still exist and be visible
|
|
expect(targetElement).toBeVisible();
|
|
});
|
|
|
|
test('should fallback to component element if target not found', async ({ page }) => {
|
|
// This test requires a component with an invalid target selector
|
|
// Since we can't easily create invalid selectors in tests, we'll test the fallback behavior
|
|
const components = page.locator('[data-live-component]');
|
|
const componentCount = await components.count();
|
|
|
|
if (componentCount === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Find any action button
|
|
const actionButton = page.locator('[data-live-action]').first();
|
|
const buttonCount = await actionButton.count();
|
|
|
|
if (buttonCount === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Get component
|
|
const component = actionButton.locator('xpath=ancestor::*[@data-live-component][1]').first();
|
|
const componentId = await component.getAttribute('data-live-component');
|
|
|
|
if (!componentId) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Click button (should work even if target not found - falls back to component)
|
|
await actionButton.click();
|
|
|
|
// Wait for update
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Component should still exist
|
|
expect(component).toBeVisible();
|
|
});
|
|
|
|
test('should support CSS selector targets', async ({ page }) => {
|
|
// Test ID selector
|
|
const idTargetButton = page.locator('[data-lc-target^="#"]').first();
|
|
const idCount = await idTargetButton.count();
|
|
|
|
if (idCount > 0) {
|
|
const targetId = await idTargetButton.getAttribute('data-lc-target');
|
|
const targetElement = page.locator(targetId || '').first();
|
|
|
|
if (await targetElement.count() > 0) {
|
|
await idTargetButton.click();
|
|
await page.waitForTimeout(1000);
|
|
expect(targetElement).toBeVisible();
|
|
}
|
|
}
|
|
|
|
// Test class selector
|
|
const classTargetButton = page.locator('[data-lc-target^="."]').first();
|
|
const classCount = await classTargetButton.count();
|
|
|
|
if (classCount > 0) {
|
|
const targetClass = await classTargetButton.getAttribute('data-lc-target');
|
|
const targetElement = page.locator(targetClass || '').first();
|
|
|
|
if (await targetElement.count() > 0) {
|
|
await classTargetButton.click();
|
|
await page.waitForTimeout(1000);
|
|
expect(targetElement).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('should combine target with swap strategies', async ({ page }) => {
|
|
// Find a button with both data-lc-target and data-lc-swap
|
|
const combinedButton = page.locator('[data-lc-target][data-lc-swap]').first();
|
|
const count = await combinedButton.count();
|
|
|
|
if (count === 0) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
const targetSelector = await combinedButton.getAttribute('data-lc-target');
|
|
const swapStrategy = await combinedButton.getAttribute('data-lc-swap');
|
|
|
|
if (!targetSelector || !swapStrategy) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
const targetElement = page.locator(targetSelector).first();
|
|
const targetExists = await targetElement.count() > 0;
|
|
|
|
if (!targetExists) {
|
|
test.skip();
|
|
return;
|
|
}
|
|
|
|
// Click button
|
|
await combinedButton.click();
|
|
|
|
// Wait for update
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Target should still exist (swap strategy applied)
|
|
expect(targetElement).toBeVisible();
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|