todays product advirories implemented
This commit is contained in:
195
src/Web/StellaOps.Web/tests/e2e/triage-card.spec.ts
Normal file
195
src/Web/StellaOps.Web/tests/e2e/triage-card.spec.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// triage-card.spec.ts
|
||||
// Sprint: SPRINT_20260117_018_FE_ux_components
|
||||
// Task: UXC-008 - Integration tests with Playwright
|
||||
// Description: Playwright e2e tests for Triage Card component
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { policyAuthorSession } from '../../src/app/testing';
|
||||
|
||||
const mockConfig = {
|
||||
authority: {
|
||||
issuer: 'https://authority.local',
|
||||
clientId: 'stellaops-ui',
|
||||
authorizeEndpoint: 'https://authority.local/connect/authorize',
|
||||
tokenEndpoint: 'https://authority.local/connect/token',
|
||||
logoutEndpoint: 'https://authority.local/connect/logout',
|
||||
redirectUri: 'http://127.0.0.1:4400/auth/callback',
|
||||
postLogoutRedirectUri: 'http://127.0.0.1:4400/',
|
||||
scope: 'openid profile email ui.read findings:read vuln:view vuln:investigate',
|
||||
audience: 'https://scanner.local',
|
||||
dpopAlgorithms: ['ES256'],
|
||||
refreshLeewaySeconds: 60,
|
||||
},
|
||||
apiBaseUrls: {
|
||||
authority: 'https://authority.local',
|
||||
scanner: 'https://scanner.local',
|
||||
policy: 'https://scanner.local',
|
||||
concelier: 'https://concelier.local',
|
||||
attestor: 'https://attestor.local',
|
||||
},
|
||||
quickstartMode: true,
|
||||
};
|
||||
|
||||
const mockTriageData = {
|
||||
vulnId: 'CVE-2024-1234',
|
||||
packageName: 'lodash',
|
||||
packageVersion: '4.17.20',
|
||||
scope: 'direct',
|
||||
riskScore: 8.5,
|
||||
riskReason: 'High CVSS + Exploited',
|
||||
evidence: [
|
||||
{ type: 'openvex', status: 'verified', value: 'not_affected' },
|
||||
{ type: 'patch-proof', status: 'verified' },
|
||||
{ type: 'reachability', status: 'pending', value: 'analyzing' },
|
||||
{ type: 'epss', status: 'verified', value: 0.67 },
|
||||
],
|
||||
digest: 'sha256:abc123def456789012345678901234567890123456789012345678901234',
|
||||
attestationDigest: 'sha256:attestation123456789012345678901234567890123456789012',
|
||||
};
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.addInitScript((session) => {
|
||||
try {
|
||||
window.sessionStorage.clear();
|
||||
} catch {
|
||||
// ignore storage errors in restricted contexts
|
||||
}
|
||||
(window as any).__stellaopsTestSession = session;
|
||||
}, policyAuthorSession);
|
||||
|
||||
await page.route('**/config.json', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockConfig),
|
||||
})
|
||||
);
|
||||
|
||||
await page.route('https://authority.local/**', (route) => route.abort());
|
||||
});
|
||||
|
||||
test.describe('Triage Card Component', () => {
|
||||
test('renders vulnerability information correctly', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify header content
|
||||
await expect(page.getByText('CVE-2024-1234')).toBeVisible();
|
||||
await expect(page.getByText('lodash@4.17.20')).toBeVisible();
|
||||
await expect(page.getByText('direct')).toBeVisible();
|
||||
|
||||
// Verify risk chip
|
||||
const riskChip = page.locator('.risk-chip');
|
||||
await expect(riskChip).toContainText('8.5');
|
||||
});
|
||||
|
||||
test('displays evidence chips with correct status', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify evidence chips
|
||||
await expect(page.getByRole('button', { name: /OpenVEX/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Patch Proof/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Reachability/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /EPSS/ })).toBeVisible();
|
||||
});
|
||||
|
||||
test('action buttons are visible and functional', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify action buttons
|
||||
await expect(page.getByRole('button', { name: /Explain/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Create task/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Mute/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Export/ })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: /Rekor Verify/ })).toBeVisible();
|
||||
});
|
||||
|
||||
test('keyboard shortcut V triggers Rekor Verify', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
const card = page.getByRole('article', { name: /CVE-2024/ });
|
||||
await expect(card).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Focus the card and press V
|
||||
await card.focus();
|
||||
await page.keyboard.press('v');
|
||||
|
||||
// Verify loading state or verification panel appears
|
||||
await expect(
|
||||
page.getByText('Verifying...').or(page.getByText('Verified')).or(page.getByText('Rekor Verification Details'))
|
||||
).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
test('keyboard shortcut M triggers Mute action', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
const card = page.getByRole('article', { name: /CVE-2024/ });
|
||||
await expect(card).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Focus the card and press M
|
||||
await card.focus();
|
||||
await page.keyboard.press('m');
|
||||
|
||||
// Verify mute action was triggered (modal or confirmation)
|
||||
// This depends on implementation - checking for any response
|
||||
await expect(page.locator('[role="dialog"]').or(page.getByText(/mute/i))).toBeVisible({ timeout: 3000 });
|
||||
});
|
||||
|
||||
test('keyboard shortcut E triggers Export action', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
const card = page.getByRole('article', { name: /CVE-2024/ });
|
||||
await expect(card).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Focus the card and press E
|
||||
await card.focus();
|
||||
await page.keyboard.press('e');
|
||||
|
||||
// Verify export action was triggered
|
||||
await expect(page.locator('[role="dialog"]').or(page.getByText(/export/i))).toBeVisible({ timeout: 3000 });
|
||||
});
|
||||
|
||||
test('Rekor Verify expands verification panel', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Click Rekor Verify button
|
||||
await page.getByRole('button', { name: /Rekor Verify/ }).click();
|
||||
|
||||
// Wait for verification to complete
|
||||
await expect(page.getByText('Rekor Verification Details')).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify details are displayed
|
||||
await expect(page.getByText('Subject')).toBeVisible();
|
||||
await expect(page.getByText('Issuer')).toBeVisible();
|
||||
await expect(page.getByText('Timestamp')).toBeVisible();
|
||||
await expect(page.getByText('Rekor Index')).toBeVisible();
|
||||
});
|
||||
|
||||
test('copy buttons work for digest and Rekor entry', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Find and click copy button for digest
|
||||
const copyBtn = page.getByRole('button', { name: /Copy digest/ });
|
||||
await expect(copyBtn).toBeVisible();
|
||||
|
||||
// Click and verify clipboard (mock)
|
||||
await copyBtn.click();
|
||||
// Clipboard API may not be available in test context, but button should be clickable
|
||||
});
|
||||
|
||||
test('evidence chips show tooltips on hover', async ({ page }) => {
|
||||
await page.goto('/triage/findings');
|
||||
await expect(page.getByRole('article', { name: /CVE-2024/ })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Hover over evidence chip
|
||||
const chip = page.getByRole('button', { name: /OpenVEX/ });
|
||||
await chip.hover();
|
||||
|
||||
// Verify tooltip appears (title attribute)
|
||||
await expect(chip).toHaveAttribute('title');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user