diff --git a/tests/ui-dictionary.spec.ts b/tests/ui-dictionary.spec.ts index f42faa1f21..ba398f3a04 100644 --- a/tests/ui-dictionary.spec.ts +++ b/tests/ui-dictionary.spec.ts @@ -207,11 +207,27 @@ test("merges search and browse into one catalogue with a measured phone header", expect(Math.abs(scopeSegments[0] - scopeSegments[1])).toBeLessThanOrEqual(1); const abbreviationsRadio = toggle.getByRole("radio", { name: /Abbreviations/ }); const expectAbbreviationsLabelToFit = async () => { - const dimensions = await abbreviationsRadio.getByText("Abbreviations", { exact: true }).evaluate((label) => ({ - clientWidth: label.clientWidth, - scrollWidth: label.scrollWidth, - })); - expect(dimensions.scrollWidth).toBeLessThanOrEqual(dimensions.clientWidth); + const dimensions = await abbreviationsRadio.getByText("Abbreviations", { exact: true }).evaluate((label) => { + const segment = label.parentElement; + const style = segment ? getComputedStyle(segment) : null; + return { + clientWidth: label.clientWidth, + scrollWidth: label.scrollWidth, + // Read on failure only: which layout the browser applied at this width. + layout: { + innerWidth: window.innerWidth, + smMatches: window.matchMedia("(min-width: 40rem)").matches, + segmentWidth: Math.round(segment?.getBoundingClientRect().width ?? -1), + fontSize: style?.fontSize, + letterSpacing: style?.letterSpacing, + paddingLeft: style?.paddingLeft, + hintWidth: Math.round(label.nextElementSibling?.getBoundingClientRect().width ?? -1), + }, + }; + }); + expect(dimensions.scrollWidth, `Abbreviations label clipped: ${JSON.stringify(dimensions)}`).toBeLessThanOrEqual( + dimensions.clientWidth, + ); }; await expectAbbreviationsLabelToFit(); await expect(abbreviationsRadio).toBeChecked(); diff --git a/tests/ui-patient-number-field.spec.ts b/tests/ui-patient-number-field.spec.ts index b0432223b8..4de9d72ddf 100644 --- a/tests/ui-patient-number-field.spec.ts +++ b/tests/ui-patient-number-field.spec.ts @@ -104,10 +104,18 @@ async function openPatientStrip(page: Page): Promise { // The panel's open state is React-controlled. A tap before hydration toggles // the native
without React's onToggle, so React's state and the // DOM can disagree and the field may never show. - await clickWhenHydrated(panel.locator("summary").first()); + // A streamed page can replace the panel after the tap, and the replacement mounts closed, so + // tap again whenever the panel is closed rather than trusting the first tap. Reading the + // panel's own open state never re-taps an open panel whose fields are still painting. const crcl = page.getByTestId("patient-crcl"); - await expect(crcl).toBeVisible({ timeout: 15_000 }); - await waitForHydratedField(crcl); + await expect(async () => { + const open = await panel.evaluate((element) => (element as HTMLDetailsElement).open); + if (!open) await clickWhenHydrated(panel.locator("summary").first()); + await expect(crcl).toBeVisible({ timeout: 5_000 }); + await waitForHydratedField(crcl); + // A replacement that lands after the field first painted mounts closed; this retries it. + await expect(crcl).toBeVisible({ timeout: 1_000 }); + }).toPass({ timeout: 30_000 }); } /**