- Added real-time updates tests (LiveView connection, live data updates) - Added pagination and sorting tests (page navigation, table sorting, URL params) - Added notifications tests (flash messages, toasts, in-app notifications) - Added session management tests (active sessions, logout, concurrent sessions) - Added accessibility tests (keyboard nav, ARIA labels, screen reader support) Covers: - LiveView real-time features and reconnection - Pagination controls and sorting on all list pages - Flash messages, toasts, and notification preferences - Session security and multi-device management - Basic WCAG compliance (keyboard, labels, roles)
146 lines
4.6 KiB
TypeScript
146 lines
4.6 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Real-Time Updates (LiveView)', () => {
|
|
test.describe('Dashboard Live Updates', () => {
|
|
test('dashboard loads and displays initial data', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows live status indicators', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
// Look for status indicators that update in real-time
|
|
const statusIndicator = page.locator(
|
|
'[data-status], .status, :has-text("Online"), :has-text("Offline")'
|
|
).first();
|
|
|
|
if (await statusIndicator.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(statusIndicator).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows device count that updates live', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
const deviceCount = page.locator(
|
|
'[data-count], :has-text("device"), .metric'
|
|
).first();
|
|
|
|
if (await deviceCount.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(deviceCount).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows alert count that updates live', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
const alertCount = page.locator(
|
|
'[data-alert-count], :has-text("alert"), .badge'
|
|
).first();
|
|
|
|
if (await alertCount.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(alertCount).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Device List Live Updates', () => {
|
|
test('device list shows live status changes', async ({ page }) => {
|
|
await page.goto('/devices');
|
|
|
|
// Wait a moment for any live updates
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Status indicators should be present
|
|
const statusIndicators = page.locator('[data-status], .status');
|
|
|
|
if ((await statusIndicators.count()) > 0) {
|
|
await expect(statusIndicators.first()).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('last seen timestamps update automatically', async ({ page }) => {
|
|
await page.goto('/devices');
|
|
|
|
const timestamp = page.locator('time, :has-text("ago")').first();
|
|
|
|
if (await timestamp.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(timestamp).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Alert List Live Updates', () => {
|
|
test('new alerts appear automatically', async ({ page }) => {
|
|
await page.goto('/alerts');
|
|
|
|
// Page should be connected to live updates
|
|
await expect(page.locator('body')).toBeVisible();
|
|
|
|
// Look for LiveView attributes
|
|
const liveView = page.locator('[data-phx-main]');
|
|
|
|
if (await liveView.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(liveView).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('alert status updates in real-time', async ({ page }) => {
|
|
await page.goto('/alerts');
|
|
|
|
// Alert statuses should be visible
|
|
const alertStatus = page.locator(
|
|
'[data-alert], .alert-item, tr:not(:has(th))'
|
|
).first();
|
|
|
|
if (await alertStatus.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(alertStatus).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Live Connection Status', () => {
|
|
test('shows connection indicator when connected', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
// Look for connection status indicator
|
|
const connectionStatus = page.locator(
|
|
'[data-connection], :has-text("Connected"), .connection-status'
|
|
).first();
|
|
|
|
if (await connectionStatus.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(connectionStatus).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('handles reconnection gracefully', async ({ page }) => {
|
|
await page.goto('/dashboard');
|
|
|
|
// Page should handle network issues gracefully
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Live Graph Updates', () => {
|
|
test('graphs update with new data', async ({ page }) => {
|
|
await page.goto('/devices');
|
|
|
|
const firstDevice = page.locator('a[href*="/devices/"]:not([href*="/devices/new"])').first();
|
|
|
|
if (await firstDevice.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstDevice.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Graphs should be present
|
|
const graph = page.locator('canvas, svg, [data-graph]').first();
|
|
|
|
if (await graph.isVisible({ timeout: 3000 }).catch(() => false)) {
|
|
await expect(graph).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|