From 0c93f5c41e32d28059204d8a2214eab90e4c3cf2 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 25 Jul 2026 17:17:24 -0700 Subject: [PATCH] test(dashboard): speed up SettingsModal close-flush tests Replace whole-tree *ByRole("button", { name: "Close" }) dismissal queries with scoped querySelector targets (.modal-close, .modal-actions-right button, .settings-embedded-mobile-close) in the SettingsModal suites and shared harness. The role+name query recomputes accessible names across the large Settings tree, adding ~700ms per dismissal test. Assertions are unchanged. - footer Close 1058ms -> 332ms; embedded mobile close 1003ms -> 344ms - models-auth workflow-lane flush ~1s -> 235ms - expectSettingPersists/assertProjectModelSavePayload harness helpers scoped too 422 SettingsModal tests pass; lint clean. --- .../__tests__/SettingsModal.general.test.tsx | 16 +++++++++++++--- .../__tests__/SettingsModal.models-auth.test.tsx | 3 ++- .../__tests__/SettingsModal.test-harness.tsx | 6 ++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx b/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx index ccc2d2cc9c..7d234e0ff2 100644 --- a/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx +++ b/packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx @@ -1979,8 +1979,17 @@ describe("SettingsModal", () => { expect(screen.queryByRole("button", { name: /^Save$/i })).not.toBeInTheDocument(); }); + /* + FNXC:SettingsModalTests 2026-07-27-17:20: + Target the footer/mobile Close affordances by their scoped selectors (`.modal-actions-right button`, + `.settings-embedded-mobile-close`) rather than `*ByRole("button", { name: "Close" })`. The role+name + query recomputes the accessible name for every button in the large Settings tree, which added ~700ms + per dismissal test in the dashboard's slowest feedback-loop suite. The scoped selectors mirror the + already-fast header/Escape/backdrop siblings while keeping the flush-on-close assertions identical + (Standing Rule: do not add slow tests / prefer narrow seams over whole-tree walks). + */ it.each([ - ["footer Close", async (container: HTMLElement) => settingsModalUser.click(screen.getAllByRole("button", { name: "Close" }).at(-1)!)], + ["footer Close", async (container: HTMLElement) => settingsModalUser.click(container.querySelector(".modal-actions-right button") as HTMLButtonElement)], ["header close", async (container: HTMLElement) => settingsModalUser.click(container.querySelector(".modal-close") as HTMLButtonElement)], ["Escape", async () => { fireEvent.keyDown(document, { key: "Escape" }); }], ["backdrop", async (container: HTMLElement) => { @@ -2007,10 +2016,11 @@ describe("SettingsModal", () => { it("flushes the latest edit through the embedded mobile close affordance", async () => { const onClose = vi.fn(); - renderModal({ initialSection: "general", presentation: "embedded", onClose }); + const { container } = renderModal({ initialSection: "general", presentation: "embedded", onClose }); await waitForSettingsModalReady(); changeProjectToggle(); - await settingsModalUser.click(screen.getByRole("button", { name: "Close" })); + // FNXC:SettingsModalTests 2026-07-27-17:20: scoped selector avoids the whole-tree accessible-name walk of getByRole({ name: "Close" }). + await settingsModalUser.click(container.querySelector(".settings-embedded-mobile-close") as HTMLButtonElement); await waitFor(() => expect(mockUpdateSettings).toHaveBeenCalledWith( expect.objectContaining({ capacityRiskBannerEnabled: true }), diff --git a/packages/dashboard/app/components/__tests__/SettingsModal.models-auth.test.tsx b/packages/dashboard/app/components/__tests__/SettingsModal.models-auth.test.tsx index 9934a9110a..a222474ae0 100644 --- a/packages/dashboard/app/components/__tests__/SettingsModal.models-auth.test.tsx +++ b/packages/dashboard/app/components/__tests__/SettingsModal.models-auth.test.tsx @@ -500,7 +500,8 @@ describe("SettingsModal", () => { await settingsModalUser.click(screen.getByLabelText("Plan/Triage Model")); await settingsModalUser.click(await screen.findByText("GPT-4o")); - await settingsModalUser.click(screen.getAllByRole("button", { name: "Close" }).at(-1)!); + // FNXC:SettingsModalTests 2026-07-27-17:20: scoped footer-close selector avoids the whole-tree accessible-name walk of getAllByRole({ name: "Close" }). + await settingsModalUser.click(document.querySelector(".modal-actions-right button") as HTMLButtonElement); await waitFor(() => expect(mockUpdateWorkflowSettingValues).toHaveBeenCalledWith("workflow-custom", expectedPatch, "proj-1")); expect(onClose).toHaveBeenCalledTimes(1); diff --git a/packages/dashboard/app/components/__tests__/SettingsModal.test-harness.tsx b/packages/dashboard/app/components/__tests__/SettingsModal.test-harness.tsx index 5fae2b20d8..2d0ab8adb1 100644 --- a/packages/dashboard/app/components/__tests__/SettingsModal.test-harness.tsx +++ b/packages/dashboard/app/components/__tests__/SettingsModal.test-harness.tsx @@ -204,7 +204,8 @@ export async function expectSettingPersists({ section, label, kind, value, scope fireEvent.change(control, { target: { value: String(value) } }); } - fireEvent.click(screen.getAllByRole("button", { name: "Close" })[0]); + // FNXC:SettingsModalTests 2026-07-27-17:20: click the header `.modal-close` directly; `getAllByRole("button", { name: "Close" })` recomputes accessible names across the whole Settings tree and added ~700ms per persist test. + fireEvent.click(document.querySelector(".modal-close") as HTMLButtonElement); if (scope === "global") { await waitFor(() => expect(mockUpdateGlobalSettings).toHaveBeenCalled()); @@ -227,7 +228,8 @@ export async function assertProjectModelSavePayload(provider: string, modelId: s fireEvent.change(screen.getByLabelText("Default Provider"), { target: { value: provider } }); fireEvent.change(screen.getByLabelText("Default Model"), { target: { value: modelId } }); - fireEvent.click(screen.getAllByRole("button", { name: "Close" })[0]); + // FNXC:SettingsModalTests 2026-07-27-17:20: scoped header-close selector avoids the whole-tree accessible-name walk of getAllByRole({ name: "Close" }). + fireEvent.click(document.querySelector(".modal-close") as HTMLButtonElement); await waitFor(() => { expect(mockUpdateSettings).toHaveBeenCalledWith(