From 6d5248a6829ef8297d0aef315903f2214bd74a6e Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Tue, 11 Nov 2025 15:31:25 -0800 Subject: [PATCH 1/4] test(gsadmin): Fix flake in BalanceChangeAction tests Attempting to silence this flake. I think the form is rerendering in some cases and the reference is to elements that have been deleted or will be deleted. Instead, in the waitFor re-query for the form field so we have the latest element. --- .../components/changeBalanceAction.spec.tsx | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/static/gsAdmin/components/changeBalanceAction.spec.tsx b/static/gsAdmin/components/changeBalanceAction.spec.tsx index 811277209ccad0..ac86d6178ecda2 100644 --- a/static/gsAdmin/components/changeBalanceAction.spec.tsx +++ b/static/gsAdmin/components/changeBalanceAction.spec.tsx @@ -174,31 +174,42 @@ describe('BalanceChangeAction', () => { triggerChangeBalanceModal({subscription, ...modalProps}); renderGlobalModal(); - // Pre-grab stable references to fields using findBy to wait for modal content - const creditInput = await screen.findByRole('spinbutton', {name: 'Credit Amount'}); - const urlField = await screen.findByTestId('url-field'); - const notesField = await screen.findByTestId('notes-field'); - const submitButton = screen.getByRole('button', {name: /submit/i}); + // Wait for modal content + expect(await screen.findByTestId('url-field')).toBeInTheDocument(); + expect(await screen.findByTestId('notes-field')).toBeInTheDocument(); - await userEvent.type(creditInput, '10'); - await waitFor(() => expect(creditInput).toHaveValue(10)); + await userEvent.type( + await screen.findByRole('spinbutton', {name: 'Credit Amount'}), + '10' + ); + await waitFor( + () => + expect(screen.getByRole('spinbutton', {name: 'Credit Amount'})).toHaveValue(10), + {timeout: 5_000} + ); // Wait for button to be enabled before clicking - await waitFor(() => expect(submitButton).toBeEnabled()); + await waitFor(() => + expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled() + ); // Disable pointer-events check to avoid false positive in CI // where modal overlay may still be settling during initialization - await userEvent.click(submitButton, {pointerEventsCheck: 0}); + await userEvent.click(screen.getByRole('button', {name: /submit/i}), { + pointerEventsCheck: 0, + }); // Wait for form to be re-enabled after error // Don't rely on error message text as the Form component shows different messages // depending on error response structure. All fields are controlled by isSubmitting // state, so if one is enabled, all should be enabled. - await waitFor(() => expect(creditInput).toBeEnabled()); + await waitFor(() => + expect(screen.getByRole('spinbutton', {name: 'Credit Amount'})).toBeEnabled() + ); // Verify all fields and submit button are re-enabled - expect(urlField).toBeEnabled(); - expect(notesField).toBeEnabled(); - expect(submitButton).toBeEnabled(); + expect(await screen.findByTestId('url-field')).toBeEnabled(); + expect(await screen.findByTestId('notes-field')).toBeEnabled(); + expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled(); }); }); From 9b0ee31fd151b5a01f0199cf648aaff3af72a630 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Tue, 11 Nov 2025 15:44:31 -0800 Subject: [PATCH 2/4] extend timeouts --- static/gsAdmin/components/changeBalanceAction.spec.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/static/gsAdmin/components/changeBalanceAction.spec.tsx b/static/gsAdmin/components/changeBalanceAction.spec.tsx index ac86d6178ecda2..d709ab34b86349 100644 --- a/static/gsAdmin/components/changeBalanceAction.spec.tsx +++ b/static/gsAdmin/components/changeBalanceAction.spec.tsx @@ -189,8 +189,9 @@ describe('BalanceChangeAction', () => { ); // Wait for button to be enabled before clicking - await waitFor(() => - expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled() + await waitFor( + () => expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled(), + {timeout: 5_000} ); // Disable pointer-events check to avoid false positive in CI @@ -211,5 +212,5 @@ describe('BalanceChangeAction', () => { expect(await screen.findByTestId('url-field')).toBeEnabled(); expect(await screen.findByTestId('notes-field')).toBeEnabled(); expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled(); - }); + }, 20_000); }); From 618e42902ff04c7d7e817a35281ed3f9f0cc8f87 Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Tue, 11 Nov 2025 16:11:28 -0800 Subject: [PATCH 3/4] find button --- static/gsAdmin/components/changeBalanceAction.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/gsAdmin/components/changeBalanceAction.spec.tsx b/static/gsAdmin/components/changeBalanceAction.spec.tsx index d709ab34b86349..20f5b6dcfb8dbf 100644 --- a/static/gsAdmin/components/changeBalanceAction.spec.tsx +++ b/static/gsAdmin/components/changeBalanceAction.spec.tsx @@ -196,7 +196,7 @@ describe('BalanceChangeAction', () => { // Disable pointer-events check to avoid false positive in CI // where modal overlay may still be settling during initialization - await userEvent.click(screen.getByRole('button', {name: /submit/i}), { + await userEvent.click(await screen.findByRole('button', {name: /submit/i}), { pointerEventsCheck: 0, }); From 30e40ce0910d2145dc02d364f8f937fd654115ca Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Tue, 11 Nov 2025 17:05:11 -0800 Subject: [PATCH 4/4] what is wrong with this form --- static/gsAdmin/components/changeBalanceAction.spec.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/static/gsAdmin/components/changeBalanceAction.spec.tsx b/static/gsAdmin/components/changeBalanceAction.spec.tsx index 20f5b6dcfb8dbf..2f67097fd4e95e 100644 --- a/static/gsAdmin/components/changeBalanceAction.spec.tsx +++ b/static/gsAdmin/components/changeBalanceAction.spec.tsx @@ -204,13 +204,14 @@ describe('BalanceChangeAction', () => { // Don't rely on error message text as the Form component shows different messages // depending on error response structure. All fields are controlled by isSubmitting // state, so if one is enabled, all should be enabled. - await waitFor(() => - expect(screen.getByRole('spinbutton', {name: 'Credit Amount'})).toBeEnabled() + await waitFor( + () => expect(screen.getByRole('spinbutton', {name: 'Credit Amount'})).toBeEnabled(), + {timeout: 5_000} ); // Verify all fields and submit button are re-enabled expect(await screen.findByTestId('url-field')).toBeEnabled(); expect(await screen.findByTestId('notes-field')).toBeEnabled(); expect(screen.getByRole('button', {name: /submit/i})).toBeEnabled(); - }, 20_000); + }, 25_000); });