diff --git a/packages/@adobe/react-spectrum/test/checkbox/CheckboxGroup.test.js b/packages/@adobe/react-spectrum/test/checkbox/CheckboxGroup.test.js index 318b0cdf710..0201e86fbf2 100644 --- a/packages/@adobe/react-spectrum/test/checkbox/CheckboxGroup.test.js +++ b/packages/@adobe/react-spectrum/test/checkbox/CheckboxGroup.test.js @@ -743,8 +743,11 @@ describe('CheckboxGroup', () => { let group = getByRole('group'); expect(group).not.toHaveAttribute('aria-describedby'); - act(() => { + await act(async () => { getByTestId('form').checkValidity(); + // Flush the microtask queued by the global invalid event handler, + // which moves focus to the first invalid field and updates modality. + await Promise.resolve(); }); expect(group).toHaveAttribute('aria-describedby'); expect(document.getElementById(group.getAttribute('aria-describedby'))).toHaveTextContent( diff --git a/packages/@adobe/react-spectrum/test/radio/Radio.test.js b/packages/@adobe/react-spectrum/test/radio/Radio.test.js index 6a668365f13..e2d6ce649a7 100644 --- a/packages/@adobe/react-spectrum/test/radio/Radio.test.js +++ b/packages/@adobe/react-spectrum/test/radio/Radio.test.js @@ -1051,8 +1051,11 @@ describe('Radios', function () { let group = getByRole('radiogroup'); expect(group).not.toHaveAttribute('aria-describedby'); - act(() => { + await act(async () => { getByTestId('form').checkValidity(); + // Flush the microtask queued by the global invalid event handler, + // which moves focus to the first invalid field and updates modality. + await Promise.resolve(); }); expect(group).toHaveAttribute('aria-describedby'); expect(document.getElementById(group.getAttribute('aria-describedby'))).toHaveTextContent( diff --git a/packages/@adobe/react-spectrum/test/textfield/TextField.test.js b/packages/@adobe/react-spectrum/test/textfield/TextField.test.js index a63420f4122..ae7c9b23673 100644 --- a/packages/@adobe/react-spectrum/test/textfield/TextField.test.js +++ b/packages/@adobe/react-spectrum/test/textfield/TextField.test.js @@ -768,8 +768,11 @@ describe('Shared TextField behavior', () => { let input = getByTestId('input'); expect(input).not.toHaveAttribute('aria-describedby'); - act(() => { + await act(async () => { getByTestId('form').checkValidity(); + // Flush the microtask queued by the global invalid event handler, + // which moves focus to the first invalid field and updates modality. + await Promise.resolve(); }); expect(input).toHaveAttribute('aria-describedby'); expect(document.getElementById(input.getAttribute('aria-describedby'))).toHaveTextContent( diff --git a/packages/react-aria-components/test/Form.test.js b/packages/react-aria-components/test/Form.test.js index 7be04208d54..891fd74cef1 100644 --- a/packages/react-aria-components/test/Form.test.js +++ b/packages/react-aria-components/test/Form.test.js @@ -199,6 +199,38 @@ describe('Form', () => { expect(form).toHaveAttribute('data-custom', 'true'); }); + (parseInt(React.version, 10) >= 19 ? it : it.skip)('shows focus-visible when a form library moves focus to the first invalid field on submit', async () => { + function Test() { + return ( +
+ ); + } + + let {getByRole} = render(