test(e2e): sprint 3 acceptance tests — US-13 to US-16

Four new spec files covering the MITRE multi-technique feature:
- us13: API contract (techniques array, dedup, unknown ID → 400, SOC 403, auto-transition)
- us14: tag UI (empty state, add/remove auto-save, SimulationList column, order, styling)
- us15: matrix modal (tactic tree, layout, select/expand/search, Apply/Cancel/Escape/backdrop, a11y)
- us16: sprint 2 regression (workflow, badge, SOC RBAC, picker still works)

Updated sprint 2 specs (us8, us10) to use technique_ids array and Quick search button
instead of deprecated scalar mitre_technique_id/name fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Knacky
2026-05-27 04:51:34 +02:00
parent 393b6ed416
commit df8a6b605b
6 changed files with 1261 additions and 12 deletions

View File

@@ -128,7 +128,7 @@ test.describe('US-10 — MITRE autocomplete', () => {
expect(subtech.name).toBeTruthy();
});
test('AC-10.5 — MitreTechniquePicker: input, dropdown, keyboard nav, selection fills both fields', async ({
test('AC-10.5 — MitreTechniquePicker: input, dropdown, keyboard nav, selection appends tag', async ({
page,
context,
}) => {
@@ -137,12 +137,14 @@ test.describe('US-10 — MITRE autocomplete', () => {
await seedTokenInStorage(context, redteamToken);
await page.goto(`/engagements/${engagementId}/simulations/${sim.id}/edit`);
// Sprint 3: picker is inside MitreTechniquesField, opened via "Quick search"
await page.getByRole('button', { name: /quick search/i }).click();
const picker = page.getByRole('combobox', { name: /mitre technique/i });
await expect(picker).toBeVisible();
// Type a query — after debounce (200ms) the dropdown opens with results
await picker.fill('T1059');
// Wait for dropdown to appear (debounce + network)
const listbox = page.getByRole('listbox', { name: /mitre techniques/i });
await expect(listbox).toBeVisible({ timeout: 5_000 });
@@ -157,13 +159,14 @@ test.describe('US-10 — MITRE autocomplete', () => {
await picker.press('ArrowDown');
await picker.press('Enter');
// After selection the dropdown closes and input shows the selected value
// Sprint 3: after selection the picker resets (one-shot append mode).
// The tag T1059 should appear in the techniques field.
await expect(listbox).not.toBeVisible();
const inputValue = await picker.inputValue();
expect(inputValue).toMatch(/T1059/);
expect(inputValue).toMatch(/—/);
await expect(page.getByTestId('techniques-tag-list')).toBeVisible({ timeout: 5_000 });
await expect(page.getByTestId('techniques-tag-list')).toContainText('T1059');
// Escape closes the dropdown
// Escape closes the dropdown (re-open picker to test Escape)
await page.getByRole('button', { name: /quick search/i }).click();
await picker.fill('T1');
await expect(listbox).toBeVisible({ timeout: 5_000 });
await picker.press('Escape');