import { test, expect } from '@playwright/test'; test.describe('Network Trace', () => { test('can access trace page', async ({ page }) => { await page.goto('/trace'); await expect(page).toHaveURL(/\/trace/); await expect(page.locator('body')).toBeVisible(); }); test('shows trace form', async ({ page }) => { await page.goto('/trace'); // Look for target input field const targetInput = page.locator( 'input[name*="target"], input[placeholder*="host"], input[placeholder*="IP"]' ).first(); if (await targetInput.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(targetInput).toBeVisible(); } }); test('shows trace type selector', async ({ page }) => { await page.goto('/trace'); // Look for trace type options (ping, traceroute, etc.) const traceType = page.locator( 'select[name*="type"], button:has-text("Ping"), button:has-text("Traceroute")' ).first(); if (await traceType.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(traceType).toBeVisible(); } }); test('has start trace button', async ({ page }) => { await page.goto('/trace'); const startButton = page.locator( 'button[type="submit"], button:has-text("Start"), button:has-text("Run"), button:has-text("Trace")' ).first(); if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(startButton).toBeVisible(); } }); test('can select device for trace source', async ({ page }) => { await page.goto('/trace'); // Look for device/agent selector const deviceSelector = page.locator( 'select[name*="device"], select[name*="agent"], select[name*="source"]' ).first(); if (await deviceSelector.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(deviceSelector).toBeVisible(); } }); test('shows trace results area', async ({ page }) => { await page.goto('/trace'); // Look for results container const resultsArea = page.locator( '[data-results], .results, pre, code, [id*="output"]' ).first(); if (await resultsArea.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(resultsArea).toBeVisible(); } }); test('can view trace history', async ({ page }) => { await page.goto('/trace'); // Look for history section const history = page.locator( ':has-text("History"), :has-text("Recent"), [data-history]' ).first(); if (await history.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(history).toBeVisible(); } }); test('shows loading state during trace', async ({ page }) => { await page.goto('/trace'); // Fill in a target const targetInput = page.locator( 'input[name*="target"], input[placeholder*="host"]' ).first(); if (await targetInput.isVisible({ timeout: 2000 }).catch(() => false)) { await targetInput.fill('8.8.8.8'); // Try to start trace const startButton = page.locator( 'button[type="submit"], button:has-text("Start")' ).first(); if (await startButton.isVisible({ timeout: 2000 }).catch(() => false)) { await startButton.click(); await page.waitForTimeout(500); // Look for loading indicator const loading = page.locator( '[data-loading], .spinner, :has-text("Running"), :has-text("Loading")' ).first(); if (await loading.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(loading).toBeVisible(); } } } }); test('can stop running trace', async ({ page }) => { await page.goto('/trace'); // Look for stop button (might only appear during trace) const stopButton = page.locator( 'button:has-text("Stop"), button:has-text("Cancel")' ).first(); if (await stopButton.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(stopButton).toBeVisible(); } }); });