towerops/e2e/tests/device-graphs.spec.ts
Graham McIntire d5b0f38ed6
feat: add remaining e2e tests and fix 'too many open files' error
- Added e2e tests for auth flows (registration, login, password reset, TOTP)
- Added e2e tests for onboarding and organization creation
- Added e2e tests for team collaboration (org switching, invitations)
- Added e2e tests for activity feed
- Added e2e tests for device graphs (sensors, time ranges, interfaces)
- Added e2e tests for MikroTik backup comparison
- Added e2e tests for sites map (geographic view)
- Added e2e tests for network trace tool

- Fixed 'too many open files' error by configuring Phoenix code reloader
  to ignore deps/, _build/, node_modules/, e2e/, and other non-source directories
- This prevents the file system watcher from monitoring unnecessary files
2026-03-06 17:08:27 -06:00

169 lines
5.6 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Device Graphs', () => {
test('can access device from devices list', async ({ page }) => {
await page.goto('/devices');
// Find first device link
const firstDevice = page.locator('a[href*="/devices/"]:not([href*="/devices/new"])').first();
if (await firstDevice.isVisible({ timeout: 2000 }).catch(() => false)) {
const href = await firstDevice.getAttribute('href');
if (href && !href.includes('#!')) {
await firstDevice.click();
await page.waitForTimeout(500);
}
}
});
test('can view sensor graphs', async ({ page }) => {
await page.goto('/devices');
// Navigate to first device
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);
// Look for graph sections
const graph = page.locator('[data-graph], canvas, svg, .chart').first();
if (await graph.isVisible({ timeout: 3000 }).catch(() => false)) {
await expect(graph).toBeVisible();
}
}
});
test('shows graph time range selector', 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);
// Look for time range selector
const timeRange = page.locator(
'select[name*="range"], button:has-text("1h"), button:has-text("24h"), button:has-text("7d")'
).first();
if (await timeRange.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(timeRange).toBeVisible();
}
}
});
test('can switch between different sensor types', 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);
// Look for sensor type tabs or buttons
const sensorTab = page.locator(
'[role="tab"], button:has-text("CPU"), button:has-text("Memory"), button:has-text("Traffic")'
).first();
if (await sensorTab.isVisible({ timeout: 2000 }).catch(() => false)) {
await sensorTab.click();
await page.waitForTimeout(1000);
}
}
});
test('shows graph legend', 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);
// Look for graph legend
const legend = page.locator(
'.legend, [data-legend], :has-text("Min"), :has-text("Max"), :has-text("Avg")'
).first();
if (await legend.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(legend).toBeVisible();
}
}
});
test('can view interface graphs', 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);
// Look for interfaces section
const interfacesTab = page.locator(
'a[href*="interfaces"], button:has-text("Interfaces"), :has-text("Interfaces")'
).first();
if (await interfacesTab.isVisible({ timeout: 2000 }).catch(() => false)) {
await interfacesTab.click();
await page.waitForTimeout(1000);
// Look for interface graphs
const interfaceGraph = page.locator('canvas, svg, [data-graph]').first();
if (await interfaceGraph.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(interfaceGraph).toBeVisible();
}
}
}
});
test('can view check result graphs', 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);
// Look for checks/monitoring section
const checksTab = page.locator(
'a[href*="checks"], button:has-text("Checks"), :has-text("Monitoring")'
).first();
if (await checksTab.isVisible({ timeout: 2000 }).catch(() => false)) {
await checksTab.click();
await page.waitForTimeout(1000);
}
}
});
test('can change graph time range', 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);
// Find and click different time range
const timeButton = page.locator('button:has-text("24h"), button:has-text("7d")').first();
if (await timeButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await timeButton.click();
await page.waitForTimeout(1000);
// Graph should update (wait for potential loading state)
await page.waitForTimeout(500);
}
}
});
});