This is an automated email from the ASF dual-hosted git repository.

jli pushed a commit to branch fix-use-theme-menu-test
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 49653dee982e1411783105959894b614bfde0112
Author: Joe Li <[email protected]>
AuthorDate: Thu Oct 30 14:39:33 2025 -0700

    test(useThemeMenuItems): add await to all userEvent calls to prevent race 
conditions
    
    Fixed 20 unawaited userEvent calls (16 hover + 4 click) that could cause 
race conditions
    between user interactions and assertions. This ensures menu rendering 
completes before
    queries execute, preventing intermittent test failures.
    
    Pattern follows commit 4932f3522f which fixed the same issue in 
DatasourceControl tests.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <[email protected]>
---
 .../src/hooks/useThemeMenuItems.test.tsx           | 40 +++++++++++-----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/superset-frontend/src/hooks/useThemeMenuItems.test.tsx 
b/superset-frontend/src/hooks/useThemeMenuItems.test.tsx
index ab0f9ee06b..bdbceec89b 100644
--- a/superset-frontend/src/hooks/useThemeMenuItems.test.tsx
+++ b/superset-frontend/src/hooks/useThemeMenuItems.test.tsx
@@ -70,7 +70,7 @@ describe('useThemeMenuItems', () => {
   test('renders Light and Dark theme options by default', async () => {
     renderThemeMenu();
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Light');
 
     expect(within(menu!).getByText('Light')).toBeInTheDocument();
@@ -79,7 +79,7 @@ describe('useThemeMenuItems', () => {
 
   test('does not render Match system option when allowOSPreference is false', 
async () => {
     renderThemeMenu({ ...defaultProps, allowOSPreference: false });
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
 
     await waitFor(() => {
       expect(screen.queryByText('Match system')).not.toBeInTheDocument();
@@ -89,7 +89,7 @@ describe('useThemeMenuItems', () => {
   test('renders with allowOSPreference as true by default', async () => {
     renderThemeMenu();
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Match system');
 
     expect(within(menu).getByText('Match system')).toBeInTheDocument();
@@ -103,7 +103,7 @@ describe('useThemeMenuItems', () => {
       onClearLocalSettings: mockClear,
     });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Clear local theme');
 
     expect(within(menu).getByText('Clear local theme')).toBeInTheDocument();
@@ -117,7 +117,7 @@ describe('useThemeMenuItems', () => {
       onClearLocalSettings: mockClear,
     });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
 
     await waitFor(() => {
       expect(screen.queryByText('Clear local theme')).not.toBeInTheDocument();
@@ -128,9 +128,9 @@ describe('useThemeMenuItems', () => {
     const mockSet = jest.fn();
     renderThemeMenu({ ...defaultProps, setThemeMode: mockSet });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Light');
-    userEvent.click(within(menu).getByText('Light'));
+    await userEvent.click(within(menu).getByText('Light'));
 
     expect(mockSet).toHaveBeenCalledWith(ThemeMode.DEFAULT);
   });
@@ -139,9 +139,9 @@ describe('useThemeMenuItems', () => {
     const mockSet = jest.fn();
     renderThemeMenu({ ...defaultProps, setThemeMode: mockSet });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Dark');
-    userEvent.click(within(menu).getByText('Dark'));
+    await userEvent.click(within(menu).getByText('Dark'));
 
     expect(mockSet).toHaveBeenCalledWith(ThemeMode.DARK);
   });
@@ -150,9 +150,9 @@ describe('useThemeMenuItems', () => {
     const mockSet = jest.fn();
     renderThemeMenu({ ...defaultProps, setThemeMode: mockSet });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Match system');
-    userEvent.click(within(menu).getByText('Match system'));
+    await userEvent.click(within(menu).getByText('Match system'));
 
     expect(mockSet).toHaveBeenCalledWith(ThemeMode.SYSTEM);
   });
@@ -165,9 +165,9 @@ describe('useThemeMenuItems', () => {
       onClearLocalSettings: mockClear,
     });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Clear local theme');
-    userEvent.click(within(menu).getByText('Clear local theme'));
+    await userEvent.click(within(menu).getByText('Clear local theme'));
 
     expect(mockClear).toHaveBeenCalledTimes(1);
   });
@@ -195,7 +195,7 @@ describe('useThemeMenuItems', () => {
   test('renders Theme group header', async () => {
     renderThemeMenu();
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Theme');
 
     expect(within(menu).getByText('Theme')).toBeInTheDocument();
@@ -204,7 +204,7 @@ describe('useThemeMenuItems', () => {
   test('renders sun icon for Light theme option', async () => {
     renderThemeMenu();
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Light');
     const lightOption = within(menu).getByText('Light').closest('li');
 
@@ -214,7 +214,7 @@ describe('useThemeMenuItems', () => {
   test('renders moon icon for Dark theme option', async () => {
     renderThemeMenu();
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Dark');
     const darkOption = within(menu).getByText('Dark').closest('li');
 
@@ -224,7 +224,7 @@ describe('useThemeMenuItems', () => {
   test('renders format-painter icon for Match system option', async () => {
     renderThemeMenu({ ...defaultProps, allowOSPreference: true });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Match system');
     const matchOption = within(menu).getByText('Match system').closest('li');
 
@@ -240,7 +240,7 @@ describe('useThemeMenuItems', () => {
       onClearLocalSettings: jest.fn(),
     });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const menu = await findMenuWithText('Clear local theme');
     const clearOption = within(menu)
       .getByText('Clear local theme')
@@ -256,7 +256,7 @@ describe('useThemeMenuItems', () => {
       onClearLocalSettings: jest.fn(),
     });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
 
     const menu = await findMenuWithText('Clear local theme');
     const divider = within(menu).queryByRole('separator');
@@ -267,7 +267,7 @@ describe('useThemeMenuItems', () => {
   test('does not render divider when clear option is not present', async () => 
{
     renderThemeMenu({ ...defaultProps });
 
-    userEvent.hover(await screen.findByRole('menuitem'));
+    await userEvent.hover(await screen.findByRole('menuitem'));
     const divider = document.querySelector('.ant-menu-item-divider');
 
     expect(divider).toBeNull();

Reply via email to