- 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
252 lines
7.7 KiB
TypeScript
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();
|
|
}
|
|
});
|
|
});
|
|
});
|