From 79035de329dc45ce80e8477d7cc4a8d2e93f0900 Mon Sep 17 00:00:00 2001 From: Anton Wiklund Date: Sun, 8 Nov 2026 19:01:03 +0100 Subject: [PATCH] test(ui): wait 10 s for a query that waits, not Testing Library's 1 s Two tests of a linked deck's pictures failed in the merge queue for pull requests that change nothing in the UI: on the learner's card page (#666) and on the Studio's card screen (#670), the "Show pictures from author.example" button was not there within findByRole's 1 s. Neither fails on a laptop, under CPU load, with coverage on, or with random delays on every use case: the button always comes. It comes late, though. A card screen shows the button only after the instances, the deck and its cards are read, then whether the deck is in the learner's pod, then the library's index. With every read slowed to 200 ms, the card's heading came at about 630 ms and the button at about 840 ms, the closest of these tests to 1 s. CI takes some tests fifty times as long as a laptop does, which is why a test may take 60 s (vitest.shared.ts). The 1 s wait of findBy and waitFor had no such allowance, so any screen that reads its data in a few steps could fail the same way. The UI's test setup, which the Studio's and the web app's import, now sets it to 10 s. A query that never matches still fails, only later. The Studio's two waits of 3 s for a saved draft would now shorten the wait, so they go. Refs: #666, #670 --- apps/studio/src/ui/StudioWorkspace.test.tsx | 6 ++---- docs/testing.md | 7 ++++++- packages/ui/src/test/setup.ts | 9 +++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/studio/src/ui/StudioWorkspace.test.tsx b/apps/studio/src/ui/StudioWorkspace.test.tsx index 7524f9284..a42c9b9d9 100644 --- a/apps/studio/src/ui/StudioWorkspace.test.tsx +++ b/apps/studio/src/ui/StudioWorkspace.test.tsx @@ -1647,7 +1647,7 @@ describe("StudioWorkspace", () => { expect(status.getByText("Draft saved")).toBeInTheDocument(); fireEvent.input(title, { target: { value: "Pods!" } }); expect(status.getByText("Saving the draft…")).toBeInTheDocument(); - expect(await status.findByText("Draft saved", {}, { timeout: 3000 })).toBeInTheDocument(); + expect(await status.findByText("Draft saved")).toBeInTheDocument(); expect(useCases.editReleaseDraft).toHaveBeenCalledTimes(1); }); @@ -1666,9 +1666,7 @@ describe("StudioWorkspace", () => { const title = await screen.findByRole("textbox", { name: "Title" }); await waitFor(() => expect(title).toBeEnabled()); fireEvent.input(title, { target: { value: "Pods!" } }); - expect( - await status.findByText("Last change not saved", {}, { timeout: 3000 }), - ).toBeInTheDocument(); + expect(await status.findByText("Last change not saved")).toBeInTheDocument(); }); it("keeps the cards' view in the URL, replacing the entry", async () => { diff --git a/docs/testing.md b/docs/testing.md index 35f28a79d..92b62f42d 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1265,7 +1265,12 @@ runs every package's tests at once with coverage on, and takes some tests fifty times as long as a laptop does: the generator's check of `ns/` took over 5 s there, against 0.1 s. Tests that read a file at the size limits, about a second on a laptop, ran out of 30 s on a slow -runner. A test that hangs still fails. +runner. A test that hangs still fails. For the same reason, a +Testing Library query that waits (`findBy…`, `waitFor`) waits 10 s, +not its 1 s. The setting is in `packages/ui/src/test/setup.ts`, which +the Studio's and the web app's setup import. A screen whose button came +after a few reads of its data, about 0.1 s on a laptop, ran out of 1 s +in CI. ## Strategy per layer diff --git a/packages/ui/src/test/setup.ts b/packages/ui/src/test/setup.ts index dce584c22..6662ae4d4 100644 --- a/packages/ui/src/test/setup.ts +++ b/packages/ui/src/test/setup.ts @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT import "@testing-library/jest-dom/vitest"; +import { configure } from "@testing-library/preact"; import { LOCALES } from "@solid-memo/domain/locale"; import { loadLocale } from "../ui/i18n"; @@ -10,6 +11,14 @@ import { loadLocale } from "../ui/i18n"; // before it renders (apps/web/src/main.tsx), so a test speaks any of them. await Promise.all(LOCALES.map(loadLocale)); +// A findBy query or waitFor waits 10 s, not Testing Library's 1 s, for +// what it waits for, as a test may take 60 s, not vitest's 5 +// (vitest.shared.ts): CI takes some tests fifty times as long as a +// laptop does, and a screen that reads its data in a few steps, about +// 0.1 s on a laptop, ran out of the 1 s there. A query that never +// matches still fails, later. +configure({ asyncUtilTimeout: 10_000 }); + // happy-dom has no HTMLElement.translate. Browsers reflect it as the // translate="yes"/"no" attribute, which Preact sets as a property // (`translate={false}` on code from data), so the tests see the same.