From 07394fdaf86cc06576a6a46880115733829c741c Mon Sep 17 00:00:00 2001 From: David Cho-Lerat Date: Fri, 24 Nov 2023 12:37:49 +0100 Subject: [PATCH] SONAR-21017 Tests: fix the use of Jest fake timers --- .../__tests__/DropdownMenu-test.tsx | 14 +++++++---- .../input/__tests__/DateRangePicker-test.tsx | 11 +++++---- .../__tests__/ComponentContainer-test.tsx | 24 +++++++++++-------- .../__tests__/IssuesApp-Filtering-it.tsx | 3 ++- .../controls/__tests__/clipboard-test.tsx | 6 ++--- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx b/server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx index e7e9776cf55..131e881e4e6 100644 --- a/server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx +++ b/server/sonar-web/design-system/src/components/__tests__/DropdownMenu-test.tsx @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { screen } from '@testing-library/react'; +import { act, screen, waitFor } from '@testing-library/react'; import { noop } from 'lodash'; import { render, renderWithRouter } from '../../helpers/testUtils'; import { @@ -65,14 +65,20 @@ it('menu items should work with tooltips', async () => { await user.hover(screen.getByRole('menuitem')); expect(screen.queryByRole('tooltip')).not.toBeInTheDocument(); - jest.runAllTimers(); + act(() => { + jest.runAllTimers(); + }); expect(screen.getByRole('tooltip')).toBeVisible(); await user.unhover(screen.getByRole('menuitem')); expect(screen.getByRole('tooltip')).toBeVisible(); - jest.runAllTimers(); - expect(screen.queryByRole('tooltip')).not.toBeInTheDocument(); + act(() => { + jest.runAllTimers(); + }); + await waitFor(() => { + expect(screen.queryByRole('tooltip')).not.toBeInTheDocument(); + }); }); function renderDropdownMenu() { diff --git a/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx b/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx index 6dcbbe82762..2b6c9e5e04d 100644 --- a/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx +++ b/server/sonar-web/design-system/src/components/input/__tests__/DateRangePicker-test.tsx @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { screen } from '@testing-library/react'; +import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { formatISO, parseISO } from 'date-fns'; import { byRole } from '../../../../../src/main/js/helpers/testSelector'; @@ -43,12 +43,13 @@ it('behaves correctly', async () => { await user.click(screen.getByRole('textbox', { name: 'from' })); - expect(nav.get()).toBeInTheDocument(); + const fromNav = nav.get(); + expect(fromNav).toBeInTheDocument(); await user.click(nav.byRole('button', { name: 'previous_month_x' }).get()); await user.click(screen.getByText('7')); - expect(nav.query()).not.toBeInTheDocument(); + expect(fromNav).not.toBeInTheDocument(); expect(onChange).toHaveBeenCalled(); const { from } = onChange.mock.calls[0][0]; // first argument @@ -57,7 +58,9 @@ it('behaves correctly', async () => { onChange.mockClear(); - jest.runAllTimers(); + act(() => { + jest.runAllTimers(); + }); const previousButton = nav.byRole('button', { name: 'previous_month_x' }); const nextButton = nav.byRole('button', { name: 'next_month_x' }); diff --git a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx index 76e98ef85d0..045fb4d4b90 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { screen, waitFor } from '@testing-library/react'; +import { act, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React, { useContext } from 'react'; import { Route } from 'react-router-dom'; @@ -155,6 +155,7 @@ describe('getTasksForComponent', () => { }); afterEach(() => { + jest.runOnlyPendingTimers(); jest.useRealTimers(); }); @@ -176,8 +177,9 @@ describe('getTasksForComponent', () => { await waitFor(() => { expect(getComponentNavigation).toHaveBeenCalledTimes(1); }); - expect(getComponentNavigation).toHaveBeenCalledTimes(1); - expect(getTasksForComponent).toHaveBeenCalledTimes(1); + await waitFor(() => expect(getTasksForComponent).toHaveBeenCalledTimes(1)); + + act(() => jest.runOnlyPendingTimers()); jest.runOnlyPendingTimers(); @@ -195,7 +197,8 @@ describe('getTasksForComponent', () => { expect(getTasksForComponent).toHaveBeenCalledTimes(3); // Make sure the timeout was cleared. It should not be called again. - jest.runAllTimers(); + act(() => jest.runAllTimers()); + // The number of calls haven't changed. await waitFor(() => { expect(getComponentNavigation).toHaveBeenCalledTimes(2); @@ -225,7 +228,9 @@ describe('getTasksForComponent', () => { await waitFor(() => { expect(getComponentNavigation).toHaveBeenCalledTimes(1); }); - expect(getTasksForComponent).toHaveBeenCalledTimes(1); + await waitFor(() => expect(getTasksForComponent).toHaveBeenCalledTimes(1)); + + act(() => jest.runOnlyPendingTimers()); jest.runOnlyPendingTimers(); @@ -259,7 +264,7 @@ describe('getTasksForComponent', () => { expect(getComponentNavigation).toHaveBeenCalledTimes(1); }); - expect(getTasksForComponent).toHaveBeenCalledTimes(1); + await waitFor(() => expect(getTasksForComponent).toHaveBeenCalledTimes(1)); }); it('only fully reloads a non-empty component if there was previously some task in progress', async () => { @@ -281,10 +286,9 @@ describe('getTasksForComponent', () => { // First round, a pending task in the queue. This should trigger a reload of the // status endpoint. - await waitFor(() => { - expect(getTasksForComponent).toHaveBeenCalledTimes(1); - }); - jest.runOnlyPendingTimers(); + await waitFor(() => expect(getTasksForComponent).toHaveBeenCalledTimes(1)); + + act(() => jest.runOnlyPendingTimers()); // Second round, nothing in the queue, and a success task is current. This // implies the current task was updated, and previously we displayed some information diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx index 2e2320f6f0b..06827728ca1 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx @@ -64,7 +64,7 @@ beforeEach(() => { describe('issues app filtering', () => { it('should combine sidebar filters properly', async () => { jest.useFakeTimers(); - const user = userEvent.setup({ delay: null }); + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); renderIssueApp(); await waitOnDataLoaded(); @@ -157,6 +157,7 @@ describe('issues app filtering', () => { expect(ui.issueItem5.get()).toBeInTheDocument(); expect(ui.issueItem6.get()).toBeInTheDocument(); expect(ui.issueItem7.get()).toBeInTheDocument(); + jest.runOnlyPendingTimers(); jest.useRealTimers(); }); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/clipboard-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/clipboard-test.tsx index c6670938912..d97bbda87b9 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/clipboard-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/clipboard-test.tsx @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { screen } from '@testing-library/react'; +import { act, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; import { renderComponent } from '../../../helpers/testReactTestingUtils'; @@ -45,13 +45,13 @@ describe('ClipboardBase', () => { }); it('should allow its content to be copied', async () => { - const user = userEvent.setup(); + const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); renderClipboardBase(); user.click(screen.getByRole('button')); expect(await screen.findByText('copied')).toBeInTheDocument(); - jest.runAllTimers(); + act(() => jest.runAllTimers()); expect(screen.getByText('click to copy')).toBeInTheDocument(); }); -- 2.39.5