towerops/e2e/tests/alert-workflows.spec.ts
Graham McIntire 0cf533c0d4
feat: add comprehensive e2e tests for workflows and validation
- Added integration tests (Preseem, Gaiia, Slack, webhooks)
- Added SNMP configuration and discovery tests
- Added form validation and error handling tests
- Added detailed alert workflow tests (lifecycle, actions, filtering, history)
- Added agent token management tests (creation, assignment, deletion)

Covers:
- Third-party integration UI
- SNMP credential hierarchy (org/site/device)
- Form validation and error states
- Alert bulk actions and filtering
- Agent token lifecycle and device assignment
2026-03-06 17:12:46 -06:00

252 lines
7.7 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Alert Workflows', () => {
test.describe('Alert Lifecycle', () => {
test('can view alert details', async ({ page }) => {
await page.goto('/alerts');
// Find first alert
const firstAlert = page.locator('[data-alert], tr:not(:has(th)), a[href*="/alerts/"]').first();
if (await firstAlert.isVisible({ timeout: 2000 }).catch(() => false)) {
await firstAlert.click();
await page.waitForTimeout(500);
// Should show alert details
const alertDetails = page.locator(
':has-text("Device"), :has-text("Time"), [data-alert-detail]'
).first();
if (await alertDetails.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(alertDetails).toBeVisible();
}
}
});
test('shows alert severity', async ({ page }) => {
await page.goto('/alerts');
// Look for severity indicators
const severityBadge = page.locator(
'.badge, :has-text("Critical"), :has-text("Warning"), :has-text("Info"), [data-severity]'
).first();
if (await severityBadge.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(severityBadge).toBeVisible();
}
});
test('shows alert timestamp', async ({ page }) => {
await page.goto('/alerts');
// Look for timestamp
const timestamp = page.locator(
'time, :has-text("ago"), [data-timestamp]'
).first();
if (await timestamp.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(timestamp).toBeVisible();
}
});
test('shows device information in alert', async ({ page }) => {
await page.goto('/alerts');
// Look for device name or link
const deviceLink = page.locator(
'a[href*="/devices/"]'
).first();
if (await deviceLink.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(deviceLink).toBeVisible();
}
});
});
test.describe('Alert Actions', () => {
test('can acknowledge multiple alerts', async ({ page }) => {
await page.goto('/alerts');
// Look for bulk actions
const bulkAckButton = page.locator(
'button:has-text("Acknowledge Selected"), button:has-text("Bulk")'
).first();
if (await bulkAckButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(bulkAckButton).toBeVisible();
}
});
test('can select alerts for bulk actions', async ({ page }) => {
await page.goto('/alerts');
// Look for checkboxes
const checkbox = page.locator('input[type="checkbox"]').first();
if (await checkbox.isVisible({ timeout: 2000 }).catch(() => false)) {
await checkbox.click();
await page.waitForTimeout(300);
}
});
test('shows acknowledge confirmation', async ({ page }) => {
await page.goto('/alerts');
const ackButton = page.locator('button:has-text("Acknowledge")').first();
if (await ackButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await ackButton.click();
await page.waitForTimeout(500);
// Look for confirmation or success message
const confirmation = page.locator(
':has-text("acknowledged"), .success, [role="status"]'
).first();
if (await confirmation.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(confirmation).toBeVisible();
}
}
});
test('can add notes to alert', async ({ page }) => {
await page.goto('/alerts');
const firstAlert = page.locator('[data-alert], tr:not(:has(th))').first();
if (await firstAlert.isVisible({ timeout: 2000 }).catch(() => false)) {
await firstAlert.click();
await page.waitForTimeout(500);
// Look for notes section
const notesSection = page.locator(
'textarea, input[name*="note"], :has-text("Note"), :has-text("Comment")'
).first();
if (await notesSection.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(notesSection).toBeVisible();
}
}
});
});
test.describe('Alert Filtering', () => {
test('can filter by date range', async ({ page }) => {
await page.goto('/alerts');
const dateFilter = page.locator(
'input[type="date"], button:has-text("Date"), [data-date-filter]'
).first();
if (await dateFilter.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(dateFilter).toBeVisible();
}
});
test('can filter by device', async ({ page }) => {
await page.goto('/alerts');
const deviceFilter = page.locator(
'select[name*="device"], input[placeholder*="Device"]'
).first();
if (await deviceFilter.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(deviceFilter).toBeVisible();
}
});
test('can filter by alert type', async ({ page }) => {
await page.goto('/alerts');
const typeFilter = page.locator(
'select[name*="type"], button:has-text("Type")'
).first();
if (await typeFilter.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(typeFilter).toBeVisible();
}
});
test('shows active filter badges', async ({ page }) => {
await page.goto('/alerts?status=active');
// Look for filter badges showing active filters
const filterBadge = page.locator(
'.badge, .tag, :has-text("Active"), [data-filter-badge]'
).first();
if (await filterBadge.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(filterBadge).toBeVisible();
}
});
test('can clear all filters', async ({ page }) => {
await page.goto('/alerts?status=active');
const clearButton = page.locator(
'button:has-text("Clear"), button:has-text("Reset")'
).first();
if (await clearButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await clearButton.click();
await page.waitForTimeout(500);
}
});
});
test.describe('Alert Notifications', () => {
test('shows alert count badge', async ({ page }) => {
await page.goto('/dashboard');
// Look for alert count in navigation
const alertBadge = page.locator(
'[data-alert-count], .badge, a[href*="/alerts"] .count'
).first();
if (await alertBadge.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(alertBadge).toBeVisible();
}
});
test('can navigate to alerts from notification', async ({ page }) => {
await page.goto('/dashboard');
const alertLink = page.locator('a[href*="/alerts"]').first();
if (await alertLink.isVisible({ timeout: 2000 }).catch(() => false)) {
await alertLink.click();
await page.waitForTimeout(500);
await expect(page).toHaveURL(/\/alerts/);
}
});
});
test.describe('Alert History', () => {
test('shows resolved alerts', async ({ page }) => {
await page.goto('/alerts');
// Switch to resolved tab/filter
const resolvedTab = page.locator(
'button:has-text("Resolved"), [role="tab"]:has-text("Resolved")'
).first();
if (await resolvedTab.isVisible({ timeout: 2000 }).catch(() => false)) {
await resolvedTab.click();
await page.waitForTimeout(500);
}
});
test('shows alert resolution time', async ({ page }) => {
await page.goto('/alerts');
// Look for resolution timestamp
const resolvedTime = page.locator(
':has-text("Resolved"), time'
).first();
if (await resolvedTime.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(resolvedTime).toBeVisible();
}
});
});
});