learning_ai_invt_trdg/web/e2e/assistant-positioning.spec.ts
Saravana Achu Mac 79f00214a9 test(ui): add comprehensive Playwright E2E test suite
- Created e2e/alert-positioning.spec.ts for critical alerts positioning tests
- Created e2e/assistant-positioning.spec.ts for assistant widget positioning tests
- Created e2e/destructive-actions.spec.ts for destructive actions confirmation tests
- Created e2e/feedback.spec.ts for save/delete/update feedback tests
- Created e2e/page-states.spec.ts for loading/empty/error/success states tests
- Created e2e/form-validation.spec.ts for form validation tests
- Created e2e/keyboard-navigation.spec.ts for keyboard navigation tests
- Created scripts/tests/run-e2e.sh test runner script with health check
- Updated LAUNCH_READY_UI_UX_ROADMAP.md checklist - all items complete
- All testing infrastructure complete (CI integration replaced with local test runner)
2026-05-09 13:28:20 -07:00

112 lines
3.9 KiB
TypeScript

import { test, expect } from '@playwright/test';
/**
* Assistant Widget Positioning Tests
*
* Tests that assistant widget never covers primary actions
*/
test.describe('Assistant Widget Positioning', () => {
test('ChatControl button does not cover primary actions', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
// ChatControl button is the floating assistant button
const chatButton = page.locator('button:has-text("Bot"), [class*="robot"], [class*="assistant"]');
const buttonCount = await chatButton.count();
if (buttonCount > 0) {
// Get primary action buttons (e.g., in header, main content)
const primaryActions = page.locator('header button, main button[type="submit"], main button:not([variant="ghost"])');
const actionCount = await primaryActions.count();
if (actionCount > 0) {
const chatBox = await chatButton.first().boundingBox();
if (chatBox) {
// Check that chat button is positioned in a corner (bottom-right)
const viewportWidth = await page.evaluate(() => window.innerWidth);
const viewportHeight = await page.evaluate(() => window.innerHeight);
// Chat button should be in bottom-right corner
const inBottomRight = (
chatBox.x + chatBox.width > viewportWidth - 100 &&
chatBox.y + chatBox.height > viewportHeight - 100
);
expect(inBottomRight).toBe(true);
}
}
}
});
test('ChatControl modal has proper z-index and backdrop', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
const chatButton = page.locator('button:has-text("Bot"), [class*="robot"], [class*="assistant"]');
const buttonCount = await chatButton.count();
if (buttonCount > 0) {
// Click to open chat
await chatButton.first().click();
// Wait for modal to appear
await page.waitForTimeout(500);
// Check for backdrop
const backdrop = page.locator('[style*="backdrop"], .backdrop, [style*="blur"]');
const hasBackdrop = await backdrop.count() > 0;
// ChatControl should have backdrop when open
expect(hasBackdrop).toBe(true);
// Check z-index of modal
const modal = page.locator('[role="dialog"], .modal, [style*="fixed"][style*="bottom"]');
const modalCount = await modal.count();
if (modalCount > 0) {
const zIndex = await modal.first().evaluate((el) => {
const computed = window.getComputedStyle(el);
return parseInt(computed.zIndex) || 0;
});
// Modal should have high z-index
expect(zIndex).toBeGreaterThan(1000);
}
}
});
test('ChatControl can be dismissed and does not block primary actions', async ({ page }) => {
await page.goto('/');
await page.waitForLoadState('networkidle');
const chatButton = page.locator('button:has-text("Bot"), [class*="robot"], [class*="assistant"]');
const buttonCount = await chatButton.count();
if (buttonCount > 0) {
// Click to open chat
await chatButton.first().click();
await page.waitForTimeout(500);
// Check if there's a close button
const closeButton = page.locator('button:has-text("Close"), button:has-text("X"), [aria-label="close"]');
const closeCount = await closeButton.count();
if (closeCount > 0) {
await closeButton.first().click();
await page.waitForTimeout(500);
}
// After closing, primary actions should be accessible
const primaryActions = page.locator('header button, main button[type="submit"]');
const actionCount = await primaryActions.count();
if (actionCount > 0) {
await expect(primaryActions.first()).toBeVisible();
await expect(primaryActions.first()).toBeEnabled();
}
}
});
});