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(); } } }); }); });