From c257492752631b1125c79d9c605d27ab9806c026 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Jul 2026 08:00:06 +0000 Subject: [PATCH 1/2] refactor(mode-home): short titles and single-line hero subtitles Make every mode-home hero read consistently: the title is the mode name (Therapy, Factsheets, Specifiers, Formulation, Services, Medication) and the subtitle is one high-yield line instead of a sentence that wraps to two lines on a phone. Titles already short (Tools, Forms, DSM-5, Favourites, Differentials) keep their name; their subtitles are trimmed where still long. Update the UI/DOM specs that assert the previous hero copy. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Gb9jucaNMEQDmRKXEN7SRV --- src/components/applications-launcher-page.tsx | 2 +- .../clinical-dashboard/favourites-hub.tsx | 2 +- .../medication-prescribing-workspace.tsx | 2 +- src/components/dsm/dsm-home-page.tsx | 2 +- .../factsheets/factsheets-home-page.tsx | 4 ++-- src/components/forms/forms-home-page.tsx | 2 +- .../formulation/formulation-home-page.tsx | 4 ++-- .../services/services-home-page.tsx | 4 ++-- .../specifiers/specifiers-home-page.tsx | 4 ++-- .../therapy-compass/screens/home-screen.tsx | 6 +++--- ...therapy-compass-data-recovery.dom.test.tsx | 20 ++++++++++--------- tests/ui-accessibility.spec.ts | 2 +- tests/ui-formulation.spec.ts | 2 +- tests/ui-route-coverage.spec.ts | 6 +++--- tests/ui-specifiers.spec.ts | 2 +- tests/ui-tools.spec.ts | 10 +++++----- 16 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/components/applications-launcher-page.tsx b/src/components/applications-launcher-page.tsx index 7ecfd2e2a..a1d1b5635 100644 --- a/src/components/applications-launcher-page.tsx +++ b/src/components/applications-launcher-page.tsx @@ -107,7 +107,7 @@ function launcherAppsForSession(canAccessFavourites: boolean): LauncherApp[] { const toolsLauncherCopy = { heading: "Tools", - description: "Assessment, prescribing, documents, and clinical workflows.", + description: "Assessment, prescribing, and clinical workflows.", allSectionLabel: "All tools", countNoun: "tools", emptyTitle: "No tools match", diff --git a/src/components/clinical-dashboard/favourites-hub.tsx b/src/components/clinical-dashboard/favourites-hub.tsx index 183caec94..34da03e4b 100644 --- a/src/components/clinical-dashboard/favourites-hub.tsx +++ b/src/components/clinical-dashboard/favourites-hub.tsx @@ -163,7 +163,7 @@ export function FavouritesHub({ diff --git a/src/components/clinical-dashboard/medication-prescribing-workspace.tsx b/src/components/clinical-dashboard/medication-prescribing-workspace.tsx index e7dd299aa..574bcd7d7 100644 --- a/src/components/clinical-dashboard/medication-prescribing-workspace.tsx +++ b/src/components/clinical-dashboard/medication-prescribing-workspace.tsx @@ -217,7 +217,7 @@ function MedicationHome({ return ( diff --git a/src/components/forms/forms-home-page.tsx b/src/components/forms/forms-home-page.tsx index 78543a917..f3ab30ad6 100644 --- a/src/components/forms/forms-home-page.tsx +++ b/src/components/forms/forms-home-page.tsx @@ -116,7 +116,7 @@ export function FormsHomePage() { { expect(await screen.findByRole("status")).toHaveTextContent("Loading therapy library…"); expect(screen.getAllByRole("main")).toHaveLength(1); - expect(screen.queryByText(/Search 0 source-grounded therapy/)).not.toBeInTheDocument(); - expect(screen.queryByRole("heading", { name: "What therapy are you looking for?" })).not.toBeInTheDocument(); + expect(screen.queryByText(/Source-grounded therapy records and clinical pathways/)).not.toBeInTheDocument(); + expect(screen.queryByRole("heading", { name: "Therapy" })).not.toBeInTheDocument(); release(undefined); - await waitFor(() => expect(screen.getByText(/Search 1 source-grounded therapy record by/)).toBeInTheDocument()); - expect(screen.getByRole("heading", { name: "What therapy are you looking for?" })).toBeInTheDocument(); + await waitFor(() => + expect(screen.getByText(/1 source-grounded therapy record and clinical pathways/)).toBeInTheDocument(), + ); + expect(screen.getByRole("heading", { name: "Therapy" })).toBeInTheDocument(); expect(screen.getAllByRole("main")).toHaveLength(1); - expect(screen.queryByText(/Search 0 source-grounded therapy/)).not.toBeInTheDocument(); + expect(screen.queryByText(/Source-grounded therapy records and clinical pathways/)).not.toBeInTheDocument(); }); it("shows an honest load error, retries all required files, and recovers", async () => { @@ -89,17 +91,17 @@ describe("Therapy Compass required data recovery", () => { ); expect(screen.getByRole("status")).toHaveTextContent("Loading therapy library"); - expect(screen.queryByText(/Search 0 source-grounded therapy records/)).not.toBeInTheDocument(); + expect(screen.queryByText(/Source-grounded therapy records and clinical pathways/)).not.toBeInTheDocument(); expect(screen.queryByRole("heading", { name: "Frequently used therapies" })).not.toBeInTheDocument(); expect(await screen.findByRole("alert")).toHaveTextContent("Therapy Compass could not load"); - expect(screen.queryByRole("heading", { name: "What therapy are you looking for?" })).not.toBeInTheDocument(); + expect(screen.queryByRole("heading", { name: "Therapy" })).not.toBeInTheDocument(); failTherapies = false; fireEvent.click(screen.getByRole("button", { name: "Retry" })); - expect(await screen.findByRole("heading", { name: "What therapy are you looking for?" })).toBeInTheDocument(); - expect(screen.getByText(/Search 1 source-grounded therapy record by/)).toBeInTheDocument(); + expect(await screen.findByRole("heading", { name: "Therapy" })).toBeInTheDocument(); + expect(screen.getByText(/1 source-grounded therapy record and clinical pathways/)).toBeInTheDocument(); expect(screen.queryByRole("alert")).not.toBeInTheDocument(); await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(2)); }); diff --git a/tests/ui-accessibility.spec.ts b/tests/ui-accessibility.spec.ts index ce308087e..846ea3e17 100644 --- a/tests/ui-accessibility.spec.ts +++ b/tests/ui-accessibility.spec.ts @@ -383,7 +383,7 @@ test.describe("Clinical KB accessibility coverage", () => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/therapy-compass", { waitUntil: "domcontentloaded" }); - await expect(page.getByRole("heading", { name: "What therapy are you looking for?" })).toBeVisible({ + await expect(page.getByRole("heading", { name: "Therapy", exact: true })).toBeVisible({ timeout: 60_000, }); diff --git a/tests/ui-formulation.spec.ts b/tests/ui-formulation.spec.ts index ff3d8e051..2101eaf01 100644 --- a/tests/ui-formulation.spec.ts +++ b/tests/ui-formulation.spec.ts @@ -57,7 +57,7 @@ test("searches patient language, opens a mechanism guide, and carries it into th }, testInfo) => { await gotoApp(page, "/formulation"); - await expect(page.getByRole("heading", { name: "How can I help with the formulation?" })).toBeVisible(); + await expect(page.getByRole("heading", { name: "Formulation", exact: true })).toBeVisible(); await expect(page.getByTestId("formulation-home")).toBeVisible(); const search = page.getByTestId("global-search-input").filter({ visible: true }).first(); diff --git a/tests/ui-route-coverage.spec.ts b/tests/ui-route-coverage.spec.ts index 1c42eb9b6..3803526fc 100644 --- a/tests/ui-route-coverage.spec.ts +++ b/tests/ui-route-coverage.spec.ts @@ -218,9 +218,9 @@ test.describe("previously uncovered production routes", () => { "/therapy-compass", async (currentPage) => { await expect(currentPage.getByRole("main")).toBeVisible(); - await expect( - currentPage.getByRole("heading", { name: "What therapy are you looking for?", level: 1 }), - ).toBeVisible({ timeout: 30_000 }); + await expect(currentPage.getByRole("heading", { name: "Therapy", level: 1, exact: true })).toBeVisible({ + timeout: 30_000, + }); }, async (currentPage) => { const search = currentPage diff --git a/tests/ui-specifiers.spec.ts b/tests/ui-specifiers.spec.ts index dfffc3867..87905a821 100644 --- a/tests/ui-specifiers.spec.ts +++ b/tests/ui-specifiers.spec.ts @@ -63,7 +63,7 @@ test("searches clinical language without provenance fields and carries a result }, testInfo) => { await gotoApp(page, "/specifiers"); - await expect(page.getByRole("heading", { name: "Refine the diagnosis with the right specifier" })).toBeVisible(); + await expect(page.getByRole("heading", { name: "Specifiers", exact: true })).toBeVisible(); await expect(page.getByTestId("specifiers-home")).toBeVisible(); const search = page.getByTestId("global-search-input").filter({ visible: true }).first(); diff --git a/tests/ui-tools.spec.ts b/tests/ui-tools.spec.ts index e8de54044..5536fb8db 100644 --- a/tests/ui-tools.spec.ts +++ b/tests/ui-tools.spec.ts @@ -481,14 +481,14 @@ test.describe("Clinical KB tools launcher", () => { await expect(page).toHaveURL(/\/services$/); await expect(page.getByRole("button", { name: "Mode Services" })).toBeVisible(); await expect(page.getByTestId("services-home")).toBeVisible(); - await expect(page.getByRole("heading", { level: 1, name: "Find a service" })).toBeVisible(); + await expect(page.getByRole("heading", { level: 1, name: "Services" })).toBeVisible(); await expect(page.getByRole("button", { name: "Expand sidebar" })).toBeVisible(); await expect(page.getByTestId("collapsed-account-settings")).toBeVisible(); await expect(visibleGlobalSearchInput(page)).toHaveCount(1); const servicesHomeSearch = page.getByTestId("services-home").getByTestId("global-search-input"); await expect(servicesHomeSearch).toBeVisible(); const servicesSearchBox = await servicesHomeSearch.boundingBox(); - const servicesHeadingBox = await page.getByRole("heading", { level: 1, name: "Find a service" }).boundingBox(); + const servicesHeadingBox = await page.getByRole("heading", { level: 1, name: "Services" }).boundingBox(); expect(servicesSearchBox).not.toBeNull(); expect(servicesHeadingBox).not.toBeNull(); expect((servicesHeadingBox?.y ?? 0) + (servicesHeadingBox?.height ?? 0)).toBeLessThan(servicesSearchBox?.y ?? 0); @@ -559,7 +559,7 @@ test.describe("Clinical KB tools launcher", () => { for (const home of [ { path: "/?mode=answer", testId: "answer-empty-state", heading: "How can I help?", headingLevel: 2 }, - { path: "/services", testId: "services-home", heading: "Find a service", headingLevel: 1 }, + { path: "/services", testId: "services-home", heading: "Services", headingLevel: 1 }, { path: "/forms", testId: "forms-home", heading: "Forms", headingLevel: 1 }, { path: "/differentials", testId: "differentials-home", heading: "Differentials", headingLevel: 1 }, { path: "/favourites", testId: "favourites-hub", heading: "Favourites command library", headingLevel: 1 }, @@ -763,10 +763,10 @@ test.describe("Clinical KB tools launcher", () => { { path: "/?mode=prescribing", testId: "medication-home", - heading: "Medication prescribing", + heading: "Medication", headingLevel: 2, }, - { path: "/services", testId: "services-home", heading: "Find a service", headingLevel: 1 }, + { path: "/services", testId: "services-home", heading: "Services", headingLevel: 1 }, { path: "/forms", testId: "forms-home", heading: "Forms", headingLevel: 1 }, { path: "/differentials", testId: "differentials-home", heading: "Differentials", headingLevel: 1 }, { path: "/tools", testId: "tools-home", heading: "Tools", headingLevel: 1 }, From 06848a4be317664899331c9e7463cdcb36497214 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Jul 2026 08:12:23 +0000 Subject: [PATCH 2/2] test(ui): scope prescribing mode-home heading assertion to its container The renamed "Medication" hero title is a substring of the answer section's sr-only "Medication matches" heading, so the page-scoped getByRole heading lookup hit two elements under Playwright strict mode. Scope the lookup to the mode-home container and match exactly. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Gb9jucaNMEQDmRKXEN7SRV --- tests/ui-tools.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/ui-tools.spec.ts b/tests/ui-tools.spec.ts index 5536fb8db..ab00979b5 100644 --- a/tests/ui-tools.spec.ts +++ b/tests/ui-tools.spec.ts @@ -784,8 +784,12 @@ test.describe("Clinical KB tools launcher", () => { await expect(heroSearch).toBeVisible(); const searchBox = await heroSearch.boundingBox(); + // Scope to the mode-home container and match exactly: the standalone + // "Medication" hero title is otherwise a substring of the answer + // section's sr-only "Medication matches" heading (strict-mode clash). const headingBox = await page - .getByRole("heading", { level: home.headingLevel, name: home.heading }) + .getByTestId(home.testId) + .getByRole("heading", { level: home.headingLevel, name: home.heading, exact: true }) .boundingBox(); expect(searchBox).not.toBeNull(); expect(headingBox).not.toBeNull();