diff --git a/frontend/src/components/user/list.js b/frontend/src/components/user/list.js index 6dee901127..1739cd6a5c 100644 --- a/frontend/src/components/user/list.js +++ b/frontend/src/components/user/list.js @@ -339,7 +339,7 @@ export const UsersTable = ({ filters, setFilters, levels }) => { {userDetails.username !== row.original.username && ( + { className="user-popup" > {(close) => ( - +
+ +
)}
)} @@ -490,7 +492,7 @@ export const UserEditMenu = ({ user, token, close, setStatus, levels }) => { }; return ( - <> +

@@ -529,6 +531,6 @@ export const UserEditMenu = ({ user, token, close, setStatus, levels }) => { ); })}

- +
); }; diff --git a/frontend/src/components/user/tests/list.test.js b/frontend/src/components/user/tests/list.test.js index 0e5498c211..0ee08fa0c0 100644 --- a/frontend/src/components/user/tests/list.test.js +++ b/frontend/src/components/user/tests/list.test.js @@ -16,7 +16,7 @@ jest.mock('react-hot-toast', () => ({ describe('User list card', () => { it('renders user card', async () => { - const { container, getByText, getAllByRole } = renderWithRouter( + const { container, getByText } = renderWithRouter( { return { user, router }; }; + jest.retryTimes(2); it('should stop mapping and direct to tasks selection page', async () => { - act(() => { + await act(() => { store.dispatch({ type: 'SET_LOCALE', locale: 'en-US' }); store.dispatch({ type: 'SET_TOKEN', token: 'validToken' }); store.dispatch({ diff --git a/frontend/src/views/tests/teams.test.js b/frontend/src/views/tests/teams.test.js index 9e16cb3d34..5e8f79889c 100644 --- a/frontend/src/views/tests/teams.test.js +++ b/frontend/src/views/tests/teams.test.js @@ -127,6 +127,7 @@ describe('Create Team', () => { }); describe('Edit Team', () => { + jest.retryTimes(2); it('should display default details of the team before editing', async () => { await act(() => { store.dispatch({ diff --git a/frontend/src/views/tests/users.test.js b/frontend/src/views/tests/users.test.js index 2c0e21496c..4d988c2228 100644 --- a/frontend/src/views/tests/users.test.js +++ b/frontend/src/views/tests/users.test.js @@ -55,17 +55,32 @@ describe('List Users', () => { }); }); +// Retry failed tests up to 2 times to handle occasional async flakiness +jest.retryTimes(2); describe('Change of role and mapper level', () => { - const setup = () => { + const setup = async () => { const { user, container } = renderWithRouter( - + , ); - return { - user, - container, - }; + + // wait until loading spinner gone + await waitFor(() => + expect(container.getElementsByClassName('show-loading-animation').length).toBe(0), + ); + + // wait for table body + const tbody = await screen.findByTestId('user-list'); + + // ensure rows & triggers are stable + await waitFor(() => { + const triggers = within(tbody).getAllByTestId('action-trigger'); + expect(triggers.length).toBeGreaterThan(0); + expect(screen.getByText(/Ram/i)).toBeInTheDocument(); + }); + + return { tbody, user, container }; }; beforeEach(() => { @@ -73,34 +88,42 @@ describe('Change of role and mapper level', () => { if (popupRoot) popupRoot.innerHTML = ''; }); - it('should call endpoint to update role', async () => { - const { user, container } = setup(); + it('should call endpoint to update level', async () => { + const { tbody, user, container } = await setup(); + + const triggers = await within(tbody).findAllByTestId('action-trigger'); + await user.click(triggers[0]); + + const tooltip = await screen.findByTestId('action-content', {}, { timeout: 1000 }); + + const advancedOption = await within(tooltip).findByText(/advanced/i); + await user.click(advancedOption); + + await waitFor(() => { + expect(screen.queryByTestId('action-content')).not.toBeInTheDocument(); + }); await waitFor(() => expect(container.getElementsByClassName('show-loading-animation').length).toBe(0), ); - await user.click(container.getElementsByClassName('pointer hover-blue-grey')[0]); - const tooltip = await screen.findByRole('tooltip'); - await user.click(within(tooltip).getByText(/advanced/i)); - await waitFor( - () => - expect(tooltip).not.toBeInTheDocument() && - expect(container.getElementsByClassName('show-loading-animation').length).toBe(16), - ); }); - it('should call endpoint to update level', async () => { - const { user, container } = setup(); + it('should call endpoint to update Role', async () => { + const { tbody, user, container } = await setup(); + + const triggers = await within(tbody).findAllByTestId('action-trigger'); + await user.click(triggers[0]); + + const tooltip = await screen.findByTestId('action-content', {}, { timeout: 1000 }); + + const adminOption = await within(tooltip).findByText(/admin/i); + await user.click(adminOption); + + await waitFor(() => { + expect(screen.queryByTestId('action-content')).not.toBeInTheDocument(); + }); await waitFor(() => expect(container.getElementsByClassName('show-loading-animation').length).toBe(0), ); - await user.click(container.getElementsByClassName('pointer hover-blue-grey')[0]); - const tooltip = await screen.findByRole('tooltip'); - await user.click(within(tooltip).getByText(/admin/i)); - await waitFor( - () => - expect(tooltip).not.toBeInTheDocument() && - expect(container.getElementsByClassName('show-loading-animation').length).toBe(16), - ); }); });