- 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
258 lines
8 KiB
TypeScript
258 lines
8 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Agent Token Management', () => {
|
|
test.describe('Token List', () => {
|
|
test('can view agent tokens from agents page', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
await expect(page).toHaveURL(/\/agents/);
|
|
await expect(page.locator('body')).toBeVisible();
|
|
});
|
|
|
|
test('shows agent token details', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for token information
|
|
const tokenInfo = page.locator(
|
|
':has-text("Token"), [data-token], .token'
|
|
).first();
|
|
|
|
if (await tokenInfo.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(tokenInfo).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows agent status indicators', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for online/offline status
|
|
const statusIndicator = page.locator(
|
|
':has-text("Online"), :has-text("Offline"), .status, [data-status]'
|
|
).first();
|
|
|
|
if (await statusIndicator.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(statusIndicator).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows last seen timestamp', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for last seen time
|
|
const lastSeen = page.locator(
|
|
':has-text("Last seen"), :has-text("ago"), time'
|
|
).first();
|
|
|
|
if (await lastSeen.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(lastSeen).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Token Creation', () => {
|
|
test('can access new agent token page', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for create new agent button
|
|
const newButton = page.locator(
|
|
'button:has-text("New"), button:has-text("Add"), a:has-text("New Agent")'
|
|
).first();
|
|
|
|
if (await newButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await newButton.click();
|
|
await page.waitForTimeout(500);
|
|
}
|
|
});
|
|
|
|
test('shows token name field', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
const newButton = page.locator(
|
|
'button:has-text("New"), a[href*="/agents/new"]'
|
|
).first();
|
|
|
|
if (await newButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await newButton.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Look for name field
|
|
const nameField = page.locator('input[name*="name"]').first();
|
|
|
|
if (await nameField.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(nameField).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('shows token after creation', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// After creating a token, should show the token value
|
|
// This is a read-only test checking the UI exists
|
|
const tokenDisplay = page.locator(
|
|
'code, pre, [data-token-value], input[readonly]'
|
|
).first();
|
|
|
|
if (await tokenDisplay.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(tokenDisplay).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Token Assignment', () => {
|
|
test('can view device assignments', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Navigate to first agent
|
|
const firstAgent = page.locator('a[href*="/agents/"]').first();
|
|
|
|
if (await firstAgent.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstAgent.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Look for assigned devices
|
|
const devicesSection = page.locator(
|
|
':has-text("Devices"), :has-text("Assigned"), table'
|
|
).first();
|
|
|
|
if (await devicesSection.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(devicesSection).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('shows device count for agent', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for device count
|
|
const deviceCount = page.locator(
|
|
':has-text("device"), [data-count], .count'
|
|
).first();
|
|
|
|
if (await deviceCount.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(deviceCount).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('can assign devices to agent', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
const firstAgent = page.locator('a[href*="/agents/"]').first();
|
|
|
|
if (await firstAgent.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstAgent.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Look for assign button
|
|
const assignButton = page.locator(
|
|
'button:has-text("Assign"), button:has-text("Add Device")'
|
|
).first();
|
|
|
|
if (await assignButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(assignButton).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('can unassign devices from agent', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
const firstAgent = page.locator('a[href*="/agents/"]').first();
|
|
|
|
if (await firstAgent.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstAgent.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Look for remove/unassign button
|
|
const removeButton = page.locator(
|
|
'button:has-text("Remove"), button:has-text("Unassign")'
|
|
).first();
|
|
|
|
if (await removeButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(removeButton).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Token Deletion', () => {
|
|
test('can access delete token option', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
const firstAgent = page.locator('a[href*="/agents/"]').first();
|
|
|
|
if (await firstAgent.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstAgent.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Look for delete button
|
|
const deleteButton = page.locator(
|
|
'button:has-text("Delete"), button:has-text("Remove")'
|
|
).first();
|
|
|
|
if (await deleteButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(deleteButton).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('shows confirmation before deleting token', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
const firstAgent = page.locator('a[href*="/agents/"]').first();
|
|
|
|
if (await firstAgent.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await firstAgent.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const deleteButton = page.locator('button:has-text("Delete")').first();
|
|
|
|
if (await deleteButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await deleteButton.click();
|
|
await page.waitForTimeout(300);
|
|
|
|
// Look for confirmation dialog
|
|
const confirmation = page.locator(
|
|
':has-text("confirm"), :has-text("sure"), [role="dialog"]'
|
|
).first();
|
|
|
|
if (await confirmation.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(confirmation).toBeVisible();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Default Agent Token', () => {
|
|
test('can set organization default agent', async ({ page }) => {
|
|
await page.goto('/settings');
|
|
|
|
if ((await page.url()).includes('sudo-verify')) {
|
|
return;
|
|
}
|
|
|
|
// Look for default agent setting
|
|
const defaultAgentSetting = page.locator(
|
|
':has-text("Default Agent"), select[name*="agent"]'
|
|
).first();
|
|
|
|
if (await defaultAgentSetting.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(defaultAgentSetting).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('shows default agent indicator', async ({ page }) => {
|
|
await page.goto('/agents');
|
|
|
|
// Look for default badge or indicator
|
|
const defaultBadge = page.locator(
|
|
':has-text("Default"), .badge, [data-default]'
|
|
).first();
|
|
|
|
if (await defaultBadge.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
await expect(defaultBadge).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
});
|