From 5dd62f1a98c1be4b312a35a0d21b6849435ced3d Mon Sep 17 00:00:00 2001 From: Ian Arawjo Date: Thu, 22 Oct 2026 12:51:33 -0400 Subject: [PATCH] Find the Prompt Node tests' buttons by text, not role (1.5 s -> 0.1 s) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Prompt Node tests from #479 timed out on CI (Jest's 5 s limit) in two runs on main and two on the PR. Profiling one showed it spent about 1.15 s in a single line: screen.getByRole("button", { name: "▶" }). In jsdom, a role query works out every element's accessible role and name, matching CSS selectors against each, and a rendered Prompt Node has many elements. The node itself rendered in about 170 ms. Finding the Run and Confirm buttons by their text instead takes each test from 1.2-1.9 s to 50-280 ms locally, well clear of the limit on CI's slower runners. The tests check the same things. Co-Authored-By: Claude Opus 5.5 --- .../src/backend/__test__/promptNodeBehavior.test.tsx | 8 ++++++-- .../src/backend/__test__/promptNodeRunEdits.test.tsx | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/chainforge/react-server/src/backend/__test__/promptNodeBehavior.test.tsx b/chainforge/react-server/src/backend/__test__/promptNodeBehavior.test.tsx index 0a406c3c1..27bbcb8b2 100644 --- a/chainforge/react-server/src/backend/__test__/promptNodeBehavior.test.tsx +++ b/chainforge/react-server/src/backend/__test__/promptNodeBehavior.test.tsx @@ -174,7 +174,9 @@ const type = (container: HTMLElement, value: string) => }); const clickRun = () => - fireEvent.click(screen.getByRole("button", { name: "▶" })); + // By its text, not getByRole: in jsdom, a role query works out every + // element's accessible role and name, which here takes about a second + fireEvent.click(screen.getByText("▶").closest("button") as HTMLElement); /** What was saved to the flow, by property. */ const saved = (prop: string) => @@ -303,7 +305,9 @@ describe("a Prompt Node, as it always has", () => { // The variant controls' trash icon comes before the models' const trash = container.querySelector(".tabler-icon-trash") as SVGElement; fireEvent.click(trash.closest("button") as HTMLButtonElement); - fireEvent.click(await screen.findByRole("button", { name: "Confirm" })); + fireEvent.click( + (await screen.findByText("Confirm")).closest("button") as HTMLElement, + ); await wait(0); expect(saved("prompt")).toEqual([["A", "C"]]); expect(saved("promptVariantLabel")).toEqual([]); diff --git a/chainforge/react-server/src/backend/__test__/promptNodeRunEdits.test.tsx b/chainforge/react-server/src/backend/__test__/promptNodeRunEdits.test.tsx index bbc335690..3d3b21752 100644 --- a/chainforge/react-server/src/backend/__test__/promptNodeRunEdits.test.tsx +++ b/chainforge/react-server/src/backend/__test__/promptNodeRunEdits.test.tsx @@ -165,7 +165,9 @@ const type = (container: HTMLElement, value: string) => }); const clickRun = () => - fireEvent.click(screen.getByRole("button", { name: "▶" })); + // By its text, not getByRole: in jsdom, a role query works out every + // element's accessible role and name, which here takes about a second + fireEvent.click(screen.getByText("▶").closest("button") as HTMLElement); /** What each query was sent: its prompt, its models and its inputs. */ const promptsSent = () => mockQueryLLM.mock.calls.map((call) => call[3]);