diff --git a/frontend/tests/MitreTechniquePicker.test.tsx b/frontend/tests/MitreTechniquePicker.test.tsx
index f1e1d42..9a416cc 100644
--- a/frontend/tests/MitreTechniquePicker.test.tsx
+++ b/frontend/tests/MitreTechniquePicker.test.tsx
@@ -219,6 +219,26 @@ describe('MitreTechniquePicker', () => {
expect(screen.queryByRole('listbox')).toBeNull();
});
+ it('typing while techniqueId is null does not reset inputValue between keystrokes', async () => {
+ mock.onGet('/mitre/techniques').reply(200, []);
+ const user = userEvent.setup({ advanceTimers: (ms) => vi.advanceTimersByTime(ms) });
+
+ renderWithProviders(
+ ,
+ );
+
+ const input = screen.getByRole('combobox') as HTMLInputElement;
+ await user.click(input);
+ await user.type(input, 'T10');
+
+ // Input must retain the full typed value — no mid-stroke reset
+ expect(input.value).toBe('T10');
+ });
+
it('shows inline error when API returns 503', async () => {
mock.onGet('/mitre/techniques').reply(503, { error: 'mitre bundle not loaded' });
const user = userEvent.setup({ advanceTimers: (ms) => vi.advanceTimersByTime(ms) });
diff --git a/frontend/tests/SimulationList.test.tsx b/frontend/tests/SimulationList.test.tsx
index 8c18068..ecd2c07 100644
--- a/frontend/tests/SimulationList.test.tsx
+++ b/frontend/tests/SimulationList.test.tsx
@@ -1,5 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-import { screen, waitFor } from '@testing-library/react';
+import { screen, waitFor, fireEvent } from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import { apiClient } from '@/api/client';
import { SimulationList } from '@/components/SimulationList';
@@ -104,6 +104,25 @@ describe('SimulationList — admin/redteam', () => {
});
expect(screen.getByTestId('new-simulation-btn')).toBeInTheDocument();
});
+
+ it('clicking a row uses SPA navigation and does not trigger window.location change', async () => {
+ mock.onGet('/engagements/42/simulations').reply(200, SIMULATIONS);
+ const originalHref = window.location.href;
+
+ renderWithProviders(, {
+ routerProps: { initialEntries: ['/engagements/42'] },
+ });
+
+ await waitFor(() => {
+ expect(screen.getByText('Lateral movement test')).toBeInTheDocument();
+ });
+
+ const row = screen.getByText('Lateral movement test').closest('tr') as HTMLElement;
+ fireEvent.click(row);
+
+ // window.location.href must be unchanged (no full-page reload)
+ expect(window.location.href).toBe(originalHref);
+ });
});
describe('SimulationList — SOC role (no edit button)', () => {