From d88ce8998ff1d5972645d8104385e83ca04f65fa Mon Sep 17 00:00:00 2001 From: David Lechner Date: Fri, 10 Mar 2023 13:51:11 -0600 Subject: [PATCH] test: wrap all user calls in act() Some user events trigger react dom changes. These need to be wrapped in act() to avoid a warning printed to the console. To be save, we wrap all instances. --- src/about/AboutDialog.test.tsx | 10 ++-- src/activities/Activities.test.tsx | 8 ++-- src/alerts/UnexpectedErrorAlert.test.tsx | 3 +- src/app/alerts/UpdateServerFailure.test.tsx | 3 +- src/ble/alerts/BluetoothNotAvailable.test.tsx | 3 +- src/ble/alerts/MissingService.test.tsx | 3 +- src/ble/alerts/NoGatt.test.tsx | 3 +- src/ble/alerts/NoHub.test.tsx | 5 +- src/ble/alerts/NoWebBluetooth.test.tsx | 3 +- src/ble/alerts/OldFimrware.test.tsx | 5 +- src/components/toolbar/Toolbar.test.tsx | 26 +++++----- src/editor/Editor.test.tsx | 40 ++++++++++------ src/explorer/Explorer.test.tsx | 48 +++++++++---------- src/explorer/alerts/FileInUseAlert.test.tsx | 3 +- src/explorer/alerts/NoFilesToBackup.test.tsx | 3 +- src/explorer/alerts/NoPyFiles.test.tsx | 3 +- .../deleteFileAlert/DeleteFileAlert.test.tsx | 12 ++--- .../DuplicateFileDialog.test.tsx | 13 ++--- .../FileNameFormGroup.test.tsx | 8 ++-- .../newFileWizard/NewFileWizard.test.tsx | 22 +++++---- .../RenameFileDialog.test.tsx | 11 +++-- .../RenameImportDialog.test.tsx | 13 ++--- .../ReplaceImportDialog.test.tsx | 7 +-- src/firmware/alerts/DfuError.test.tsx | 5 +- src/firmware/alerts/FlashProgress.test.tsx | 3 +- src/firmware/alerts/NoDfuHub.test.tsx | 5 +- src/firmware/alerts/NoDfuInterface.test.tsx | 3 +- src/firmware/alerts/NoWebUsb.test.tsx | 3 +- src/firmware/alerts/ReleaseButton.test.tsx | 3 +- .../DfuWindowsDriverInstallDialog.test.tsx | 10 ++-- .../InstallPybricksDialog.test.tsx | 14 +++--- .../RestoreOfficialDialog.test.tsx | 18 +++---- src/hub/alerts/UserProgramSize.test.tsx | 3 +- src/licenses/LicenseDialog.test.tsx | 6 +-- src/mpy/alerts/CompileError.test.tsx | 5 +- src/settings/Settings.test.tsx | 16 +++---- src/sponsor/alerts/AddressCopied.test.tsx | 3 +- src/status-bar/StatusBar.test.tsx | 8 ++-- .../bluetooth/BluetoothButton.test.tsx | 6 +-- src/toolbar/buttons/repl/ReplButton.test.tsx | 6 +-- src/toolbar/buttons/run/RunButton.test.tsx | 6 +-- src/toolbar/buttons/stop/StopButton.test.tsx | 6 +-- 42 files changed, 212 insertions(+), 172 deletions(-) diff --git a/src/about/AboutDialog.test.tsx b/src/about/AboutDialog.test.tsx index 3427cf62..3be08e54 100644 --- a/src/about/AboutDialog.test.tsx +++ b/src/about/AboutDialog.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2021-2022 The Pybricks Authors +// Copyright (c) 2021-2023 The Pybricks Authors -import { getByLabelText, waitFor } from '@testing-library/react'; +import { act, getByLabelText, waitFor } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import AboutDialog from './AboutDialog'; @@ -11,7 +11,7 @@ it('should close when the button is clicked', async () => { const [user, dialog] = testRender(); - await user.click(dialog.getByLabelText('Close')); + await act(() => user.click(dialog.getByLabelText('Close'))); expect(close).toHaveBeenCalled(); }); @@ -25,7 +25,7 @@ it('should manage license dialog open/close', async () => { dialog.queryByRole('dialog', { name: 'Open Source Software Licenses' }), ).toBeNull(); - await user.click(dialog.getByText('Software Licenses')); + await act(() => user.click(dialog.getByText('Software Licenses'))); const licenseDialog = dialog.getByRole('dialog', { name: 'Open Source Software Licenses', @@ -33,7 +33,7 @@ it('should manage license dialog open/close', async () => { expect(licenseDialog).toBeVisible(); - await user.click(getByLabelText(licenseDialog, 'Close')); + await act(() => user.click(getByLabelText(licenseDialog, 'Close'))); await waitFor(() => expect(licenseDialog).not.toBeVisible()); }); diff --git a/src/activities/Activities.test.tsx b/src/activities/Activities.test.tsx index 0074bfe9..bc99bf5e 100644 --- a/src/activities/Activities.test.tsx +++ b/src/activities/Activities.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import Activities from './Activities'; @@ -48,7 +48,7 @@ describe('Activities', () => { ); } - await user.click(explorerTab); + await act(() => user.click(explorerTab)); for (const tab of activities.getAllByRole('tab')) { expect(tab).toHaveAttribute('aria-selected', 'false'); @@ -68,7 +68,7 @@ describe('Activities', () => { ); } - await user.click(settingsTab); + await act(() => user.click(settingsTab)); for (const tab of activities.getAllByRole('tab')) { expect(tab).toHaveAttribute( diff --git a/src/alerts/UnexpectedErrorAlert.test.tsx b/src/alerts/UnexpectedErrorAlert.test.tsx index 2ece8103..7bcbe15d 100644 --- a/src/alerts/UnexpectedErrorAlert.test.tsx +++ b/src/alerts/UnexpectedErrorAlert.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import { unexpectedError } from './UnexpectedErrorAlert'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/app/alerts/UpdateServerFailure.test.tsx b/src/app/alerts/UpdateServerFailure.test.tsx index b257bfcc..d39bd947 100644 --- a/src/app/alerts/UpdateServerFailure.test.tsx +++ b/src/app/alerts/UpdateServerFailure.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { updateServerFailure } from './UpdateServerFailure'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/ble/alerts/BluetoothNotAvailable.test.tsx b/src/ble/alerts/BluetoothNotAvailable.test.tsx index 3130f93d..00fba949 100644 --- a/src/ble/alerts/BluetoothNotAvailable.test.tsx +++ b/src/ble/alerts/BluetoothNotAvailable.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { bluetoothNotAvailable } from './BluetoothNotAvailable'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/ble/alerts/MissingService.test.tsx b/src/ble/alerts/MissingService.test.tsx index 34fdc5a1..4ff34335 100644 --- a/src/ble/alerts/MissingService.test.tsx +++ b/src/ble/alerts/MissingService.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { missingService } from './MissingService'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/ble/alerts/NoGatt.test.tsx b/src/ble/alerts/NoGatt.test.tsx index b0a3150d..0a018e47 100644 --- a/src/ble/alerts/NoGatt.test.tsx +++ b/src/ble/alerts/NoGatt.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noGatt } from './NoGatt'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/ble/alerts/NoHub.test.tsx b/src/ble/alerts/NoHub.test.tsx index a7bdb7ac..12bf04a6 100644 --- a/src/ble/alerts/NoHub.test.tsx +++ b/src/ble/alerts/NoHub.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noHub } from './NoHub'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); @@ -23,7 +24,7 @@ it('should flash firmware when button is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /firmware/i })); + await act(() => user.click(message.getByRole('button', { name: /firmware/i }))); expect(callback).toHaveBeenCalledWith('flashFirmware'); }); diff --git a/src/ble/alerts/NoWebBluetooth.test.tsx b/src/ble/alerts/NoWebBluetooth.test.tsx index e54389f5..c63b8430 100644 --- a/src/ble/alerts/NoWebBluetooth.test.tsx +++ b/src/ble/alerts/NoWebBluetooth.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noWebBluetooth } from './NoWebBluetooth'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/ble/alerts/OldFimrware.test.tsx b/src/ble/alerts/OldFimrware.test.tsx index 22d3f397..a31e0f9f 100644 --- a/src/ble/alerts/OldFimrware.test.tsx +++ b/src/ble/alerts/OldFimrware.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { oldFirmware } from './OldFirmware'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); @@ -23,7 +24,7 @@ it('should flash firmware when button is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /firmware/i })); + await act(() => user.click(message.getByRole('button', { name: /firmware/i }))); expect(callback).toHaveBeenCalledWith('flashFirmware'); }); diff --git a/src/components/toolbar/Toolbar.test.tsx b/src/components/toolbar/Toolbar.test.tsx index 8d494e63..80a1556e 100644 --- a/src/components/toolbar/Toolbar.test.tsx +++ b/src/components/toolbar/Toolbar.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { RenderResult, cleanup } from '@testing-library/react'; +import { RenderResult, act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { Toolbar } from './Toolbar'; @@ -55,7 +55,7 @@ describe('Toolbar', () => { expect(button2).toHaveAttribute('tabindex', '-1'); expect(button3).toHaveAttribute('tabindex', '-1'); - await user.tab(); + await act(() => user.tab()); expect(button1).toHaveFocus(); expect(button1).not.toHaveAttribute('tabindex'); @@ -69,7 +69,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button1.focus(); - await user.keyboard('{ArrowRight}'); + await act(() => user.keyboard('{ArrowRight}')); expect(button2).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -83,7 +83,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button3.focus(); - await user.keyboard('{ArrowLeft}'); + await act(() => user.keyboard('{ArrowLeft}')); expect(button2).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -97,7 +97,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button3.focus(); - await user.keyboard('{ArrowRight}'); + await act(() => user.keyboard('{ArrowRight}')); expect(button1).toHaveFocus(); expect(button1).not.toHaveAttribute('tabindex'); @@ -111,7 +111,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button1.focus(); - await user.keyboard('{ArrowLeft}'); + await act(() => user.keyboard('{ArrowLeft}')); expect(button3).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -125,7 +125,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button3.focus(); - await user.keyboard('{Home}'); + await act(() => user.keyboard('{Home}')); expect(button1).toHaveFocus(); expect(button1).not.toHaveAttribute('tabindex'); @@ -139,7 +139,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button1.focus(); - await user.keyboard('{End}'); + await act(() => user.keyboard('{End}')); expect(button3).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -153,7 +153,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button2.focus(); - await user.keyboard('{ArrowUp}'); + await act(() => user.keyboard('{ArrowUp}')); expect(button2).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -167,7 +167,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button2.focus(); - await user.keyboard('{ArrowDown}'); + await act(() => user.keyboard('{ArrowDown}')); expect(button2).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -181,7 +181,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); button2.focus(); - await user.tab(); + await act(() => user.tab()); expect(document.body).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); @@ -194,7 +194,7 @@ describe('Toolbar', () => { const { button1, button2, button3 } = getButtons(toolbar); - await user.click(button2); + await act(() => user.click(button2)); expect(button2).toHaveFocus(); expect(button1).toHaveAttribute('tabindex', '-1'); diff --git a/src/editor/Editor.test.tsx b/src/editor/Editor.test.tsx index ddaa9389..7d9a4a1c 100644 --- a/src/editor/Editor.test.tsx +++ b/src/editor/Editor.test.tsx @@ -2,7 +2,7 @@ // Copyright (c) 2021-2023 The Pybricks Authors import { Classes } from '@blueprintjs/core'; -import { cleanup, fireEvent, waitFor } from '@testing-library/react'; +import { act, cleanup, fireEvent, waitFor } from '@testing-library/react'; import * as monaco from 'monaco-editor'; import React from 'react'; import { testRender, uuid } from '../../test'; @@ -41,7 +41,7 @@ describe('Editor', () => { editor: { openFileUuids: [testFile.uuid] }, }); - await user.click(editor.getByRole('tab', { name: 'test.file' })); + await act(() => user.click(editor.getByRole('tab', { name: 'test.file' }))); expect(dispatch).toHaveBeenCalledWith(editorActivateFile(testFile.uuid)); }); @@ -56,7 +56,9 @@ describe('Editor', () => { editor: { openFileUuids: [testFile.uuid] }, }); - await user.type(editor.getByRole('tab', { name: 'test.file' }), key); + await act(() => + user.type(editor.getByRole('tab', { name: 'test.file' }), key), + ); expect(dispatch).toHaveBeenCalledWith( editorActivateFile(testFile.uuid), @@ -72,7 +74,9 @@ describe('Editor', () => { editor: { openFileUuids: [testFile.uuid] }, }); - await user.click(editor.getByRole('button', { name: 'Close test.file' })); + await act(() => + user.click(editor.getByRole('button', { name: 'Close test.file' })), + ); expect(dispatch).toHaveBeenCalledWith(editorCloseFile(testFile.uuid)); }); @@ -85,7 +89,9 @@ describe('Editor', () => { editor: { openFileUuids: [testFile.uuid] }, }); - await user.type(editor.getByRole('tab', { name: 'test.file' }), '{Delete}'); + await act(() => + user.type(editor.getByRole('tab', { name: 'test.file' }), '{Delete}'), + ); expect(dispatch).toHaveBeenCalledWith(editorCloseFile(testFile.uuid)); }); @@ -98,10 +104,12 @@ describe('Editor', () => { editor: { openFileUuids: [testFile.uuid] }, }); - await user.pointer({ - keys: '[MouseMiddle]', - target: editor.getByRole('tab', { name: 'test.file' }), - }); + await act(() => + user.pointer({ + keys: '[MouseMiddle]', + target: editor.getByRole('tab', { name: 'test.file' }), + }), + ); expect(dispatch).toHaveBeenCalledWith(editorCloseFile(testFile.uuid)); }); @@ -145,7 +153,7 @@ describe('Editor', () => { expect(editor.getByRole('menuitem', { name: 'Copy' })).toHaveFocus(), ); - await user.keyboard('{Escape}'); + await act(() => user.keyboard('{Escape}')); await waitFor(() => expect(contextMenu).not.toBeInTheDocument()); @@ -169,10 +177,12 @@ describe('Editor', () => { editor.queryByRole('menu', { name: 'Editor context menu' }), ).toBeNull(); - await user.pointer({ - keys: '[MouseRight]', - target: editor.getByRole('textbox', { name: /^Editor content/ }), - }); + await act(() => + user.pointer({ + keys: '[MouseRight]', + target: editor.getByRole('textbox', { name: /^Editor content/ }), + }), + ); const contextMenu = await editor.findByRole('menu', { name: 'Editor context menu', @@ -190,7 +200,7 @@ describe('Editor', () => { defined(overlay); - await user.click(overlay); + await act(() => user.click(overlay)); await waitFor(() => expect(contextMenu).not.toBeInTheDocument()); diff --git a/src/explorer/Explorer.test.tsx b/src/explorer/Explorer.test.tsx index 4e57422a..9bb05aa1 100644 --- a/src/explorer/Explorer.test.tsx +++ b/src/explorer/Explorer.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup, waitFor } from '@testing-library/react'; +import { act, cleanup, waitFor } from '@testing-library/react'; import React from 'react'; import { testRender, uuid } from '../../test'; import { FileMetadata } from '../fileStorage'; @@ -39,7 +39,7 @@ describe('archive button', () => { const button = explorer.getByTitle('Backup all files'); expect(button).toBeEnabled(); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(explorerArchiveAllFiles()); }); }); @@ -50,7 +50,7 @@ describe('import file button', () => { const button = explorer.getByTitle('Import a file'); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(explorerImportFiles()); }); }); @@ -61,7 +61,7 @@ describe('new file button', () => { const button = explorer.getByTitle('Create a new file'); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(explorerCreateNewFile()); }); }); @@ -73,7 +73,7 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); + await act(() => user.click(treeItem)); expect(dispatch).toHaveBeenCalledWith( explorerUserActivateFile('test.file', uuid(0)), @@ -86,8 +86,8 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); - await user.keyboard('{Enter}'); + await act(() => user.click(treeItem)); + await act(() => user.keyboard('{Enter}')); expect(dispatch).toHaveBeenCalledWith( explorerUserActivateFile('test.file', uuid(0)), @@ -100,14 +100,14 @@ describe('tree item', () => { const [user, explorer, dispatch] = testRender(); const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.hover(treeItem); + await act(() => user.hover(treeItem)); const button = await waitFor(() => explorer.getByRole('button', { name: 'Duplicate test.file' }), ); // user.click() has bad interaction with hover so we use user.pointer() instead - await user.pointer({ keys: '[MouseLeft]', target: button }); + await act(() => user.pointer({ keys: '[MouseLeft]', target: button })); expect(dispatch).toHaveBeenCalledWith(explorerDuplicateFile('test.file')); @@ -121,8 +121,8 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); - await user.keyboard('{Control>}d{/Control}'); + await act(() => user.click(treeItem)); + await act(() => user.keyboard('{Control>}d{/Control}')); expect(dispatch).toHaveBeenCalledWith(explorerDuplicateFile('test.file')); }); @@ -134,14 +134,14 @@ describe('tree item', () => { const [user, explorer, dispatch] = testRender(); const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.hover(treeItem); + await act(() => user.hover(treeItem)); const button = await waitFor(() => explorer.getByRole('button', { name: 'Rename test.file' }), ); // user.click() has bad interaction with hover so we use user.pointer() instead - await user.pointer({ keys: '[MouseLeft]', target: button }); + await act(() => user.pointer({ keys: '[MouseLeft]', target: button })); expect(dispatch).toHaveBeenCalledWith(explorerRenameFile('test.file')); @@ -155,8 +155,8 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); - await user.keyboard('{F2}'); + await act(() => user.click(treeItem)); + await act(() => user.keyboard('{F2}')); expect(dispatch).toHaveBeenCalledWith(explorerRenameFile('test.file')); }); @@ -168,14 +168,14 @@ describe('tree item', () => { const [user, explorer, dispatch] = testRender(); const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.hover(treeItem); + await act(() => user.hover(treeItem)); const button = await waitFor(() => explorer.getByRole('button', { name: 'Export test.file' }), ); // user.click() has bad interaction with hover so we use user.pointer() instead - await user.pointer({ keys: '[MouseLeft]', target: button }); + await act(() => user.pointer({ keys: '[MouseLeft]', target: button })); expect(dispatch).toHaveBeenCalledWith(explorerExportFile('test.file')); @@ -189,8 +189,8 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); - await user.keyboard('{Control>}e{/Control}'); + await act(() => user.click(treeItem)); + await act(() => user.keyboard('{Control>}e{/Control}')); expect(dispatch).toHaveBeenCalledWith(explorerExportFile('test.file')); }); @@ -202,14 +202,14 @@ describe('tree item', () => { const [user, explorer, dispatch] = testRender(); const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.hover(treeItem); + await act(() => user.hover(treeItem)); const button = await waitFor(() => explorer.getByRole('button', { name: 'Delete test.file' }), ); // user.click() has bad interaction with hover so we use user.pointer() instead - await user.pointer({ keys: '[MouseLeft]', target: button }); + await act(() => user.pointer({ keys: '[MouseLeft]', target: button })); expect(dispatch).toHaveBeenCalledWith( explorerDeleteFile('test.file', uuid(0)), @@ -225,8 +225,8 @@ describe('tree item', () => { const treeItem = explorer.getByRole('treeitem', { name: 'test.file' }); - await user.click(treeItem); - await user.keyboard('{Delete}'); + await act(() => user.click(treeItem)); + await act(() => user.keyboard('{Delete}')); expect(dispatch).toHaveBeenCalledWith( explorerDeleteFile('test.file', uuid(0)), diff --git a/src/explorer/alerts/FileInUseAlert.test.tsx b/src/explorer/alerts/FileInUseAlert.test.tsx index 6251b2cc..04ecb1cc 100644 --- a/src/explorer/alerts/FileInUseAlert.test.tsx +++ b/src/explorer/alerts/FileInUseAlert.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { fileInUse } from './FileInUseAlert'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/explorer/alerts/NoFilesToBackup.test.tsx b/src/explorer/alerts/NoFilesToBackup.test.tsx index 6d40367f..814a3238 100644 --- a/src/explorer/alerts/NoFilesToBackup.test.tsx +++ b/src/explorer/alerts/NoFilesToBackup.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noFilesToBackup } from './NoFilesToBackup'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/explorer/alerts/NoPyFiles.test.tsx b/src/explorer/alerts/NoPyFiles.test.tsx index 30c13253..fc806862 100644 --- a/src/explorer/alerts/NoPyFiles.test.tsx +++ b/src/explorer/alerts/NoPyFiles.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noPyFiles } from './NoPyFiles'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/explorer/deleteFileAlert/DeleteFileAlert.test.tsx b/src/explorer/deleteFileAlert/DeleteFileAlert.test.tsx index 2cf0c93e..01b9f84f 100644 --- a/src/explorer/deleteFileAlert/DeleteFileAlert.test.tsx +++ b/src/explorer/deleteFileAlert/DeleteFileAlert.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup, waitFor } from '@testing-library/react'; +import { act, cleanup, waitFor } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import DeleteFileAlert from './DeleteFileAlert'; @@ -17,7 +17,7 @@ describe('accept', () => { explorer: { deleteFileAlert: { fileName: 'test.file', isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Delete' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Delete' }))); expect(dispatch).toHaveBeenCalledWith(deleteFileAlertDidAccept()); }); @@ -29,7 +29,7 @@ describe('accept', () => { await waitFor(() => expect(dialog.getByRole('button', { name: 'Delete' })).toHaveFocus(), ); - await user.keyboard('{Enter}'); + await act(() => user.keyboard('{Enter}')); expect(dispatch).toHaveBeenCalledWith(deleteFileAlertDidAccept()); }); @@ -41,7 +41,7 @@ describe('cancel', () => { explorer: { deleteFileAlert: { fileName: 'test.file', isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Keep' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Keep' }))); expect(dispatch).toHaveBeenCalledWith(deleteFileAlertDidCancel()); }); @@ -55,7 +55,7 @@ describe('cancel', () => { expect(dialog.getByRole('button', { name: 'Delete' })).toHaveFocus(), ); - await user.keyboard('{Escape}'); + await act(() => user.keyboard('{Escape}')); expect(dispatch).toHaveBeenCalledWith(deleteFileAlertDidCancel()); }); diff --git a/src/explorer/duplicateFileDialog/DuplicateFileDialog.test.tsx b/src/explorer/duplicateFileDialog/DuplicateFileDialog.test.tsx index 5969fcdb..3f856457 100644 --- a/src/explorer/duplicateFileDialog/DuplicateFileDialog.test.tsx +++ b/src/explorer/duplicateFileDialog/DuplicateFileDialog.test.tsx @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors import { waitFor } from '@testing-library/dom'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import DuplicateFileDialog from './DuplicateFileDialog'; @@ -20,10 +21,10 @@ describe('duplicate button', () => { // have to type a new file name before Duplicate button is enabled const input = dialog.getByRole('textbox', { name: 'File name' }); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new', { skipClick: true }); + await act(() => user.type(input, 'new', { skipClick: true })); await waitFor(() => expect(button).not.toBeDisabled()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith( duplicateFileDialogDidAccept('source.file', 'new.file'), ); @@ -39,7 +40,7 @@ describe('duplicate button', () => { // have to type a new file name before Duplicate button is enabled const input = dialog.getByRole('textbox', { name: 'File name' }); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new{Enter}', { skipClick: true }); + await act(() => user.type(input, 'new{Enter}', { skipClick: true })); expect(dispatch).toHaveBeenCalledWith( duplicateFileDialogDidAccept('source.file', 'new.file'), @@ -57,7 +58,7 @@ describe('duplicate button', () => { await waitFor(() => expect(button).toBeVisible()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(duplicateFileDialogDidCancel()); }); @@ -72,7 +73,7 @@ describe('duplicate button', () => { expect(dialog.getByRole('textbox', { name: 'File name' })).toHaveFocus(), ); - await user.keyboard('{Escape}'); + await act(() => user.keyboard('{Escape}')); expect(dispatch).toHaveBeenCalledWith(duplicateFileDialogDidCancel()); }); diff --git a/src/explorer/fileNameFormGroup/FileNameFormGroup.test.tsx b/src/explorer/fileNameFormGroup/FileNameFormGroup.test.tsx index 36bdd750..8221333b 100644 --- a/src/explorer/fileNameFormGroup/FileNameFormGroup.test.tsx +++ b/src/explorer/fileNameFormGroup/FileNameFormGroup.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { FileNameValidationResult } from '../../pybricksMicropython/lib'; @@ -40,7 +40,7 @@ it('should fix file names with spaces', async () => { />, ); - await user.click(group.getByRole('button', { name: /fix it/i })); + await act(() => user.click(group.getByRole('button', { name: /fix it/i }))); expect(callback).toHaveBeenCalledWith('test_name'); }); @@ -57,7 +57,7 @@ it('should fix file names with file extension', async () => { />, ); - await user.click(group.getByRole('button', { name: /fix it/i })); + await act(() => user.click(group.getByRole('button', { name: /fix it/i }))); expect(callback).toHaveBeenCalledWith('test'); }); @@ -74,7 +74,7 @@ it('should fix file names with invalid characters', async () => { />, ); - await user.click(group.getByRole('button', { name: /fix it/i })); + await act(() => user.click(group.getByRole('button', { name: /fix it/i }))); expect(callback).toHaveBeenCalledWith('test_name'); }); diff --git a/src/explorer/newFileWizard/NewFileWizard.test.tsx b/src/explorer/newFileWizard/NewFileWizard.test.tsx index c083d731..9351265b 100644 --- a/src/explorer/newFileWizard/NewFileWizard.test.tsx +++ b/src/explorer/newFileWizard/NewFileWizard.test.tsx @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors import { waitFor } from '@testing-library/dom'; -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { Hub } from '../../components/hubPicker'; @@ -22,10 +22,12 @@ describe('accept', () => { const button = dialog.getByLabelText('Create'); // have to type a file name before Create button is enabled - await user.type(dialog.getByRole('textbox', { name: 'File name' }), 'test'); + await act(() => + user.type(dialog.getByRole('textbox', { name: 'File name' }), 'test'), + ); await waitFor(() => expect(button).not.toBeDisabled()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith( newFileWizardDidAccept('test', '.py', Hub.Move), ); @@ -36,9 +38,11 @@ describe('accept', () => { explorer: { newFileWizard: { isOpen: true } }, }); - await user.type( - dialog.getByRole('textbox', { name: 'File name' }), - 'test{Enter}', + await act(() => + user.type( + dialog.getByRole('textbox', { name: 'File name' }), + 'test{Enter}', + ), ); expect(dispatch).toHaveBeenCalledWith( @@ -53,7 +57,7 @@ describe('cancel', () => { explorer: { newFileWizard: { isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Close' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Close' }))); expect(dispatch).toHaveBeenCalledWith(newFileWizardDidCancel()); }); @@ -67,7 +71,7 @@ describe('cancel', () => { expect(dialog.getByRole('textbox', { name: 'File name' })).toHaveFocus(), ); - await user.keyboard('{Escape}'); + await act(() => user.keyboard('{Escape}')); expect(dispatch).toHaveBeenCalledWith(newFileWizardDidCancel()); }); diff --git a/src/explorer/renameFileDialog/RenameFileDialog.test.tsx b/src/explorer/renameFileDialog/RenameFileDialog.test.tsx index 91b600b1..3ae251a4 100644 --- a/src/explorer/renameFileDialog/RenameFileDialog.test.tsx +++ b/src/explorer/renameFileDialog/RenameFileDialog.test.tsx @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors import { waitFor } from '@testing-library/dom'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import RenameFileDialog from './RenameFileDialog'; @@ -18,10 +19,10 @@ describe('rename button', () => { // have to type a new file name before Rename button is enabled const input = dialog.getByLabelText('File name'); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new', { skipClick: true }); + await act(() => user.type(input, 'new', { skipClick: true })); await waitFor(() => expect(button).not.toBeDisabled()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith( renameFileDialogDidAccept('old.file', 'new.file'), ); @@ -35,7 +36,7 @@ describe('rename button', () => { // have to type a new file name before Rename button is enabled const input = dialog.getByLabelText('File name'); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new{Enter}', { skipClick: true }); + await act(() => user.type(input, 'new{Enter}', { skipClick: true })); expect(dispatch).toHaveBeenCalledWith( renameFileDialogDidAccept('old.file', 'new.file'), @@ -51,7 +52,7 @@ describe('rename button', () => { await waitFor(() => expect(button).toBeVisible()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(renameFileDialogDidCancel()); }); }); diff --git a/src/explorer/renameImportDialog/RenameImportDialog.test.tsx b/src/explorer/renameImportDialog/RenameImportDialog.test.tsx index 08712c4e..b8f8b442 100644 --- a/src/explorer/renameImportDialog/RenameImportDialog.test.tsx +++ b/src/explorer/renameImportDialog/RenameImportDialog.test.tsx @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors import { waitFor } from '@testing-library/dom'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import RenameImportDialog from './RenameImportDialog'; @@ -18,10 +19,10 @@ describe('rename button', () => { // have to type a new file name before Rename button is enabled const input = dialog.getByLabelText('File name'); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new', { skipClick: true }); + await act(() => user.type(input, 'new', { skipClick: true })); await waitFor(() => expect(button).not.toBeDisabled()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith( renameImportDialogDidAccept('old.file', 'new.file'), ); @@ -35,7 +36,7 @@ describe('rename button', () => { // have to type a new file name before Rename button is enabled const input = dialog.getByLabelText('File name'); await waitFor(() => expect(input).toHaveFocus()); - await user.type(input, 'new{Enter}', { skipClick: true }); + await act(() => user.type(input, 'new{Enter}', { skipClick: true })); expect(dispatch).toHaveBeenCalledWith( renameImportDialogDidAccept('old.file', 'new.file'), @@ -51,7 +52,7 @@ describe('rename button', () => { await waitFor(() => expect(button).toBeVisible()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(renameImportDialogDidCancel()); }); @@ -64,7 +65,7 @@ describe('rename button', () => { await waitFor(() => expect(button).toBeVisible()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(renameImportDialogDidCancel()); }); }); diff --git a/src/explorer/replaceImportDialog/ReplaceImportDialog.test.tsx b/src/explorer/replaceImportDialog/ReplaceImportDialog.test.tsx index bfadff6a..7282389d 100644 --- a/src/explorer/replaceImportDialog/ReplaceImportDialog.test.tsx +++ b/src/explorer/replaceImportDialog/ReplaceImportDialog.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { waitFor } from '@testing-library/dom'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import RenameImportDialog from './ReplaceImportDialog'; @@ -32,11 +33,11 @@ describe('replace button', () => { const rememberCheckBox = dialog.getByRole('checkbox', { name: /remember/i, }); - await user.click(rememberCheckBox); + await act(() => user.click(rememberCheckBox)); } const button = dialog.getByRole('button', { name: buttonName }); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith( replaceImportDialogDidAccept(action, remember), @@ -53,7 +54,7 @@ describe('replace button', () => { await waitFor(() => expect(button).toBeVisible()); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(replaceImportDialogDidCancel()); }); }); diff --git a/src/firmware/alerts/DfuError.test.tsx b/src/firmware/alerts/DfuError.test.tsx index 791c355f..71e67863 100644 --- a/src/firmware/alerts/DfuError.test.tsx +++ b/src/firmware/alerts/DfuError.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { dfuError } from './DfuError'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); @@ -23,7 +24,7 @@ it('should try again when clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /again/i })); + await act(() => user.click(message.getByRole('button', { name: /again/i }))); expect(callback).toHaveBeenCalledWith('tryAgain'); }); diff --git a/src/firmware/alerts/FlashProgress.test.tsx b/src/firmware/alerts/FlashProgress.test.tsx index 26e64b69..a902dcd5 100644 --- a/src/firmware/alerts/FlashProgress.test.tsx +++ b/src/firmware/alerts/FlashProgress.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { flashProgress } from './FlashProgress'; @@ -16,7 +17,7 @@ it.each(['erase' as ActionType, 'flash' as ActionType])( const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }, diff --git a/src/firmware/alerts/NoDfuHub.test.tsx b/src/firmware/alerts/NoDfuHub.test.tsx index d6bb2ea3..311f8697 100644 --- a/src/firmware/alerts/NoDfuHub.test.tsx +++ b/src/firmware/alerts/NoDfuHub.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { isLinux, isWindows } from '../../utils/os'; @@ -19,7 +20,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); @@ -33,7 +34,7 @@ it('should install windows driver when clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /driver/i })); + await act(() => user.click(message.getByRole('button', { name: /driver/i }))); expect(callback).toHaveBeenCalledWith('installWindowsDriver'); }); diff --git a/src/firmware/alerts/NoDfuInterface.test.tsx b/src/firmware/alerts/NoDfuInterface.test.tsx index 3955bd0e..97f1c15c 100644 --- a/src/firmware/alerts/NoDfuInterface.test.tsx +++ b/src/firmware/alerts/NoDfuInterface.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noDfuInterface } from './NoDfuInterface'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/firmware/alerts/NoWebUsb.test.tsx b/src/firmware/alerts/NoWebUsb.test.tsx index 315137ea..3895f016 100644 --- a/src/firmware/alerts/NoWebUsb.test.tsx +++ b/src/firmware/alerts/NoWebUsb.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { noWebUsb } from './NoWebUsb'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/firmware/alerts/ReleaseButton.test.tsx b/src/firmware/alerts/ReleaseButton.test.tsx index 81cb1f66..7a9426f7 100644 --- a/src/firmware/alerts/ReleaseButton.test.tsx +++ b/src/firmware/alerts/ReleaseButton.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { releaseButton } from './ReleaseButton'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.test.tsx b/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.test.tsx index 15497309..d703d6d9 100644 --- a/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.test.tsx +++ b/src/firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import DfuWindowsDriverInstallDialog from './DfuWindowsDriverInstallDialog'; @@ -19,7 +19,7 @@ it('should dispatch action when the close button is pressed', async () => { firmware: { dfuWindowsDriverInstallDialog: { isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Close' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Close' }))); expect(dispatch).toHaveBeenCalledWith( firmwareDfuWindowsDriverInstallDialogDialogHide(), @@ -32,10 +32,10 @@ it('should navigate when next button is pressed and dispatch action when the don }); for (let i = 1; i < 9; i++) { - await user.click(dialog.getByRole('button', { name: 'Next' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Next' }))); } - await user.click(dialog.getByRole('button', { name: 'Done' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Done' }))); expect(dispatch).toHaveBeenCalledWith( firmwareDfuWindowsDriverInstallDialogDialogHide(), diff --git a/src/firmware/installPybricksDialog/InstallPybricksDialog.test.tsx b/src/firmware/installPybricksDialog/InstallPybricksDialog.test.tsx index fc5083b6..89454ee8 100644 --- a/src/firmware/installPybricksDialog/InstallPybricksDialog.test.tsx +++ b/src/firmware/installPybricksDialog/InstallPybricksDialog.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { InstallPybricksDialog } from './InstallPybricksDialog'; @@ -24,7 +24,7 @@ it('should dispatch when close is clicked', async () => { firmware: { installPybricksDialog: { isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: /close/i })); + await act(() => user.click(dialog.getByRole('button', { name: /close/i }))); expect(dispatch).toHaveBeenCalledWith(firmwareInstallPybricksDialogCancel()); }); @@ -35,17 +35,17 @@ it('should dispatch when done is clicked', async () => { }); // first page - select hub - await user.click(dialog.getByRole('button', { name: /next/i })); + await act(() => user.click(dialog.getByRole('button', { name: /next/i }))); // second page - accept license - await user.click(dialog.getByRole('checkbox', { name: /agree/i })); - await user.click(dialog.getByRole('button', { name: /next/i })); + await act(() => user.click(dialog.getByRole('checkbox', { name: /agree/i }))); + await act(() => user.click(dialog.getByRole('button', { name: /next/i }))); // third page - options - await user.click(dialog.getByRole('button', { name: /next/i })); + await act(() => user.click(dialog.getByRole('button', { name: /next/i }))); // last page - await user.click(dialog.getByRole('button', { name: /install/i })); + await act(() => user.click(dialog.getByRole('button', { name: /install/i }))); expect(dispatch).toHaveBeenCalledWith( firmwareInstallPybricksDialogAccept( diff --git a/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.test.tsx b/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.test.tsx index d0d789f0..b296944d 100644 --- a/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.test.tsx +++ b/src/firmware/restoreOfficialDialog/RestoreOfficialDialog.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { Hub } from '../../components/hubPicker'; @@ -21,7 +21,7 @@ describe('closing', () => { firmware: { restoreOfficialDialog: { isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Close' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Close' }))); expect(dispatch).toHaveBeenCalledWith(firmwareRestoreOfficialDialogHide()); }); @@ -31,8 +31,8 @@ describe('closing', () => { firmware: { restoreOfficialDialog: { isOpen: true } }, }); - await user.click(dialog.getByRole('button', { name: 'Next' })); - await user.click(dialog.getByRole('button', { name: 'Done' })); + await act(() => user.click(dialog.getByRole('button', { name: 'Next' }))); + await act(() => user.click(dialog.getByRole('button', { name: 'Done' }))); expect(dispatch).toHaveBeenCalledWith(firmwareRestoreOfficialDialogHide()); }); @@ -50,9 +50,11 @@ describe('flashing', () => { firmware: { restoreOfficialDialog: { isOpen: true } }, }); - await user.click(dialog.getByRole('radio', { name: hubName })); - await user.click(dialog.getByRole('button', { name: 'Next' })); - await user.click(dialog.getByRole('button', { name: 'Restore' })); + await act(() => user.click(dialog.getByRole('radio', { name: hubName }))); + await act(() => user.click(dialog.getByRole('button', { name: 'Next' }))); + await act(() => + user.click(dialog.getByRole('button', { name: 'Restore' })), + ); expect(dispatch).toHaveBeenCalledWith(firmwareRestoreOfficialDfu(hub)); }, diff --git a/src/hub/alerts/UserProgramSize.test.tsx b/src/hub/alerts/UserProgramSize.test.tsx index d435cdd7..edaa4f2e 100644 --- a/src/hub/alerts/UserProgramSize.test.tsx +++ b/src/hub/alerts/UserProgramSize.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { userProgramSize } from './UserProgramSize'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/licenses/LicenseDialog.test.tsx b/src/licenses/LicenseDialog.test.tsx index 02bec541..7fafee58 100644 --- a/src/licenses/LicenseDialog.test.tsx +++ b/src/licenses/LicenseDialog.test.tsx @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors import { Classes } from '@blueprintjs/core'; -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import LicenseDialog from './LicenseDialog'; @@ -50,7 +50,7 @@ describe('LicenseDialog', () => { expect(dialog.queryByText('Joe Somebody')).toBeNull(); // then when you click on a license name, the license is shown - await user.click(treeNode); + await act(() => user.click(treeNode)); expect(dialog.getByText('Joe Somebody')).toBeDefined(); }); }); diff --git a/src/mpy/alerts/CompileError.test.tsx b/src/mpy/alerts/CompileError.test.tsx index e4adb03f..eea8dd3c 100644 --- a/src/mpy/alerts/CompileError.test.tsx +++ b/src/mpy/alerts/CompileError.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender, uuid } from '../../../test'; import { editorGoto } from '../../editor/actions'; @@ -18,7 +19,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); @@ -33,7 +34,7 @@ it('should dispatch go to error when clicked', async () => { const [user, message, dispatch] = testRender(); - await user.click(message.getByRole('button', { name: /go to/i })); + await act(() => user.click(message.getByRole('button', { name: /go to/i }))); expect(dispatch).toHaveBeenCalledWith(editorGoto(uuid(0), 1)); }); diff --git a/src/settings/Settings.test.tsx b/src/settings/Settings.test.tsx index 22b4c62c..a50a27aa 100644 --- a/src/settings/Settings.test.tsx +++ b/src/settings/Settings.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup, getByLabelText, waitFor } from '@testing-library/react'; +import { act, cleanup, getByLabelText, waitFor } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import { firmwareInstallPybricks } from '../firmware/actions'; @@ -23,11 +23,11 @@ describe('darkMode setting switch', () => { expect(darkMode).not.toBeChecked(); expect(localStorage.getItem('usehooks-ts-ternary-dark-mode')).toBe(null); - await user.click(darkMode); + await act(() => user.click(darkMode)); expect(darkMode).toBeChecked(); expect(localStorage.getItem('usehooks-ts-ternary-dark-mode')).toBe('"dark"'); - await user.click(darkMode); + await act(() => user.click(darkMode)); expect(darkMode).not.toBeChecked(); expect(localStorage.getItem('usehooks-ts-ternary-dark-mode')).toBe('"light"'); }); @@ -40,7 +40,7 @@ describe('firmware', () => { const button = settings.getByRole('button', { name: 'Install Pybricks Firmware', }); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(firmwareInstallPybricks()); }); @@ -51,7 +51,7 @@ describe('firmware', () => { const button = settings.getByRole('button', { name: 'Restore Official LEGO® Firmware', }); - await user.click(button); + await act(() => user.click(button)); expect(dispatch).toHaveBeenCalledWith(firmwareRestoreOfficialDialogShow()); }); @@ -65,13 +65,13 @@ describe('about dialog', () => { expect(settings.queryByRole('dialog', { name: `About ${appName}` })).toBeNull(); - await user.click(settings.getByText('About')); + await act(() => user.click(settings.getByText('About'))); const dialog = settings.getByRole('dialog', { name: `About ${appName}` }); expect(dialog).toBeVisible(); - await user.click(getByLabelText(dialog, 'Close')); + await act(() => user.click(getByLabelText(dialog, 'Close'))); await waitFor(() => expect(dialog).not.toBeVisible()); }); diff --git a/src/sponsor/alerts/AddressCopied.test.tsx b/src/sponsor/alerts/AddressCopied.test.tsx index d897726e..6674726a 100644 --- a/src/sponsor/alerts/AddressCopied.test.tsx +++ b/src/sponsor/alerts/AddressCopied.test.tsx @@ -2,6 +2,7 @@ // Copyright (c) 2022-2023 The Pybricks Authors import { Toast } from '@blueprintjs/core'; +import { act } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../test'; import { addressCopied } from './AddressCopied'; @@ -12,7 +13,7 @@ it('should dismiss when close is clicked', async () => { const [user, message] = testRender(); - await user.click(message.getByRole('button', { name: /close/i })); + await act(() => user.click(message.getByRole('button', { name: /close/i }))); expect(callback).toHaveBeenCalledWith('dismiss'); }); diff --git a/src/status-bar/StatusBar.test.tsx b/src/status-bar/StatusBar.test.tsx index 4f68adec..0ba74439 100644 --- a/src/status-bar/StatusBar.test.tsx +++ b/src/status-bar/StatusBar.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2021-2022 The Pybricks Authors +// Copyright (c) 2021-2023 The Pybricks Authors -import { waitFor } from '@testing-library/react'; +import { act, waitFor } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../test'; import { BleConnectionState } from '../ble/reducers'; @@ -21,7 +21,7 @@ it('should show popover when hub name is clicked', async () => { }, }); - await user.click(statusBar.getByText(testHubName)); + await act(() => user.click(statusBar.getByText(testHubName))); await waitFor(() => statusBar.getByText('Connected to:')); }); @@ -40,7 +40,7 @@ it('should show popover when battery is clicked', async () => { }, }); - await user.click(statusBar.getByTitle('Battery')); + await act(() => user.click(statusBar.getByTitle('Battery'))); await waitFor(() => statusBar.getByText('Battery level is OK.')); }); diff --git a/src/toolbar/buttons/bluetooth/BluetoothButton.test.tsx b/src/toolbar/buttons/bluetooth/BluetoothButton.test.tsx index e1cfb830..36644bd6 100644 --- a/src/toolbar/buttons/bluetooth/BluetoothButton.test.tsx +++ b/src/toolbar/buttons/bluetooth/BluetoothButton.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../../test'; import { toggleBluetooth } from '../../../ble/actions'; @@ -16,7 +16,7 @@ it('should dispatch action when clicked', async () => { , ); - await user.click(button.getByRole('button', { name: 'Bluetooth' })); + await act(() => user.click(button.getByRole('button', { name: 'Bluetooth' }))); expect(dispatch).toHaveBeenCalledWith(toggleBluetooth()); }); diff --git a/src/toolbar/buttons/repl/ReplButton.test.tsx b/src/toolbar/buttons/repl/ReplButton.test.tsx index 00b3900d..9ca4cf65 100644 --- a/src/toolbar/buttons/repl/ReplButton.test.tsx +++ b/src/toolbar/buttons/repl/ReplButton.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../../test'; import { repl } from '../../../hub/actions'; @@ -17,7 +17,7 @@ it('should dispatch action when clicked', async () => { hub: { hasRepl: true, runtime: HubRuntimeState.Idle }, }); - await user.click(button.getByRole('button', { name: 'REPL' })); + await act(() => user.click(button.getByRole('button', { name: 'REPL' }))); expect(dispatch).toHaveBeenCalledWith(repl(false)); }); diff --git a/src/toolbar/buttons/run/RunButton.test.tsx b/src/toolbar/buttons/run/RunButton.test.tsx index cb9af47f..6e2277c4 100644 --- a/src/toolbar/buttons/run/RunButton.test.tsx +++ b/src/toolbar/buttons/run/RunButton.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender, uuid } from '../../../../test'; import { FileFormat } from '../../../ble-pybricks-service/protocol'; @@ -22,7 +22,7 @@ it('should dispatch action when clicked', async () => { }, }); - await user.click(button.getByRole('button', { name: 'Run' })); + await act(() => user.click(button.getByRole('button', { name: 'Run' }))); expect(dispatch).toHaveBeenCalledWith(downloadAndRun(FileFormat.MultiMpy6, false)); }); diff --git a/src/toolbar/buttons/stop/StopButton.test.tsx b/src/toolbar/buttons/stop/StopButton.test.tsx index 8cef9e90..3f1bb60f 100644 --- a/src/toolbar/buttons/stop/StopButton.test.tsx +++ b/src/toolbar/buttons/stop/StopButton.test.tsx @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT -// Copyright (c) 2022 The Pybricks Authors +// Copyright (c) 2022-2023 The Pybricks Authors -import { cleanup } from '@testing-library/react'; +import { act, cleanup } from '@testing-library/react'; import React from 'react'; import { testRender } from '../../../../test'; import { stop } from '../../../hub/actions'; @@ -17,7 +17,7 @@ it('should dispatch action when clicked', async () => { hub: { runtime: HubRuntimeState.Running }, }); - await user.click(button.getByRole('button', { name: 'Stop' })); + await act(() => user.click(button.getByRole('button', { name: 'Stop' }))); expect(dispatch).toHaveBeenCalledWith(stop()); });