From 0843f32d92be0789423c72473b9158933517419e Mon Sep 17 00:00:00 2001 From: Gabriel Garcia Date: Fri, 11 Sep 2026 16:50:18 +0200 Subject: [PATCH] fix(tests): close radiogroup re-query race in fillRadio helper fillRadio/assertRadioValue waited for a radiogroup via waitFor(), then discarded that result and re-queried synchronously with getByRole. If the group briefly unmounted again between those two calls (e.g. a step re-entering a loading state from a second async fetch), the second call threw even though the first had just succeeded - the likely cause of the flaky ContractorOnboarding "Invite Contractor" test failure. Both helpers now keep the element waitFor() already resolved instead of re-querying. Co-Authored-By: Claude Sonnet 5 --- src/tests/testHelpers.tsx | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/tests/testHelpers.tsx b/src/tests/testHelpers.tsx index 42e779de1..ba192673a 100644 --- a/src/tests/testHelpers.tsx +++ b/src/tests/testHelpers.tsx @@ -48,19 +48,14 @@ export async function assertRadioValue( radioName: string, expectedValue: string, ) { - // Wait for the radio group to be available - await waitFor(() => { - const radioGroup = screen.getByRole('radiogroup', { + // Wait for the radio group to be available, keeping the resolved element + // instead of re-querying afterwards (which raced against the group + // briefly unmounting again, e.g. during a second async loading phase) + const radioGroup = await waitFor(() => + screen.getByRole('radiogroup', { name: new RegExp(radioName, 'i'), - }); - expect(radioGroup).toBeInTheDocument(); - }); - - // Get the radio group - const radioGroup = screen.getByRole('radiogroup', { - name: new RegExp(radioName, 'i'), - }); - expect(radioGroup).toBeInTheDocument(); + }), + ); // Find all radio buttons within the group const radioButtons = within(radioGroup).getAllByRole('radio'); @@ -86,15 +81,12 @@ export async function assertRadioValue( export async function fillRadio(radioName: string, radioValue: string) { const user = userEvent.setup(); - // Wait for the radio group to be available - use role-based query for specificity - await waitFor(() => { - screen.getByRole('radiogroup', { name: new RegExp(radioName, 'i') }); - }); - - // Get the specific radiogroup by role (not just by text) - const radioGroup = screen.getByRole('radiogroup', { - name: new RegExp(radioName, 'i'), - }); + // Wait for the radio group to be available, keeping the resolved element + // instead of re-querying afterwards (which raced against the group + // briefly unmounting again, e.g. during a second async loading phase) + const radioGroup = await waitFor(() => + screen.getByRole('radiogroup', { name: new RegExp(radioName, 'i') }), + ); // Find the radio button within that group const radioButton = within(radioGroup).getByRole('radio', {