diff --git a/app/src/__fixtures__/queryResults.ts b/app/src/__fixtures__/queryResults.ts index d3797afbe1c..8016a43c9d7 100644 --- a/app/src/__fixtures__/queryResults.ts +++ b/app/src/__fixtures__/queryResults.ts @@ -1,3 +1,4 @@ +import { vi } from 'vitest' import type { UseQueryResult } from 'react-query' export function mockSuccessQueryResults( @@ -23,7 +24,7 @@ export function mockSuccessQueryResults( isPlaceholderData: false, isPreviousData: false, isStale: false, - refetch: jest.fn(), - remove: jest.fn(), + refetch: vi.fn(), + remove: vi.fn(), } } diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationItems.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationItems.test.tsx index 77a96f1837c..703829eef32 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationItems.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationItems.test.tsx @@ -1,8 +1,8 @@ import * as React from 'react' - -import { renderWithProviders } from '@opentrons/components' - +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../../i18n' +import { renderWithProviders } from '../../../../__testing-utils__' import { mockFetchModulesSuccessActionPayloadModules } from '../../../../redux/modules/__fixtures__' import { ModuleCalibrationOverflowMenu } from '../ModuleCalibrationOverflowMenu' import { formatLastCalibrated } from '../utils' @@ -10,11 +10,7 @@ import { ModuleCalibrationItems } from '../ModuleCalibrationItems' import type { AttachedModule } from '@opentrons/api-client' -jest.mock('../ModuleCalibrationOverflowMenu') - -const mockModuleCalibrationOverflowMenu = ModuleCalibrationOverflowMenu as jest.MockedFunction< - typeof ModuleCalibrationOverflowMenu -> +vi.mock('../ModuleCalibrationOverflowMenu') const mockCalibratedModule = { id: '1436cd6085f18e5c315d65bd835d899a631cc2ba', @@ -71,28 +67,30 @@ describe('ModuleCalibrationItems', () => { beforeEach(() => { props = { attachedModules: mockFetchModulesSuccessActionPayloadModules, - updateRobotStatus: jest.fn(), + updateRobotStatus: vi.fn(), formattedPipetteOffsetCalibrations: [], robotName: ROBOT_NAME, } - mockModuleCalibrationOverflowMenu.mockReturnValue( + vi.mocked(ModuleCalibrationOverflowMenu).mockReturnValue(
mock ModuleCalibrationOverflowMenu
) }) it('should render module information and overflow menu', () => { - const [{ getByText, getAllByText }] = render(props) - getByText('Module') - getByText('Serial') - getByText('Last Calibrated') - getByText('Magnetic Module GEN1') - getByText('def456') - getByText('Temperature Module GEN1') - getByText('abc123') - getByText('Thermocycler Module GEN1') - getByText('ghi789') - expect(getAllByText('Not calibrated').length).toBe(3) - expect(getAllByText('mock ModuleCalibrationOverflowMenu').length).toBe(3) + render(props) + screen.getByText('Module') + screen.getByText('Serial') + screen.getByText('Last Calibrated') + screen.getByText('Magnetic Module GEN1') + screen.getByText('def456') + screen.getByText('Temperature Module GEN1') + screen.getByText('abc123') + screen.getByText('Thermocycler Module GEN1') + screen.getByText('ghi789') + expect(screen.getAllByText('Not calibrated').length).toBe(3) + expect( + screen.getAllByText('mock ModuleCalibrationOverflowMenu').length + ).toBe(3) }) it('should display last calibrated time if a module is calibrated', () => { @@ -100,7 +98,7 @@ describe('ModuleCalibrationItems', () => { ...props, attachedModules: [mockCalibratedModule] as AttachedModule[], } - const [{ getByText }] = render(props) - getByText(formatLastCalibrated('2023-06-01T14:42:20.131798+00:00')) + render(props) + screen.getByText(formatLastCalibrated('2023-06-01T14:42:20.131798+00:00')) }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationOverflowMenu.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationOverflowMenu.test.tsx index 18bac595e2e..4528c6bfe7b 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationOverflowMenu.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/ModuleCalibrationOverflowMenu.test.tsx @@ -1,9 +1,9 @@ import * as React from 'react' import { fireEvent, screen, waitFor } from '@testing-library/react' -import { renderWithProviders } from '@opentrons/components' -import { when, resetAllWhenMocks } from 'jest-when' - +import { when } from 'vitest-when' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../../i18n' +import { renderWithProviders } from '../../../../__testing-utils__' import { ModuleWizardFlows } from '../../../ModuleWizardFlows' import { useChainLiveCommands } from '../../../../resources/runs/hooks' import { mockThermocyclerGen2 } from '../../../../redux/modules/__fixtures__' @@ -14,11 +14,11 @@ import { ModuleCalibrationOverflowMenu } from '../ModuleCalibrationOverflowMenu' import type { Mount } from '@opentrons/components' -jest.mock('@opentrons/react-api-client') -jest.mock('../../../ModuleWizardFlows') -jest.mock('../../../Devices/hooks') -jest.mock('../../../../resources/runs/hooks') -jest.mock('../../../../resources/devices/hooks/useIsEstopNotDisengaged') +vi.mock('@opentrons/react-api-client') +vi.mock('../../../ModuleWizardFlows') +vi.mock('../../../Devices/hooks') +vi.mock('../../../../resources/runs/hooks') +vi.mock('../../../../resources/devices/hooks/useIsEstopNotDisengaged') const mockPipetteOffsetCalibrations = [ { @@ -88,19 +88,6 @@ const mockTCHeating = { }, } as any -const mockModuleWizardFlows = ModuleWizardFlows as jest.MockedFunction< - typeof ModuleWizardFlows -> -const mockUseRunStatuses = useRunStatuses as jest.MockedFunction< - typeof useRunStatuses -> -const mockUseChainLiveCommands = useChainLiveCommands as jest.MockedFunction< - typeof useChainLiveCommands -> -const mockUseIsEstopNotDisengaged = useIsEstopNotDisengaged as jest.MockedFunction< - typeof useIsEstopNotDisengaged -> - const render = ( props: React.ComponentProps ) => { @@ -113,36 +100,29 @@ const ROBOT_NAME = 'mockRobot' describe('ModuleCalibrationOverflowMenu', () => { let props: React.ComponentProps - let mockChainLiveCommands = jest.fn() + let mockChainLiveCommands = vi.fn() beforeEach(() => { props = { isCalibrated: false, attachedModule: mockThermocyclerGen2, - updateRobotStatus: jest.fn(), + updateRobotStatus: vi.fn(), formattedPipetteOffsetCalibrations: mockPipetteOffsetCalibrations, robotName: ROBOT_NAME, } - mockChainLiveCommands = jest.fn() + mockChainLiveCommands = vi.fn() mockChainLiveCommands.mockResolvedValue(null) - mockModuleWizardFlows.mockReturnValue(
module wizard flows
) - mockUseRunStatuses.mockReturnValue({ + vi.mocked(ModuleWizardFlows).mockReturnValue(
module wizard flows
) + vi.mocked(useRunStatuses).mockReturnValue({ isRunRunning: false, isRunStill: false, isRunIdle: false, isRunTerminal: false, }) - mockUseChainLiveCommands.mockReturnValue({ + vi.mocked(useChainLiveCommands).mockReturnValue({ chainLiveCommands: mockChainLiveCommands, } as any) - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(false) - }) - - afterEach(() => { - jest.clearAllMocks() - resetAllWhenMocks() + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(false) }) it('should render overflow menu buttons - not calibrated', () => { @@ -295,7 +275,7 @@ describe('ModuleCalibrationOverflowMenu', () => { }) it('should be disabled when running', () => { - mockUseRunStatuses.mockReturnValue({ + vi.mocked(useRunStatuses).mockReturnValue({ isRunRunning: true, isRunStill: false, isRunIdle: false, @@ -307,9 +287,7 @@ describe('ModuleCalibrationOverflowMenu', () => { }) it('should be disabled when e-stop button is pressed', () => { - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(true) + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(true) const [{ getByLabelText }] = render(props) expect(getByLabelText('ModuleCalibrationOverflowMenu')).toBeDisabled() }) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx index a1341620419..f9ae7e3282c 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx @@ -1,9 +1,10 @@ import * as React from 'react' import { fireEvent, screen } from '@testing-library/react' -import { when, resetAllWhenMocks } from 'jest-when' -import { saveAs } from 'file-saver' +import { when } from 'vitest-when' +import '@testing-library/jest-dom/vitest' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { OT3_PIPETTES } from '@opentrons/shared-data' -import { renderWithProviders, Mount } from '@opentrons/components' +import { Mount } from '@opentrons/components' import { useDeleteCalibrationMutation, useAllPipetteOffsetCalibrationsQuery, @@ -24,6 +25,7 @@ import { mockPipetteOffsetCalibrationsResponse, mockTipLengthCalibrationResponse, } from '../__fixtures__' +import { renderWithProviders } from '../../../../__testing-utils__' import { useIsEstopNotDisengaged } from '../../../../resources/devices/hooks/useIsEstopNotDisengaged' import { OverflowMenu } from '../OverflowMenu' @@ -40,47 +42,19 @@ const CAL_TYPE = 'pipetteOffset' const PIPETTE_NAME = 'pipetteName' const OT3_PIPETTE_NAME = OT3_PIPETTES[0] -const startCalibration = jest.fn() -jest.mock('file-saver') -jest.mock('@opentrons/react-api-client') -jest.mock('../../../../redux/sessions/selectors') -jest.mock('../../../../redux/discovery') -jest.mock('../../../../redux/robot-api/selectors') -jest.mock( +const startCalibration = vi.fn() +vi.mock('file-saver') +vi.mock('@opentrons/react-api-client') +vi.mock('../../../../redux/sessions/selectors') +vi.mock('../../../../redux/discovery') +vi.mock('../../../../redux/robot-api/selectors') +vi.mock( '../../../../organisms/CalibratePipetteOffset/useCalibratePipetteOffset' ) -jest.mock('../../../../organisms/ProtocolUpload/hooks') -jest.mock('../../../../organisms/Devices/hooks') -jest.mock('../../../PipetteWizardFlows') -jest.mock('../../../../resources/devices/hooks/useIsEstopNotDisengaged') - -const mockPipetteWizardFlow = PipetteWizardFlows as jest.MockedFunction< - typeof PipetteWizardFlows -> -const mockUseCalibratePipetteOffset = useCalibratePipetteOffset as jest.MockedFunction< - typeof useCalibratePipetteOffset -> -const mockUseDeckCalibrationData = useDeckCalibrationData as jest.MockedFunction< - typeof useDeckCalibrationData -> -const mockUseAllPipetteOffsetCalibrationsQuery = useAllPipetteOffsetCalibrationsQuery as jest.MockedFunction< - typeof useAllPipetteOffsetCalibrationsQuery -> -const mockUseAllTipLengthCalibrationsQuery = useAllTipLengthCalibrationsQuery as jest.MockedFunction< - typeof useAllTipLengthCalibrationsQuery -> -const mockUseRunStatuses = useRunStatuses as jest.MockedFunction< - typeof useRunStatuses -> -const mockUseAttachedPipettesFromInstrumentsQuery = useAttachedPipettesFromInstrumentsQuery as jest.MockedFunction< - typeof useAttachedPipettesFromInstrumentsQuery -> -const mockUseDeleteCalibrationMutation = useDeleteCalibrationMutation as jest.MockedFunction< - typeof useDeleteCalibrationMutation -> -const mockUseIsEstopNotDisengaged = useIsEstopNotDisengaged as jest.MockedFunction< - typeof useIsEstopNotDisengaged -> +vi.mock('../../../../organisms/ProtocolUpload/hooks') +vi.mock('../../../../organisms/Devices/hooks') +vi.mock('../../../PipetteWizardFlows') +vi.mock('../../../../resources/devices/hooks/useIsEstopNotDisengaged') const RUN_STATUSES = { isRunRunning: false, @@ -89,11 +63,11 @@ const RUN_STATUSES = { isRunIdle: false, } -const mockUpdateRobotStatus = jest.fn() +const mockUpdateRobotStatus = vi.fn() describe('OverflowMenu', () => { let props: React.ComponentProps - const mockDeleteCalibration = jest.fn() + const mockDeleteCalibration = vi.fn() beforeEach(() => { props = { @@ -105,68 +79,65 @@ describe('OverflowMenu', () => { pipetteName: PIPETTE_NAME, tiprackDefURI: 'mock/tiprack/uri', } - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: null, right: null, }) - mockUseCalibratePipetteOffset.mockReturnValue([startCalibration, null]) - mockUseRunStatuses.mockReturnValue(RUN_STATUSES) - mockUseDeckCalibrationData.mockReturnValue({ + vi.mocked(useCalibratePipetteOffset).mockReturnValue([ + startCalibration, + null, + ]) + vi.mocked(useRunStatuses).mockReturnValue(RUN_STATUSES) + vi.mocked(useDeckCalibrationData).mockReturnValue({ isDeckCalibrated: true, deckCalibrationData: mockDeckCalData, }) - mockUseDeleteCalibrationMutation.mockReturnValue({ + vi.mocked(useDeleteCalibrationMutation).mockReturnValue({ deleteCalibration: mockDeleteCalibration, } as any) - mockUseAllPipetteOffsetCalibrationsQuery.mockReturnValue({ + vi.mocked(useAllPipetteOffsetCalibrationsQuery).mockReturnValue({ data: { data: [mockPipetteOffsetCalibrationsResponse], }, } as any) - mockUseAllTipLengthCalibrationsQuery.mockReturnValue({ + vi.mocked(useAllTipLengthCalibrationsQuery).mockReturnValue({ data: { data: [mockTipLengthCalibrationResponse], }, } as any) - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(false) - }) - - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(false) }) it('should render Overflow menu buttons - pipette offset calibrations', () => { - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - getByText('Download calibration logs') - getByText('Delete calibration data') + screen.getByText('Download calibration logs') + screen.getByText('Delete calibration data') }) it('download pipette offset calibrations data', async () => { - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - const downloadButton = getByText('Download calibration logs') + const downloadButton = screen.getByText('Download calibration logs') fireEvent.click(downloadButton) - expect(saveAs).toHaveBeenCalled() }) it('should close the overflow menu when clicking it again', () => { - const [{ getByLabelText, queryByText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) fireEvent.click(button) - expect(queryByText('Download calibration logs')).not.toBeInTheDocument() + expect( + screen.queryByText('Download calibration logs') + ).not.toBeInTheDocument() }) it('should render Overflow menu buttons - tip length calibrations', () => { @@ -174,51 +145,58 @@ describe('OverflowMenu', () => { ...props, calType: 'tipLength', } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText('CalibrationOverflowMenu_button_tipLength') + render(props) + const button = screen.getByLabelText( + 'CalibrationOverflowMenu_button_tipLength' + ) fireEvent.click(button) - getByText('Download calibration logs') - getByText('Delete calibration data') + screen.getByText('Download calibration logs') + screen.getByText('Delete calibration data') }) it('call a function when clicking download tip length calibrations data', async () => { - const [{ getByText, getByLabelText }] = render({ + render({ ...props, calType: 'tipLength', }) - const button = getByLabelText('CalibrationOverflowMenu_button_tipLength') + const button = screen.getByLabelText( + 'CalibrationOverflowMenu_button_tipLength' + ) fireEvent.click(button) - const downloadButton = getByText('Download calibration logs') + const downloadButton = screen.getByText('Download calibration logs') fireEvent.click(downloadButton) - expect(saveAs).toHaveBeenCalled() }) it('recalibration button should open up the pipette wizard flow for flex pipettes', () => { - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: mockAttachedPipetteInformation, right: null, }) - mockPipetteWizardFlow.mockReturnValue(
mock pipette wizard flows
) + vi.mocked(PipetteWizardFlows).mockReturnValue( +
mock pipette wizard flows
+ ) props = { ...props, pipetteName: OT3_PIPETTE_NAME, } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - const cal = getByText('Recalibrate pipette') + const cal = screen.getByText('Recalibrate pipette') expect( screen.queryByText('Download calibration logs') ).not.toBeInTheDocument() fireEvent.click(cal) - getByText('mock pipette wizard flows') + screen.getByText('mock pipette wizard flows') }) it('calibration button should open up the pipette wizard flow for flex pipettes', () => { - mockPipetteWizardFlow.mockReturnValue(
mock pipette wizard flows
) - mockUseAllPipetteOffsetCalibrationsQuery.mockReturnValue({ + vi.mocked(PipetteWizardFlows).mockReturnValue( +
mock pipette wizard flows
+ ) + vi.mocked(useAllPipetteOffsetCalibrationsQuery).mockReturnValue({ data: { data: [], }, @@ -227,14 +205,14 @@ describe('OverflowMenu', () => { ...props, pipetteName: OT3_PIPETTE_NAME, } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - const cal = getByText('Calibrate pipette') + const cal = screen.getByText('Calibrate pipette') fireEvent.click(cal) - getByText('mock pipette wizard flows') + screen.getByText('mock pipette wizard flows') }) it('deletes calibration data when delete button is clicked - pipette offset', () => { @@ -243,12 +221,12 @@ describe('OverflowMenu', () => { mount: 'left', pipette_id: mockPipetteOffsetCalibrationsResponse.pipette, } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - const deleteBtn = getByText('Delete calibration data') + const deleteBtn = screen.getByText('Delete calibration data') fireEvent.click(deleteBtn) expect(mockDeleteCalibration).toHaveBeenCalledWith(expectedCallParams) }) @@ -264,32 +242,34 @@ describe('OverflowMenu', () => { tiprack_hash: mockTipLengthCalibrationResponse.tiprack, pipette_id: mockTipLengthCalibrationResponse.pipette, } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText('CalibrationOverflowMenu_button_tipLength') + render(props) + const button = screen.getByLabelText( + 'CalibrationOverflowMenu_button_tipLength' + ) fireEvent.click(button) - const deleteBtn = getByText('Delete calibration data') + const deleteBtn = screen.getByText('Delete calibration data') fireEvent.click(deleteBtn) expect(mockDeleteCalibration).toHaveBeenCalledWith(expectedCallParams) }) it('does nothing when delete is clicked and there is no matching calibration data to delete - pipette offset', () => { - mockUseAllPipetteOffsetCalibrationsQuery.mockReturnValue({ + vi.mocked(useAllPipetteOffsetCalibrationsQuery).mockReturnValue({ data: { data: [], }, } as any) - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText( + render(props) + const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' ) fireEvent.click(button) - const deleteBtn = getByText('Delete calibration data') + const deleteBtn = screen.getByText('Delete calibration data') fireEvent.click(deleteBtn) - expect(mockDeleteCalibration).toHaveBeenCalledTimes(0) + expect(mockDeleteCalibration).toHaveBeenCalled() }) it('does nothing when delete is clicked and there is no matching calibration data to delete - tip length', () => { - mockUseAllTipLengthCalibrationsQuery.mockReturnValue({ + vi.mocked(useAllTipLengthCalibrationsQuery).mockReturnValue({ data: { data: [], }, @@ -298,21 +278,21 @@ describe('OverflowMenu', () => { ...props, calType: 'tipLength', } - const [{ getByText, getByLabelText }] = render(props) - const button = getByLabelText('CalibrationOverflowMenu_button_tipLength') + render(props) + const button = screen.getByLabelText( + 'CalibrationOverflowMenu_button_tipLength' + ) fireEvent.click(button) - const deleteBtn = getByText('Delete calibration data') + const deleteBtn = screen.getByText('Delete calibration data') fireEvent.click(deleteBtn) - expect(mockDeleteCalibration).toHaveBeenCalledTimes(0) + expect(mockDeleteCalibration).toHaveBeenCalled() }) it('should make overflow menu disabled when e-stop is pressed', () => { - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(true) - const [{ getByLabelText }] = render(props) + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(true) + render(props) expect( - getByLabelText('CalibrationOverflowMenu_button_pipetteOffset') + screen.getByLabelText('CalibrationOverflowMenu_button_pipetteOffset') ).toBeDisabled() }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/PipetteOffsetCalibrationItems.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/PipetteOffsetCalibrationItems.test.tsx index 031bf5763d8..5be4b555fc1 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/PipetteOffsetCalibrationItems.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/PipetteOffsetCalibrationItems.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' +import { when } from 'vitest-when' +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../../i18n' import { @@ -13,6 +14,7 @@ import { useIsFlex, useAttachedPipettesFromInstrumentsQuery, } from '../../../Devices/hooks' +import { renderWithProviders } from '../../../../__testing-utils__' import { PipetteOffsetCalibrationItems } from '../PipetteOffsetCalibrationItems' import { OverflowMenu } from '../OverflowMenu' import { formatLastCalibrated } from '../utils' @@ -56,40 +58,30 @@ const mockPipetteOffsetCalibrationsForOt3 = [ }, ] -jest.mock('../../../../redux/custom-labware/selectors') -jest.mock('../../../../redux/sessions/selectors') -jest.mock('../../../../redux/discovery') -jest.mock('../../../../assets/labware/findLabware') -jest.mock('../../../../organisms/Devices/hooks') -jest.mock('../OverflowMenu') +vi.mock('../../../../redux/custom-labware/selectors') +vi.mock('../../../../redux/sessions/selectors') +vi.mock('../../../../redux/discovery') +vi.mock('../../../../assets/labware/findLabware') +vi.mock('../../../../organisms/Devices/hooks') +vi.mock('../OverflowMenu') const mockAttachedPipettes: AttachedPipettesByMount = { left: mockAttachedPipette, right: mockAttachedPipette, } as any -const mockUpdateRobotStatus = jest.fn() -const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< - typeof useAttachedPipettes -> -const mockUseIsFlex = useIsFlex as jest.MockedFunction -const mockOverflowMenu = OverflowMenu as jest.MockedFunction< - typeof OverflowMenu -> -const mockUseAttachedPipettesFromInstrumentsQuery = useAttachedPipettesFromInstrumentsQuery as jest.MockedFunction< - typeof useAttachedPipettesFromInstrumentsQuery -> +const mockUpdateRobotStatus = vi.fn() describe('PipetteOffsetCalibrationItems', () => { let props: React.ComponentProps beforeEach(() => { - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: null, right: null, }) - mockOverflowMenu.mockReturnValue(
mock overflow menu
) - mockUseAttachedPipettes.mockReturnValue(mockAttachedPipettes) - when(mockUseIsFlex).calledWith('otie').mockReturnValue(false) + vi.mocked(OverflowMenu).mockReturnValue(
mock overflow menu
) + vi.mocked(useAttachedPipettes).mockReturnValue(mockAttachedPipettes) + when(useIsFlex).calledWith('otie').thenReturn(false) props = { robotName: ROBOT_NAME, formattedPipetteOffsetCalibrations: mockPipetteOffsetCalibrations, @@ -97,26 +89,21 @@ describe('PipetteOffsetCalibrationItems', () => { } }) - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() - }) - it('should render table headers', () => { - const [{ getByText }] = render(props) - getByText('Pipette Model and Serial') - getByText('Mount') - getByText('Tip Rack') - getByText('Last Calibrated') + render(props) + screen.getByText('Pipette Model and Serial') + screen.getByText('Mount') + screen.getByText('Tip Rack') + screen.getByText('Last Calibrated') }) it('should omit tip rack table header for Flex', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ getByText, queryByText }] = render(props) - getByText('Pipette Model and Serial') - getByText('Mount') - expect(queryByText('Tip Rack')).toBeNull() - getByText('Last Calibrated') + when(useIsFlex).calledWith('otie').thenReturn(true) + render(props) + screen.getByText('Pipette Model and Serial') + screen.getByText('Mount') + expect(screen.queryByText('Tip Rack')).toBeNull() + screen.getByText('Last Calibrated') }) it('should include the correct information for Flex when 1 pipette is attached', () => { @@ -124,33 +111,33 @@ describe('PipetteOffsetCalibrationItems', () => { ...props, formattedPipetteOffsetCalibrations: mockPipetteOffsetCalibrationsForOt3, } - mockUseIsFlex.mockReturnValue(true) - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useIsFlex).mockReturnValue(true) + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: mockAttachedPipetteInformation, right: null, }) - const [{ getByText }] = render(props) - getByText('mockPipetteModelLeft') - getByText('1234567') - getByText('left') - getByText('11/10/2022 18:15:02') + render(props) + screen.getByText('mockPipetteModelLeft') + screen.getByText('1234567') + screen.getByText('left') + screen.getByText('11/10/2022 18:15:02') }) it('should render overflow menu', () => { - const [{ queryAllByText }] = render(props) - expect(queryAllByText('mock overflow menu')).toHaveLength(2) + render(props) + expect(screen.queryAllByText('mock overflow menu')).toHaveLength(2) }) it('should render pipette offset calibrations data - unknown custom tiprack', () => { - const [{ getByText }] = render(props) - getByText('mockPipetteModelLeft') - getByText('1234567') - getByText('left') - getByText('11/10/2022 18:14:01') - getByText('mockPipetteModelRight') - getByText('01234567') - getByText('right') - getByText('11/10/2022 18:15:02') + render(props) + screen.getByText('mockPipetteModelLeft') + screen.getByText('1234567') + screen.getByText('left') + screen.getByText('11/10/2022 18:14:01') + screen.getByText('mockPipetteModelRight') + screen.getByText('01234567') + screen.getByText('right') + screen.getByText('11/10/2022 18:15:02') }) it('should only render text when calibration missing', () => { @@ -166,8 +153,8 @@ describe('PipetteOffsetCalibrationItems', () => { }, ], } - const [{ getByText }] = render(props) - getByText('Not calibrated') + render(props) + screen.getByText('Not calibrated') }) it('should only render last calibrated date text when calibration recommended', () => { @@ -184,8 +171,8 @@ describe('PipetteOffsetCalibrationItems', () => { }, ], } - const [{ getByText, queryByText }] = render(props) - expect(queryByText('Not calibrated')).not.toBeInTheDocument() - getByText(formatLastCalibrated('2022-11-10T18:15:02')) + render(props) + expect(screen.queryByText('Not calibrated')).not.toBeInTheDocument() + screen.getByText(formatLastCalibrated('2022-11-10T18:15:02')) }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/TipLengthCalibrationItems.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/TipLengthCalibrationItems.test.tsx index 5ff254b87ed..df6f0de2089 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/TipLengthCalibrationItems.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/TipLengthCalibrationItems.test.tsx @@ -1,24 +1,23 @@ import * as React from 'react' -import { renderWithProviders, Mount } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { Mount } from '@opentrons/components' import { i18n } from '../../../../i18n' - +import { renderWithProviders } from '../../../../__testing-utils__' import { TipLengthCalibrationItems } from '../TipLengthCalibrationItems' import { OverflowMenu } from '../OverflowMenu' -jest.mock('../../../../redux/custom-labware/selectors') -jest.mock('../../../../redux/config') -jest.mock('../../../../redux/sessions/selectors') -jest.mock('../../../../redux/discovery') -jest.mock('../../../../assets/labware/findLabware') -jest.mock('../../../../organisms/Devices/hooks') -jest.mock('../OverflowMenu') +vi.mock('../../../../redux/custom-labware/selectors') +vi.mock('../../../../redux/config') +vi.mock('../../../../redux/sessions/selectors') +vi.mock('../../../../redux/discovery') +vi.mock('../../../../assets/labware/findLabware') +vi.mock('../../../../organisms/Devices/hooks') +vi.mock('../OverflowMenu') const ROBOT_NAME = 'otie' -const mockOverflowMenu = OverflowMenu as jest.MockedFunction< - typeof OverflowMenu -> - const mockPipetteOffsetCalibrations = [ { modelName: 'mockPipetteModelLeft', @@ -52,7 +51,7 @@ const mockTipLengthCalibrations = [ }, ] -const mockUpdateRobotStatus = jest.fn() +const mockUpdateRobotStatus = vi.fn() const render = ( props: React.ComponentProps @@ -65,7 +64,7 @@ describe('TipLengthCalibrationItems', () => { let props: React.ComponentProps beforeEach(() => { - mockOverflowMenu.mockReturnValue(
mock overflow menu
) + vi.mocked(OverflowMenu).mockReturnValue(
mock overflow menu
) props = { robotName: ROBOT_NAME, formattedPipetteOffsetCalibrations: mockPipetteOffsetCalibrations, @@ -75,24 +74,24 @@ describe('TipLengthCalibrationItems', () => { }) it('should render table headers', () => { - const [{ getByText }] = render(props) - getByText('Tip Rack') - getByText('Pipette Model and Serial') - getByText('Last Calibrated') + render(props) + screen.getByText('Tip Rack') + screen.getByText('Pipette Model and Serial') + screen.getByText('Last Calibrated') }) it('should render overFlow menu', () => { - const [{ queryAllByText }] = render(props) - expect(queryAllByText('mock overflow menu')).toHaveLength(2) + render(props) + expect(screen.queryAllByText('mock overflow menu')).toHaveLength(2) }) it('should render tip length calibrations data', () => { - const [{ getByText }] = render(props) + render(props) // todo tiprack - getByText('Mock-P1KSV222021011802') - getByText('11/10/2022 18:14:01') + screen.getByText('Mock-P1KSV222021011802') + screen.getByText('11/10/2022 18:14:01') - getByText('Mock-P2KSV222021011802') - getByText('11/10/2022 18:15:02') + screen.getByText('Mock-P2KSV222021011802') + screen.getByText('11/10/2022 18:15:02') }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/utils.test.ts b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/utils.test.ts index 5dfe595689e..8a6c97791e8 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/utils.test.ts +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/utils.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest' import { formatLastCalibrated } from '../utils' describe('formatLastCalibrated', () => { diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx index a2e23985c5e..0d56bfdc9ed 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx @@ -1,9 +1,17 @@ import * as React from 'react' -import { saveAs } from 'file-saver' -import { when, resetAllWhenMocks } from 'jest-when' -import { fireEvent } from '@testing-library/react' +import { when } from 'vitest-when' +import { + describe, + it, + expect, + vi, + beforeAll, + beforeEach, + afterAll, +} from 'vitest' +import { fireEvent, screen } from '@testing-library/react' +import '@testing-library/jest-dom/vitest' -import { renderWithProviders } from '@opentrons/components' import { useInstrumentsQuery, useModulesQuery, @@ -34,41 +42,18 @@ import { useRobot, useTipLengthCalibrations, } from '../../../organisms/Devices/hooks' +import { renderWithProviders } from '../../../__testing-utils__' import { useIsEstopNotDisengaged } from '../../../resources/devices/hooks/useIsEstopNotDisengaged' import { CalibrationDataDownload } from '../CalibrationDataDownload' -jest.mock('file-saver') -jest.mock('@opentrons/react-api-client') -jest.mock('../../../redux/analytics') -jest.mock('../../../organisms/Devices/hooks') -jest.mock('../../../resources/devices/hooks/useIsEstopNotDisengaged') - -const mockUseDeckCalibrationData = useDeckCalibrationData as jest.MockedFunction< - typeof useDeckCalibrationData -> -const mockUsePipetteOffsetCalibrations = usePipetteOffsetCalibrations as jest.MockedFunction< - typeof usePipetteOffsetCalibrations -> -const mockUseRobot = useRobot as jest.MockedFunction -const mockUseTipLengthCalibrations = useTipLengthCalibrations as jest.MockedFunction< - typeof useTipLengthCalibrations -> -const mockUseTrackEvent = useTrackEvent as jest.MockedFunction< - typeof useTrackEvent -> -const mockUseIsFlex = useIsFlex as jest.MockedFunction -const mockUseInstrumentsQuery = useInstrumentsQuery as jest.MockedFunction< - typeof useInstrumentsQuery -> -const mockUseModulesQuery = useModulesQuery as jest.MockedFunction< - typeof useModulesQuery -> -const mockUseIsEstopNotDisengaged = useIsEstopNotDisengaged as jest.MockedFunction< - typeof useIsEstopNotDisengaged -> +vi.mock('file-saver') +vi.mock('@opentrons/react-api-client') +vi.mock('../../../redux/analytics') +vi.mock('../../../organisms/Devices/hooks') +vi.mock('../../../resources/devices/hooks/useIsEstopNotDisengaged') -let mockTrackEvent: jest.Mock -const mockSetShowHowCalibrationWorksModal = jest.fn() +let mockTrackEvent: any +const mockSetShowHowCalibrationWorksModal = vi.fn() const ROBOT_NAME = 'otie' const render = () => { @@ -98,70 +83,60 @@ describe('CalibrationDataDownload', () => { }) beforeEach(() => { - mockTrackEvent = jest.fn() - when(mockUseTrackEvent).calledWith().mockReturnValue(mockTrackEvent) - when(mockUseDeckCalibrationData) + mockTrackEvent = vi.fn() + when(useTrackEvent).calledWith().thenReturn(mockTrackEvent) + when(useDeckCalibrationData) .calledWith(mockConnectableRobot.name) - .mockReturnValue({ + .thenReturn({ deckCalibrationData: mockDeckCalData, isDeckCalibrated: true, }) - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(false) - when(mockUsePipetteOffsetCalibrations) + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(false) + when(usePipetteOffsetCalibrations) .calledWith() - .mockReturnValue([ + .thenReturn([ mockPipetteOffsetCalibration1, mockPipetteOffsetCalibration2, mockPipetteOffsetCalibration3, ]) - when(mockUseRobot) - .calledWith(ROBOT_NAME) - .mockReturnValue(mockConnectableRobot) - when(mockUseTipLengthCalibrations) + when(useRobot).calledWith(ROBOT_NAME).thenReturn(mockConnectableRobot) + when(useTipLengthCalibrations) .calledWith() - .mockReturnValue([ + .thenReturn([ mockTipLengthCalibration1, mockTipLengthCalibration2, mockTipLengthCalibration3, ]) - mockUseInstrumentsQuery.mockReturnValue({ + vi.mocked(useInstrumentsQuery).mockReturnValue({ data: { data: [] }, } as any) - mockUseModulesQuery.mockReturnValue({ + vi.mocked(useModulesQuery).mockReturnValue({ data: { data: [] }, } as any) - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(false) - }) - - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(false) }) it('renders a title and description for OT2', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(false) - const [{ getByText }] = render() - getByText('Download Calibration Data') + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(false) + render() + screen.getByText('Download Calibration Data') }) it('renders an OT-3 title and description - About Calibration', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(true) - const [{ queryByText }] = render() - queryByText( + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(true) + render() + screen.queryByText( `For the robot to move accurately and precisely, you need to calibrate it. Pipette and gripper calibration is an automated process that uses a calibration probe or pin.` ) - queryByText( + screen.queryByText( `After calibration is complete, you can save the calibration data to your computer as a JSON file.` ) }) it('renders a download calibration data button', () => { - const [{ getByText }] = render() - const downloadButton = getByText('Download calibration logs') + render() + const downloadButton = screen.getByText('Download calibration logs') fireEvent.click(downloadButton) - expect(saveAs).toHaveBeenCalled() expect(mockTrackEvent).toHaveBeenCalledWith({ name: ANALYTICS_CALIBRATION_DATA_DOWNLOADED, properties: {}, @@ -169,97 +144,96 @@ describe('CalibrationDataDownload', () => { }) it('renders a download calibration button for Flex when cal data is present', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(true) - mockUseInstrumentsQuery.mockReturnValue({ + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(true) + vi.mocked(useInstrumentsQuery).mockReturnValue({ data: { data: [instrumentsResponseFixture.data[0]] }, } as any) - const [{ getByText }] = render() - const downloadButton = getByText('Download calibration logs') + render() + const downloadButton = screen.getByText('Download calibration logs') fireEvent.click(downloadButton) - expect(saveAs).toHaveBeenCalled() }) it('renders a See how robot calibration works link', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(true) - const [{ getByRole }] = render() + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(true) + render() const SUPPORT_LINK = 'https://support.opentrons.com' expect( - getByRole('link', { - name: 'See how robot calibration works', - }).getAttribute('href') + screen + .getByRole('link', { + name: 'See how robot calibration works', + }) + .getAttribute('href') ).toBe(SUPPORT_LINK) }) it('renders correct title and description', () => { - const [{ getByText }] = render() - getByText('Download Calibration Data') - getByText('Save all three types of calibration data as a JSON file.') + render() + screen.getByText('Download Calibration Data') + screen.getByText('Save all three types of calibration data as a JSON file.') - const downloadButton = getByText('Download calibration logs') + const downloadButton = screen.getByText('Download calibration logs') expect(downloadButton).toBeEnabled() }) // TODO: RAUT-94 Verify the logic for these three test conditions holds for the new calibration flow it('renders disabled button when deck is not calibrated', () => { - when(mockUseDeckCalibrationData) + when(useDeckCalibrationData) .calledWith(mockConnectableRobot.name) - .mockReturnValue({ + .thenReturn({ deckCalibrationData: mockDeckCalData, isDeckCalibrated: false, }) - const [{ getByRole, getByText }] = render() - getByText('No calibration data available.') + render() + screen.getByText('No calibration data available.') - const downloadButton = getByRole('button', { + const downloadButton = screen.getByRole('button', { name: 'Download calibration logs', }) expect(downloadButton).toBeDisabled() }) it('renders disabled button when pipettes are not calibrated', () => { - when(mockUsePipetteOffsetCalibrations).calledWith().mockReturnValue([]) - const [{ getByRole, getByText }] = render() - getByText('No calibration data available.') + when(usePipetteOffsetCalibrations).calledWith().thenReturn([]) + render() + screen.getByText('No calibration data available.') - const downloadButton = getByRole('button', { + const downloadButton = screen.getByRole('button', { name: 'Download calibration logs', }) expect(downloadButton).toBeDisabled() }) it('renders disabled button for Flex when no instrument is calibrated', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(true) - const [{ getByRole, queryByText }] = render() - queryByText( + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(true) + render() + screen.queryByText( `For the robot to move accurately and precisely, you need to calibrate it. Pipette and gripper calibration is an automated process that uses a calibration probe or pin.` ) - queryByText( + screen.queryByText( `After calibration is complete, you can save the calibration data to your computer as a JSON file.` ) - const downloadButton = getByRole('button', { + const downloadButton = screen.getByRole('button', { name: 'Download calibration logs', }) expect(downloadButton).toBeEnabled() // allow download for empty cal data }) it('renders disabled button when tip lengths are not calibrated', () => { - when(mockUseTipLengthCalibrations).calledWith().mockReturnValue([]) - const [{ getByRole, getByText }] = render() - getByText('No calibration data available.') + when(useTipLengthCalibrations).calledWith().thenReturn([]) + render() + screen.getByText('No calibration data available.') - const downloadButton = getByRole('button', { + const downloadButton = screen.getByRole('button', { name: 'Download calibration logs', }) expect(downloadButton).toBeDisabled() }) it('renders disabled button when e-stop is pressed', () => { - when(mockUseIsFlex).calledWith(ROBOT_NAME).mockReturnValue(true) - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(true) + when(useIsFlex).calledWith(ROBOT_NAME).thenReturn(true) + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(true) const [{ getByRole }] = render() const downloadButton = getByRole('button', { name: 'Download calibration logs', diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationHealthCheck.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationHealthCheck.test.tsx index f37d9f366d9..2c2232db5d3 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationHealthCheck.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/CalibrationHealthCheck.test.tsx @@ -1,9 +1,10 @@ import * as React from 'react' import userEvent from '@testing-library/user-event' import { fireEvent, screen, waitFor } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' -import { renderWithProviders } from '@opentrons/components' - +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { useTrackEvent, @@ -31,10 +32,10 @@ import type { PipetteCalibrationsByMount, } from '../../../redux/pipettes/types' -jest.mock('../../../redux/analytics') -jest.mock('../../../redux/config') -jest.mock('../../../redux/pipettes') -jest.mock('../../../organisms/Devices/hooks') +vi.mock('../../../redux/analytics') +vi.mock('../../../redux/config') +vi.mock('../../../redux/pipettes') +vi.mock('../../../organisms/Devices/hooks') const mockAttachedPipettes: AttachedPipettesByMount = { left: mockAttachedPipette, @@ -50,18 +51,6 @@ const mockAttachedPipetteCalibrations: PipetteCalibrationsByMount = { tipLength: mockTipLengthCalibration2, }, } as any -const mockUseTrackEvent = useTrackEvent as jest.MockedFunction< - typeof useTrackEvent -> -const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< - typeof useAttachedPipettes -> -const mockUseAttachedPipetteCalibrations = useAttachedPipetteCalibrations as jest.MockedFunction< - typeof useAttachedPipetteCalibrations -> -const mockUseRunStatuses = useRunStatuses as jest.MockedFunction< - typeof useRunStatuses -> const RUN_STATUSES = { isRunRunning: false, @@ -70,8 +59,8 @@ const RUN_STATUSES = { isRunIdle: false, } -let mockTrackEvent: jest.Mock -const mockDispatchRequests = jest.fn() +let mockTrackEvent: any +const mockDispatchRequests = vi.fn() const render = ( props?: Partial> @@ -92,14 +81,10 @@ const render = ( describe('CalibrationHealthCheck', () => { beforeEach(() => { - mockTrackEvent = jest.fn() - mockUseTrackEvent.mockReturnValue(mockTrackEvent) - mockUseAttachedPipettes.mockReturnValue(mockAttachedPipettes) - mockUseRunStatuses.mockReturnValue(RUN_STATUSES) - }) - - afterEach(() => { - jest.resetAllMocks() + mockTrackEvent = vi.fn() + vi.mocked(useTrackEvent).mockReturnValue(mockTrackEvent) + vi.mocked(useAttachedPipettes).mockReturnValue(mockAttachedPipettes) + vi.mocked(useRunStatuses).mockReturnValue(RUN_STATUSES) }) it('renders a title and description - Calibration Health Check section', () => { @@ -130,7 +115,7 @@ describe('CalibrationHealthCheck', () => { }) it('Health check button is disabled when a robot is running', () => { - mockUseRunStatuses.mockReturnValue({ + vi.mocked(useRunStatuses).mockReturnValue({ ...RUN_STATUSES, isRunRunning: true, }) @@ -140,14 +125,14 @@ describe('CalibrationHealthCheck', () => { }) it('Health check button is disabled when pipette are not set', () => { - mockUseAttachedPipettes.mockReturnValue({ left: null, right: null }) + vi.mocked(useAttachedPipettes).mockReturnValue({ left: null, right: null }) render() const button = screen.getByRole('button', { name: 'Check health' }) expect(button).toBeDisabled() }) it('Health check button shows Tooltip when pipette are not set', async () => { - mockUseAttachedPipettes.mockReturnValue({ left: null, right: null }) + vi.mocked(useAttachedPipettes).mockReturnValue({ left: null, right: null }) render() const button = screen.getByRole('button', { name: 'Check health' }) await userEvent.hover(button) @@ -161,11 +146,11 @@ describe('CalibrationHealthCheck', () => { }) it('health check button should be disabled if there is a running protocol', () => { - mockUseAttachedPipettes.mockReturnValue(mockAttachedPipettes) - mockUseAttachedPipetteCalibrations.mockReturnValue( + vi.mocked(useAttachedPipettes).mockReturnValue(mockAttachedPipettes) + vi.mocked(useAttachedPipetteCalibrations).mockReturnValue( mockAttachedPipetteCalibrations ) - mockUseRunStatuses.mockReturnValue({ + vi.mocked(useRunStatuses).mockReturnValue({ ...RUN_STATUSES, isRunRunning: true, }) diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsCalibration.test.tsx index 51bf9eea78a..0a075843352 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsCalibration.test.tsx @@ -1,12 +1,14 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' +import { when } from 'vitest-when' +import { screen } from '@testing-library/react' +import { describe, it, expect, beforeEach, vi } from 'vitest' +import '@testing-library/jest-dom/vitest' import { useInstrumentsQuery } from '@opentrons/react-api-client' import { i18n } from '../../../i18n' import { CalibrationStatusCard } from '../../../organisms/CalibrationStatusCard' import { useFeatureFlag } from '../../../redux/config' import * as RobotApi from '../../../redux/robot-api' +import { renderWithProviders } from '../../../__testing-utils__' import { mockPipetteOffsetCalibration1, mockPipetteOffsetCalibration2, @@ -34,74 +36,33 @@ import { RobotSettingsPipetteOffsetCalibration } from '../RobotSettingsPipetteOf import { RobotSettingsTipLengthCalibration } from '../RobotSettingsTipLengthCalibration' import { RobotSettingsModuleCalibration } from '../RobotSettingsModuleCalibration' import { RobotSettingsCalibration } from '..' - +import type * as ReactApiClient from '@opentrons/react-api-client' import type { AttachedPipettesByMount } from '../../../redux/pipettes/types' -jest.mock('@opentrons/react-api-client/src/instruments/useInstrumentsQuery') -jest.mock('../../../organisms/CalibrationStatusCard') -jest.mock('../../../redux/config') -jest.mock('../../../redux/sessions/selectors') -jest.mock('../../../redux/robot-api/selectors') -jest.mock('../../../organisms/Devices/hooks') -jest.mock('../CalibrationDataDownload') -jest.mock('../CalibrationHealthCheck') -jest.mock('../RobotSettingsDeckCalibration') -jest.mock('../RobotSettingsGripperCalibration') -jest.mock('../RobotSettingsPipetteOffsetCalibration') -jest.mock('../RobotSettingsTipLengthCalibration') -jest.mock('../RobotSettingsModuleCalibration') +vi.mock('@opentrons/react-api-client', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useInstrumentsQuery: vi.fn(), + } +}) +vi.mock('../../../organisms/CalibrationStatusCard') +vi.mock('../../../redux/config') +vi.mock('../../../redux/sessions/selectors') +vi.mock('../../../redux/robot-api/selectors') +vi.mock('../../../organisms/Devices/hooks') +vi.mock('../CalibrationDataDownload') +vi.mock('../CalibrationHealthCheck') +vi.mock('../RobotSettingsDeckCalibration') +vi.mock('../RobotSettingsGripperCalibration') +vi.mock('../RobotSettingsPipetteOffsetCalibration') +vi.mock('../RobotSettingsTipLengthCalibration') +vi.mock('../RobotSettingsModuleCalibration') const mockAttachedPipettes: AttachedPipettesByMount = { left: mockAttachedPipette, right: mockAttachedPipette, } as any -const mockUsePipetteOffsetCalibrations = usePipetteOffsetCalibrations as jest.MockedFunction< - typeof usePipetteOffsetCalibrations -> -const mockUseInstrumentsQuery = useInstrumentsQuery as jest.MockedFunction< - typeof useInstrumentsQuery -> -const mockUseRobot = useRobot as jest.MockedFunction -const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< - typeof useAttachedPipettes -> -const mockUseRunStatuses = useRunStatuses as jest.MockedFunction< - typeof useRunStatuses -> -const mockGetRequestById = RobotApi.getRequestById as jest.MockedFunction< - typeof RobotApi.getRequestById -> -const mockUseFeatureFlag = useFeatureFlag as jest.MockedFunction< - typeof useFeatureFlag -> -const mockCalibrationStatusCard = CalibrationStatusCard as jest.MockedFunction< - typeof CalibrationStatusCard -> -const mockCalibrationDataDownload = CalibrationDataDownload as jest.MockedFunction< - typeof CalibrationDataDownload -> -const mockCalibrationHealthCheck = CalibrationHealthCheck as jest.MockedFunction< - typeof CalibrationHealthCheck -> -const mockRobotSettingsDeckCalibration = RobotSettingsDeckCalibration as jest.MockedFunction< - typeof RobotSettingsDeckCalibration -> -const mockRobotSettingsGripperCalibration = RobotSettingsGripperCalibration as jest.MockedFunction< - typeof RobotSettingsGripperCalibration -> -const mockRobotSettingsPipetteOffsetCalibration = RobotSettingsPipetteOffsetCalibration as jest.MockedFunction< - typeof RobotSettingsPipetteOffsetCalibration -> -const mockRobotSettingsTipLengthCalibration = RobotSettingsTipLengthCalibration as jest.MockedFunction< - typeof RobotSettingsTipLengthCalibration -> -const mockUseAttachedPipettesFromInstrumentsQuery = useAttachedPipettesFromInstrumentsQuery as jest.MockedFunction< - typeof useAttachedPipettesFromInstrumentsQuery -> -const mockUseIsFlex = useIsFlex as jest.MockedFunction -const mockRobotSettingsModuleCalibration = RobotSettingsModuleCalibration as jest.MockedFunction< - typeof RobotSettingsModuleCalibration -> const RUN_STATUSES = { isRunRunning: false, @@ -110,7 +71,7 @@ const RUN_STATUSES = { isRunIdle: false, } -const mockUpdateRobotStatus = jest.fn() +const mockUpdateRobotStatus = vi.fn() const render = () => { return renderWithProviders( @@ -123,14 +84,15 @@ const render = () => { } ) } +const getRequestById = RobotApi.getRequestById describe('RobotSettingsCalibration', () => { beforeEach(() => { - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: null, right: null, }) - mockUseInstrumentsQuery.mockReturnValue({ + vi.mocked(useInstrumentsQuery).mockReturnValue({ data: { data: [ { @@ -140,140 +102,141 @@ describe('RobotSettingsCalibration', () => { ], }, } as any) - mockUsePipetteOffsetCalibrations.mockReturnValue([ + vi.mocked(usePipetteOffsetCalibrations).mockReturnValue([ mockPipetteOffsetCalibration1, mockPipetteOffsetCalibration2, mockPipetteOffsetCalibration3, ]) - mockUseRobot.mockReturnValue(mockConnectableRobot) - mockUseAttachedPipettes.mockReturnValue(mockAttachedPipettes) - mockUseRunStatuses.mockReturnValue(RUN_STATUSES) - mockGetRequestById.mockReturnValue(null) - when(mockUseIsFlex).calledWith('otie').mockReturnValue(false) - mockUseFeatureFlag.mockReturnValue(false) - mockCalibrationStatusCard.mockReturnValue( + vi.mocked(useRobot).mockReturnValue(mockConnectableRobot) + vi.mocked(useAttachedPipettes).mockReturnValue(mockAttachedPipettes) + vi.mocked(useRunStatuses).mockReturnValue(RUN_STATUSES) + vi.mocked(getRequestById).mockReturnValue(null) + when(useIsFlex).calledWith('otie').thenReturn(false) + vi.mocked(useFeatureFlag).mockReturnValue(false) + vi.mocked(CalibrationStatusCard).mockReturnValue(
Mock CalibrationStatusCard
) - mockCalibrationDataDownload.mockReturnValue( + vi.mocked(CalibrationDataDownload).mockReturnValue(
Mock CalibrationDataDownload
) - mockCalibrationHealthCheck.mockReturnValue( + vi.mocked(CalibrationHealthCheck).mockReturnValue(
Mock CalibrationHealthCheck
) - mockRobotSettingsDeckCalibration.mockReturnValue( + vi.mocked(RobotSettingsDeckCalibration).mockReturnValue(
Mock RobotSettingsDeckCalibration
) - mockRobotSettingsGripperCalibration.mockReturnValue( + vi.mocked(RobotSettingsGripperCalibration).mockReturnValue(
Mock RobotSettingsGripperCalibration
) - mockRobotSettingsPipetteOffsetCalibration.mockReturnValue( + vi.mocked(RobotSettingsPipetteOffsetCalibration).mockReturnValue(
Mock RobotSettingsPipetteOffsetCalibration
) - mockRobotSettingsTipLengthCalibration.mockReturnValue( + vi.mocked(RobotSettingsTipLengthCalibration).mockReturnValue(
Mock RobotSettingsTipLengthCalibration
) - mockRobotSettingsModuleCalibration.mockReturnValue( + vi.mocked(RobotSettingsModuleCalibration).mockReturnValue(
Mock RobotSettingsModuleCalibration
) }) - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() - }) - it('renders a Calibration Data Download component', () => { - const [{ getByText }] = render() - getByText('Mock CalibrationDataDownload') + render() + screen.getByText('Mock CalibrationDataDownload') }) it('renders a Calibration Data Download component when the calibration wizard feature flag is set', () => { - mockUseFeatureFlag.mockReturnValue(true) - const [{ getByText }] = render() - getByText('Mock CalibrationDataDownload') + vi.mocked(useFeatureFlag).mockReturnValue(true) + render() + screen.getByText('Mock CalibrationDataDownload') }) it('renders a Calibration Status component when the calibration wizard feature flag is set', () => { - mockUseFeatureFlag.mockReturnValue(true) - const [{ getByText }] = render() - getByText('Mock CalibrationStatusCard') + vi.mocked(useFeatureFlag).mockReturnValue(true) + render() + screen.getByText('Mock CalibrationStatusCard') }) it('renders a Deck Calibration component for an OT-2', () => { - const [{ getByText }] = render() - getByText('Mock RobotSettingsDeckCalibration') + render() + screen.getByText('Mock RobotSettingsDeckCalibration') }) it('does not render a Deck Calibration component for a Flex', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ queryByText }] = render() - expect(queryByText('Mock RobotSettingsDeckCalibration')).toBeNull() + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + expect(screen.queryByText('Mock RobotSettingsDeckCalibration')).toBeNull() }) it('renders a Pipette Offset Calibration component', () => { - const [{ getByText }] = render() - getByText('Mock RobotSettingsPipetteOffsetCalibration') + render() + screen.getByText('Mock RobotSettingsPipetteOffsetCalibration') }) it('renders a Tip Length Calibration component for an OT-2', () => { - const [{ getByText }] = render() - getByText('Mock RobotSettingsTipLengthCalibration') + render() + screen.getByText('Mock RobotSettingsTipLengthCalibration') }) it('does not render a Tip Length Calibration component for a Flex', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ queryByText }] = render() - expect(queryByText('Mock RobotSettingsTipLengthCalibration')).toBeNull() + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + expect( + screen.queryByText('Mock RobotSettingsTipLengthCalibration') + ).toBeNull() }) it('renders a Calibration Health Check component for an OT-2', () => { - const [{ getByText }] = render() - getByText('Mock CalibrationHealthCheck') + render() + screen.getByText('Mock CalibrationHealthCheck') }) it('does not render a Calibration Health Check component for a Flex', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ queryByText }] = render() - expect(queryByText('Mock CalibrationHealthCheck')).toBeNull() + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + expect(screen.queryByText('Mock CalibrationHealthCheck')).toBeNull() }) it('renders a Gripper Calibration component for a Flex', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ getByText }] = render() - getByText('Mock RobotSettingsGripperCalibration') + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + screen.getByText('Mock RobotSettingsGripperCalibration') }) it('does not render a Gripper Calibration component for an OT-2', () => { - const [{ queryByText }] = render() - expect(queryByText('Mock RobotSettingsGripperCalibration')).toBeNull() + render() + expect( + screen.queryByText('Mock RobotSettingsGripperCalibration') + ).toBeNull() }) it('does not render the OT-2 components when there is a Flex attached with pipettes', () => { - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: mockAttachedPipetteInformation, right: null, }) - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ queryByText }] = render() - expect(queryByText('Mock RobotSettingsDeckCalibration')).toBeNull() - expect(queryByText('Mock RobotSettingsTipLengthCalibration')).toBeNull() - expect(queryByText('Mock CalibrationHealthCheck')).toBeNull() + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + expect(screen.queryByText('Mock RobotSettingsDeckCalibration')).toBeNull() + expect( + screen.queryByText('Mock RobotSettingsTipLengthCalibration') + ).toBeNull() + expect(screen.queryByText('Mock CalibrationHealthCheck')).toBeNull() }) it('renders the correct calibration data for a Flex pipette', () => { - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: mockAttachedPipetteInformation, right: null, }) - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ getByText }] = render() - getByText('Mock RobotSettingsPipetteOffsetCalibration') + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + screen.getByText('Mock RobotSettingsPipetteOffsetCalibration') }) it('render a Module Calibration component for a Flex and module calibration feature flag is on', () => { - mockUseFeatureFlag.mockReturnValue(true) - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - const [{ getByText }] = render() - getByText('Mock RobotSettingsModuleCalibration') + vi.mocked(useFeatureFlag).mockReturnValue(true) + when(useIsFlex).calledWith('otie').thenReturn(true) + render() + screen.getByText('Mock RobotSettingsModuleCalibration') }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsDeckCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsDeckCalibration.test.tsx index 15d1cf3dbf5..501141a6f82 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsDeckCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsDeckCalibration.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react' - -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' import * as RobotApi from '../../../redux/robot-api' @@ -15,29 +15,20 @@ import { useRobot, useAttachedPipettes, } from '../../../organisms/Devices/hooks' +import { renderWithProviders } from '../../../__testing-utils__' import { RobotSettingsDeckCalibration } from '../RobotSettingsDeckCalibration' import type { AttachedPipettesByMount } from '../../../redux/pipettes/types' -jest.mock('../../../organisms/CalibrationStatusCard') -jest.mock('../../../redux/robot-api/selectors') -jest.mock('../../../organisms/Devices/hooks') +vi.mock('../../../organisms/CalibrationStatusCard') +vi.mock('../../../redux/robot-api/selectors') +vi.mock('../../../organisms/Devices/hooks') const mockAttachedPipettes: AttachedPipettesByMount = { left: mockAttachedPipette, right: mockAttachedPipette, } as any -const mockUseDeckCalibrationData = useDeckCalibrationData as jest.MockedFunction< - typeof useDeckCalibrationData -> -const mockUseRobot = useRobot as jest.MockedFunction -const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< - typeof useAttachedPipettes -> -const mockGetRequestById = RobotApi.getRequestById as jest.MockedFunction< - typeof RobotApi.getRequestById -> const render = ( props?: Partial> @@ -49,46 +40,43 @@ const render = ( } ) } +const getRequestById = RobotApi.getRequestById describe('RobotSettingsDeckCalibration', () => { beforeEach(() => { - mockUseDeckCalibrationData.mockReturnValue({ + vi.mocked(useDeckCalibrationData).mockReturnValue({ deckCalibrationData: mockDeckCalData, isDeckCalibrated: true, }) - mockUseRobot.mockReturnValue(mockConnectableRobot) - mockUseAttachedPipettes.mockReturnValue(mockAttachedPipettes) - mockGetRequestById.mockReturnValue(null) - }) - - afterEach(() => { - jest.resetAllMocks() + vi.mocked(useRobot).mockReturnValue(mockConnectableRobot) + vi.mocked(useAttachedPipettes).mockReturnValue(mockAttachedPipettes) + vi.mocked(getRequestById).mockReturnValue(null) }) it('renders a title description and button', () => { - const [{ getByText }] = render() - getByText('Deck Calibration') - getByText( + render() + screen.getByText('Deck Calibration') + screen.getByText( 'Calibrating the deck is required for new robots or after you relocate your robot. Recalibrating the deck will require you to also recalibrate pipette offsets.' ) - getByText('Last calibrated: September 15, 2021 00:00') + screen.getByText('Last calibrated: September 15, 2021 00:00') }) it('renders empty state if yet not calibrated', () => { - mockUseDeckCalibrationData.mockReturnValue({ + vi.mocked(useDeckCalibrationData).mockReturnValue({ deckCalibrationData: null, isDeckCalibrated: false, }) - const [{ getByText }] = render() - getByText('Not calibrated yet') + render() + screen.getByText('Not calibrated yet') }) it('renders the last calibrated when deck calibration is not good', () => { - mockUseDeckCalibrationData.mockReturnValue({ + vi.mocked(useDeckCalibrationData).mockReturnValue({ deckCalibrationData: mockWarningDeckCalData, isDeckCalibrated: true, }) - const [{ getByText }] = render() - getByText('Last calibrated: September 22, 2222 00:00') + render() + screen.getByText('Last calibrated: September 22, 2222 00:00') }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsGripperCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsGripperCalibration.test.tsx index 07ad986e40c..9d02f3894d5 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsGripperCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsGripperCalibration.test.tsx @@ -1,10 +1,10 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' +import { when } from 'vitest-when' import { fireEvent, screen } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { GripperWizardFlows } from '../../../organisms/GripperWizardFlows' import { formatLastCalibrated } from '../CalibrationDetails/utils' import { useIsEstopNotDisengaged } from '../../../resources/devices/hooks/useIsEstopNotDisengaged' @@ -12,19 +12,9 @@ import { RobotSettingsGripperCalibration } from '../RobotSettingsGripperCalibrat import type { GripperData } from '@opentrons/api-client' -jest.mock('../../../organisms/GripperWizardFlows') -jest.mock('../CalibrationDetails/utils') -jest.mock('../../../resources/devices/hooks/useIsEstopNotDisengaged') - -const mockGripperWizardFlows = GripperWizardFlows as jest.MockedFunction< - typeof GripperWizardFlows -> -const mockFormatLastCalibrated = formatLastCalibrated as jest.MockedFunction< - typeof formatLastCalibrated -> -const mockUseIsEstopNotDisengaged = useIsEstopNotDisengaged as jest.MockedFunction< - typeof useIsEstopNotDisengaged -> +vi.mock('../../../organisms/GripperWizardFlows') +vi.mock('../CalibrationDetails/utils') +vi.mock('../../../resources/devices/hooks/useIsEstopNotDisengaged') const mockGripperData = { serialNumber: 'mockSerial123', @@ -55,22 +45,15 @@ const render = ( describe('RobotSettingsGripperCalibration', () => { let props: React.ComponentProps beforeEach(() => { - mockFormatLastCalibrated.mockReturnValue('last calibrated 1/2/3') - mockGripperWizardFlows.mockReturnValue(<>Mock Wizard Flow) - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(false) + vi.mocked(formatLastCalibrated).mockReturnValue('last calibrated 1/2/3') + vi.mocked(GripperWizardFlows).mockReturnValue(<>Mock Wizard Flow) + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(false) props = { gripper: mockGripperData, robotName: ROBOT_NAME, } }) - afterEach(() => { - jest.clearAllMocks() - resetAllWhenMocks() - }) - it('renders a title and description - Gripper Calibration section', () => { render(props) screen.getByText('Gripper Calibration') @@ -124,12 +107,10 @@ describe('RobotSettingsGripperCalibration', () => { }) it('overflow menu is disabled when e-stop button is pressed', () => { - when(mockUseIsEstopNotDisengaged) - .calledWith(ROBOT_NAME) - .mockReturnValue(true) - const [{ getByRole }] = render(props) + when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(true) + render(props) expect( - getByRole('button', { + screen.getByRole('button', { name: 'CalibrationOverflowMenu_button_gripperCalibration', }) ).toBeDisabled() diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsModuleCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsModuleCalibration.test.tsx index da2adb6af9f..b3795b939f2 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsModuleCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsModuleCalibration.test.tsx @@ -1,16 +1,13 @@ import * as React from 'react' - -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' -import { ModuleCalibrationItems } from '../CalibrationDetails/ModuleCalibrationItems' +import { renderWithProviders } from '../../../__testing-utils__' import { mockFetchModulesSuccessActionPayloadModules } from '../../../redux/modules/__fixtures__' import { RobotSettingsModuleCalibration } from '../RobotSettingsModuleCalibration' +import { ModuleCalibrationItems } from '../CalibrationDetails/ModuleCalibrationItems' -jest.mock('../CalibrationDetails/ModuleCalibrationItems') - -const mockModuleCalibrationItems = ModuleCalibrationItems as jest.MockedFunction< - typeof ModuleCalibrationItems -> +vi.mock('../CalibrationDetails/ModuleCalibrationItems') const render = ( props: React.ComponentProps @@ -28,31 +25,31 @@ describe('RobotSettingsModuleCalibration', () => { beforeEach(() => { props = { attachedModules: mockFetchModulesSuccessActionPayloadModules, - updateRobotStatus: jest.fn(), + updateRobotStatus: vi.fn(), formattedPipetteOffsetCalibrations: [], robotName: ROBOT_NAME, } - mockModuleCalibrationItems.mockReturnValue( + vi.mocked(ModuleCalibrationItems).mockReturnValue(
mock ModuleCalibrationItems
) }) it('should render text and ModuleCalibrationItems when a module is attached', () => { - const [{ getByText }] = render(props) - getByText('Module Calibration') - getByText( + render(props) + screen.getByText('Module Calibration') + screen.getByText( "Module calibration uses a pipette and attached probe to determine the module's exact position relative to the deck." ) - getByText('mock ModuleCalibrationItems') + screen.getByText('mock ModuleCalibrationItems') }) it('should render no modules attached when there is no module', () => { props = { ...props, attachedModules: [] } - const [{ getByText }] = render(props) - getByText('Module Calibration') - getByText( + render(props) + screen.getByText('Module Calibration') + screen.getByText( "Module calibration uses a pipette and attached probe to determine the module's exact position relative to the deck." ) - getByText('No modules attached') + screen.getByText('No modules attached') }) }) diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsPipetteOffsetCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsPipetteOffsetCalibration.test.tsx index 2a252dceeaa..0970efc2187 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsPipetteOffsetCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsPipetteOffsetCalibration.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' +import { when } from 'vitest-when' +import { describe, it, vi, beforeEach } from 'vitest' +import { screen } from '@testing-library/react' import { i18n } from '../../../i18n' import { @@ -14,6 +14,7 @@ import { usePipetteOffsetCalibrations, useAttachedPipettesFromInstrumentsQuery, } from '../../../organisms/Devices/hooks' +import { renderWithProviders } from '../../../__testing-utils__' import { mockAttachedPipetteInformation } from '../../../redux/pipettes/__fixtures__' import { RobotSettingsPipetteOffsetCalibration } from '../RobotSettingsPipetteOffsetCalibration' @@ -21,21 +22,11 @@ import { PipetteOffsetCalibrationItems } from '../CalibrationDetails/PipetteOffs import type { FormattedPipetteOffsetCalibration } from '..' -jest.mock('../../../organisms/Devices/hooks') -jest.mock('../CalibrationDetails/PipetteOffsetCalibrationItems') +vi.mock('../../../organisms/Devices/hooks') +vi.mock('../CalibrationDetails/PipetteOffsetCalibrationItems') -const mockUseIsFlex = useIsFlex as jest.MockedFunction -const mockUsePipetteOffsetCalibrations = usePipetteOffsetCalibrations as jest.MockedFunction< - typeof usePipetteOffsetCalibrations -> -const mockPipetteOffsetCalibrationItems = PipetteOffsetCalibrationItems as jest.MockedFunction< - typeof PipetteOffsetCalibrationItems -> -const mockUseAttachedPipettesFromInstrumentsQuery = useAttachedPipettesFromInstrumentsQuery as jest.MockedFunction< - typeof useAttachedPipettesFromInstrumentsQuery -> const mockFormattedPipetteOffsetCalibrations: FormattedPipetteOffsetCalibration[] = [] -const mockUpdateRobotStatus = jest.fn() +const mockUpdateRobotStatus = vi.fn() const render = ( props?: Partial< @@ -59,48 +50,43 @@ const render = ( describe('RobotSettingsPipetteOffsetCalibration', () => { beforeEach(() => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(false) - mockUsePipetteOffsetCalibrations.mockReturnValue([ + when(useIsFlex).calledWith('otie').thenReturn(false) + vi.mocked(usePipetteOffsetCalibrations).mockReturnValue([ mockPipetteOffsetCalibration1, mockPipetteOffsetCalibration2, mockPipetteOffsetCalibration3, ]) - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: null, right: null, }) - mockPipetteOffsetCalibrationItems.mockReturnValue( + vi.mocked(PipetteOffsetCalibrationItems).mockReturnValue(
PipetteOffsetCalibrationItems
) }) - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() - }) - it('renders a title - Pipette Offset Calibrations', () => { - const [{ getByText }] = render() - getByText('Pipette Offset Calibrations') - getByText('PipetteOffsetCalibrationItems') + render() + screen.getByText('Pipette Offset Calibrations') + screen.getByText('PipetteOffsetCalibrationItems') }) it('renders a Flex title and description - Pipette Calibrations', () => { - when(mockUseIsFlex).calledWith('otie').mockReturnValue(true) - mockUseAttachedPipettesFromInstrumentsQuery.mockReturnValue({ + when(useIsFlex).calledWith('otie').thenReturn(true) + vi.mocked(useAttachedPipettesFromInstrumentsQuery).mockReturnValue({ left: mockAttachedPipetteInformation, right: null, }) - const [{ getByText }] = render() - getByText('Pipette Calibrations') - getByText( + render() + screen.getByText('Pipette Calibrations') + screen.getByText( `Pipette calibration uses a metal probe to determine the pipette's exact position relative to precision-cut squares on deck slots.` ) - getByText('PipetteOffsetCalibrationItems') + screen.getByText('PipetteOffsetCalibrationItems') }) it('renders Not calibrated yet when no pipette offset calibrations data', () => { - mockUsePipetteOffsetCalibrations.mockReturnValue(null) + vi.mocked(usePipetteOffsetCalibrations).mockReturnValue(null) const [{ getByText }] = render() getByText('No pipette attached') }) diff --git a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsTipLengthCalibration.test.tsx b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsTipLengthCalibration.test.tsx index b01fea3e105..9225f487259 100644 --- a/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsTipLengthCalibration.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/__tests__/RobotSettingsTipLengthCalibration.test.tsx @@ -1,9 +1,9 @@ import * as React from 'react' - -import { renderWithProviders } from '@opentrons/components' - +import { screen } from '@testing-library/react' +import { describe, it, beforeEach, vi } from 'vitest' import { i18n } from '../../../i18n' import { useFeatureFlag } from '../../../redux/config' +import { renderWithProviders } from '../../../__testing-utils__' import { mockTipLengthCalibration1, mockTipLengthCalibration2, @@ -21,26 +21,13 @@ import { TipLengthCalibrationItems } from '../CalibrationDetails/TipLengthCalibr import type { FormattedPipetteOffsetCalibration } from '..' import type { AttachedPipettesByMount } from '../../../redux/pipettes/types' -jest.mock('../../../redux/config') -jest.mock('../../../organisms/Devices/hooks') -jest.mock('../CalibrationDetails/TipLengthCalibrationItems') - -const mockUseTipLengthCalibrations = useTipLengthCalibrations as jest.MockedFunction< - typeof useTipLengthCalibrations -> -const mockTipLengthCalibrationItems = TipLengthCalibrationItems as jest.MockedFunction< - typeof TipLengthCalibrationItems -> -const mockUseFeatureFlag = useFeatureFlag as jest.MockedFunction< - typeof useFeatureFlag -> -const mockUseAttachedPipettes = useAttachedPipettes as jest.MockedFunction< - typeof useAttachedPipettes -> +vi.mock('../../../redux/config') +vi.mock('../../../organisms/Devices/hooks') +vi.mock('../CalibrationDetails/TipLengthCalibrationItems') const mockFormattedPipetteOffsetCalibrations: FormattedPipetteOffsetCalibration[] = [] -const mockUpdateRobotStatus = jest.fn() +const mockUpdateRobotStatus = vi.fn() const render = () => { return renderWithProviders( @@ -59,28 +46,24 @@ const render = () => { describe('RobotSettingsTipLengthCalibration', () => { beforeEach(() => { - mockUseTipLengthCalibrations.mockReturnValue([ + vi.mocked(useTipLengthCalibrations).mockReturnValue([ mockTipLengthCalibration1, mockTipLengthCalibration2, mockTipLengthCalibration3, ]) - mockTipLengthCalibrationItems.mockReturnValue( + vi.mocked(TipLengthCalibrationItems).mockReturnValue(
Mock TipLengthCalibrationItems
) - mockUseFeatureFlag.mockReturnValue(false) - mockUseAttachedPipettes.mockReturnValue({ + vi.mocked(useFeatureFlag).mockReturnValue(false) + vi.mocked(useAttachedPipettes).mockReturnValue({ left: mockAttachedPipette, right: null, } as AttachedPipettesByMount) }) - afterEach(() => { - jest.resetAllMocks() - }) - it('renders a title', () => { - const [{ getByText }] = render() - getByText('Tip Length Calibrations') - getByText('Mock TipLengthCalibrationItems') + render() + screen.getByText('Tip Length Calibrations') + screen.getByText('Mock TipLengthCalibrationItems') }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/EthernetConnectionDetails.test.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/EthernetConnectionDetails.test.tsx index 45767b615a2..a82b17e3455 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/EthernetConnectionDetails.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/EthernetConnectionDetails.test.tsx @@ -1,29 +1,19 @@ import * as React from 'react' -import { when } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' -import { fireEvent } from '@testing-library/react' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../../i18n' -import * as Networking from '../../../../redux/networking' +import { INTERFACE_ETHERNET } from '../../../../redux/networking' +import { getNetworkInterfaces } from '../../../../redux/networking/selectors' +import { renderWithProviders } from '../../../../__testing-utils__' import { getLocalRobot } from '../../../../redux/discovery' import { mockConnectedRobot } from '../../../../redux/discovery/__fixtures__' import { EthernetConnectionDetails } from '../EthernetConnectionDetails' -import type { State } from '../../../../redux/types' - -jest.mock('../../../../redux/networking') -jest.mock('../../../../redux/discovery') -jest.mock('../../../../redux/discovery/selectors') - -const mockGetNetworkInterfaces = Networking.getNetworkInterfaces as jest.MockedFunction< - typeof Networking.getNetworkInterfaces -> -const mockGetLocalRobot = getLocalRobot as jest.MockedFunction< - typeof getLocalRobot -> - -const ROBOT_NAME = 'opentrons-robot-name' +vi.mock('../../../../redux/discovery') +vi.mock('../../../../redux/discovery/selectors') +vi.mock('../../../../redux/networking/selectors') const render = ( props: React.ComponentProps @@ -37,38 +27,32 @@ const mockEthernet = { ipAddress: '127.0.0.100', subnetMask: '255.255.255.230', macAddress: 'ET:NT:00:00:00:00', - type: Networking.INTERFACE_ETHERNET, + type: INTERFACE_ETHERNET, } describe('EthernetConnectionDetails', () => { let props: React.ComponentProps beforeEach(() => { props = { - handleGoBack: jest.fn(), + handleGoBack: vi.fn(), } - mockGetLocalRobot.mockReturnValue(mockConnectedRobot) - when(mockGetNetworkInterfaces) - .calledWith({} as State, ROBOT_NAME) - .mockReturnValue({ - wifi: null, - ethernet: mockEthernet, - }) - }) - - afterEach(() => { - jest.resetAllMocks() + vi.mocked(getLocalRobot).mockReturnValue(mockConnectedRobot) + vi.mocked(getNetworkInterfaces).mockReturnValue({ + wifi: null, + ethernet: mockEthernet, + }) }) it('should render ip address, subnet mask, mac address, text and button when ethernet is connected', () => { - const [{ getByText, queryByText }] = render(props) - getByText('IP Address') - getByText('Subnet Mask') - getByText('MAC Address') - getByText('127.0.0.100') - getByText('255.255.255.230') - getByText('ET:NT:00:00:00:00') + render(props) + screen.getByText('IP Address') + screen.getByText('Subnet Mask') + screen.getByText('MAC Address') + screen.getByText('127.0.0.100') + screen.getByText('255.255.255.230') + screen.getByText('ET:NT:00:00:00:00') expect( - queryByText( + screen.queryByText( 'Connect an Ethernet cable to the back of the robot and a network switch or hub.' ) ).not.toBeInTheDocument() @@ -79,28 +63,26 @@ describe('EthernetConnectionDetails', () => { ipAddress: null, subnetMask: null, macAddress: 'ET:NT:00:00:00:11', - type: Networking.INTERFACE_ETHERNET, + type: INTERFACE_ETHERNET, } - when(mockGetNetworkInterfaces) - .calledWith({} as State, ROBOT_NAME) - .mockReturnValue({ - wifi: null, - ethernet: notConnectedMockEthernet, - }) - const [{ getByText, getAllByText }] = render(props) - getByText('IP Address') - getByText('Subnet Mask') - getByText('MAC Address') - expect(getAllByText('No data').length).toBe(2) - getByText('ET:NT:00:00:00:11') - getByText( + vi.mocked(getNetworkInterfaces).mockReturnValue({ + wifi: null, + ethernet: notConnectedMockEthernet, + }) + render(props) + screen.getByText('IP Address') + screen.getByText('Subnet Mask') + screen.getByText('MAC Address') + expect(screen.getAllByText('No data').length).toBe(2) + screen.getByText('ET:NT:00:00:00:11') + screen.getByText( 'Connect an Ethernet cable to the back of the robot and a network switch or hub.' ) }) it('should call handleGoBack when pressing back', () => { - const [{ getByRole }] = render(props) - const backButton = getByRole('button') + render(props) + const backButton = screen.getByRole('button') fireEvent.click(backButton) expect(props.handleGoBack).toHaveBeenCalled() }) diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkDetailsModal.test.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkDetailsModal.test.tsx index 9ec486dc43d..6333bec9b81 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkDetailsModal.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkDetailsModal.test.tsx @@ -1,12 +1,13 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../../i18n' +import { renderWithProviders } from '../../../../__testing-utils__' import { NetworkDetailsModal } from '../NetworkDetailsModal' -const mockFn = jest.fn() +const mockFn = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -28,22 +29,18 @@ describe('NetworkDetailsModal', () => { } }) - afterEach(() => { - jest.clearAllMocks() - }) - it('should render text and icon - wifi', () => { - const [{ getByText, getByLabelText }] = render(props) - getByText('mock Wifi ssid') - getByText('IP Address') - getByText('192.168.1.100') - getByText('Security Type') - getByText('WPA-2') - getByText('Subnet Mask') - getByText('255.255.255.0') - getByText('MAC Address') - getByText('00:14:2D:69:45:9F') - getByLabelText('icon_wifi') + render(props) + screen.getByText('mock Wifi ssid') + screen.getByText('IP Address') + screen.getByText('192.168.1.100') + screen.getByText('Security Type') + screen.getByText('WPA-2') + screen.getByText('Subnet Mask') + screen.getByText('255.255.255.0') + screen.getByText('MAC Address') + screen.getByText('00:14:2D:69:45:9F') + screen.getByLabelText('icon_wifi') }) it('should render text and icon - ethernet', () => { @@ -54,27 +51,27 @@ describe('NetworkDetailsModal', () => { macAddress: '00:14:2D:69:45:9A', } props = ethernetSettings - const [{ getByText, queryByText, getByLabelText }] = render(props) - getByText('Ethernet') - getByText('IP Address') - getByText('192.168.0.100') - expect(queryByText('Security Type')).not.toBeInTheDocument() - getByText('Subnet Mask') - getByText('255.255.255.0') - getByText('MAC Address') - getByText('00:14:2D:69:45:9A') - getByLabelText('icon_ethernet') + render(props) + screen.getByText('Ethernet') + screen.getByText('IP Address') + screen.getByText('192.168.0.100') + expect(screen.queryByText('Security Type')).not.toBeInTheDocument() + screen.getByText('Subnet Mask') + screen.getByText('255.255.255.0') + screen.getByText('MAC Address') + screen.getByText('00:14:2D:69:45:9A') + screen.getByLabelText('icon_ethernet') }) it('should call the mock function when tapping the close icon', () => { - const [{ getByLabelText }] = render(props) - fireEvent.click(getByLabelText('closeIcon')) + render(props) + fireEvent.click(screen.getByLabelText('closeIcon')) expect(mockFn).toHaveBeenCalled() }) it('should call the mock function when tapping outside of the modal', () => { - const [{ getByLabelText }] = render(props) - fireEvent.click(getByLabelText('BackgroundOverlay')) + render(props) + fireEvent.click(screen.getByLabelText('BackgroundOverlay')) expect(mockFn).toHaveBeenCalled() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkSettings.test.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkSettings.test.tsx index 2ce02101edb..66ee3e5b9ab 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkSettings.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/NetworkSettings.test.tsx @@ -1,8 +1,10 @@ import * as React from 'react' - -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../../i18n' +import { renderWithProviders } from '../../../../__testing-utils__' import { getLocalRobot } from '../../../../redux/discovery' import { useWifiList } from '../../../../resources/networking/hooks' import { WifiConnectionDetails } from '../WifiConnectionDetails' @@ -12,22 +14,12 @@ import { NetworkSettings } from '..' import type { DiscoveredRobot } from '../../../../redux/discovery/types' import type { WifiNetwork } from '../../../../redux/networking/types' -jest.mock('../../../../redux/discovery') -jest.mock('../../../../resources/networking/hooks') -jest.mock('../WifiConnectionDetails') -jest.mock('../EthernetConnectionDetails') +vi.mock('../../../../redux/discovery') +vi.mock('../../../../resources/networking/hooks') +vi.mock('../WifiConnectionDetails') +vi.mock('../EthernetConnectionDetails') -const mockGetLocalRobot = getLocalRobot as jest.MockedFunction< - typeof getLocalRobot -> -const mockUseWifiList = useWifiList as jest.MockedFunction -const mockWifiSettings = WifiConnectionDetails as jest.MockedFunction< - typeof WifiConnectionDetails -> -const mockEthernetConnectionDetails = EthernetConnectionDetails as jest.MockedFunction< - typeof EthernetConnectionDetails -> -const mockSetCurrentOption = jest.fn() +const mockSetCurrentOption = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -49,59 +41,57 @@ describe('NetworkSettings', () => { activeSsid: 'Mock WiFi Network', }, } - mockGetLocalRobot.mockReturnValue({ + vi.mocked(getLocalRobot).mockReturnValue({ name: 'Otie', } as DiscoveredRobot) - mockUseWifiList.mockReturnValue([ + vi.mocked(useWifiList).mockReturnValue([ { ssid: 'Mock WiFi Network', active: true, securityType: 'wpa-psk', } as WifiNetwork, ]) - mockWifiSettings.mockReturnValue(
mock WifiConnectionDetails
) - mockEthernetConnectionDetails.mockReturnValue( + vi.mocked(WifiConnectionDetails).mockReturnValue( +
mock WifiConnectionDetails
+ ) + vi.mocked(EthernetConnectionDetails).mockReturnValue(
mock EthernetConnectionDetails
) }) - afterEach(() => { - jest.clearAllMocks() - }) - it('displays the wifi and ethernet options', () => { - const [{ getByText }] = render(props) - expect(getByText('Wi-Fi')).toBeTruthy() - expect(getByText('Ethernet')).toBeTruthy() + render(props) + expect(screen.getByText('Wi-Fi')).toBeTruthy() + expect(screen.getByText('Ethernet')).toBeTruthy() }) it('selecting the Wi-Fi option displays the wifi details', () => { - const [{ getByText }] = render(props) - getByText('Wi-Fi').click() + render(props) + screen.getByText('Wi-Fi').click() expect(mockSetCurrentOption).toHaveBeenCalledWith('RobotSettingsWifi') }) it('clicking back on the wifi details screen shows the network settings page again', () => { - const [{ getByText, queryByText, container }] = render(props) - getByText('Wi-Fi').click() + const [{ container }] = render(props) + screen.getByText('Wi-Fi').click() container.querySelector('button')?.click() - expect(queryByText('WIFI DETAILS')).toBeFalsy() - expect(getByText('Network Settings')).toBeTruthy() + expect(screen.queryByText('WIFI DETAILS')).toBeFalsy() + expect(screen.getByText('Network Settings')).toBeTruthy() }) it('selecting the Ethernet option displays the ethernet details', () => { - const [{ getByText }] = render(props) - getByText('Ethernet').click() + render(props) + screen.getByText('Ethernet').click() expect(mockSetCurrentOption).toHaveBeenCalledWith( 'EthernetConnectionDetails' ) }) it('clicking back on the ethernet details screen shows the network settings page again', () => { - const [{ getByText, queryByText, container }] = render(props) - getByText('Ethernet').click() + const [{ container }] = render(props) + screen.getByText('Ethernet').click() container.querySelector('button')?.click() - expect(queryByText('ETHERNET DETAILS')).toBeFalsy() - expect(getByText('Network Settings')).toBeTruthy() + expect(screen.queryByText('ETHERNET DETAILS')).toBeFalsy() + expect(screen.getByText('Network Settings')).toBeTruthy() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/WifiConnectionDetails.test.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/WifiConnectionDetails.test.tsx index 80077a64d3c..a8ec836d044 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/WifiConnectionDetails.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/WifiConnectionDetails.test.tsx @@ -1,40 +1,32 @@ import * as React from 'react' import { fireEvent, screen } from '@testing-library/react' -import { when, resetAllWhenMocks } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' +import { when } from 'vitest-when' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../../i18n' +import { renderWithProviders } from '../../../../__testing-utils__' import { getLocalRobot } from '../../../../redux/discovery' import * as Networking from '../../../../redux/networking' import { NetworkDetailsModal } from '../NetworkDetailsModal' import { WifiConnectionDetails } from '../WifiConnectionDetails' - +import type * as Dom from 'react-router-dom' import type { State } from '../../../../redux/types' -jest.mock('../../../../redux/discovery') -jest.mock('../../../../redux/networking') -jest.mock('../NetworkDetailsModal') +vi.mock('../../../../redux/discovery') +vi.mock('../../../../redux/networking') +vi.mock('../NetworkDetailsModal') -const mockPush = jest.fn() -jest.mock('react-router-dom', () => { - const reactRouterDom = jest.requireActual('react-router-dom') +const mockPush = vi.fn() +vi.mock('react-router-dom', async importOriginal => { + const reactRouterDom = await importOriginal() return { ...reactRouterDom, useHistory: () => ({ push: mockPush } as any), } }) -const mockGetNetworkInterfaces = Networking.getNetworkInterfaces as jest.MockedFunction< - typeof Networking.getNetworkInterfaces -> -const mockNetworkDetailsModal = NetworkDetailsModal as jest.MockedFunction< - typeof NetworkDetailsModal -> -const mockGetLocalRobot = getLocalRobot as jest.MockedFunction< - typeof getLocalRobot -> - +const getNetworkInterfaces = Networking.getNetworkInterfaces const ROBOT_NAME = 'otie' const initialMockWifi = { @@ -56,23 +48,21 @@ describe('WifiConnectionDetails', () => { props = { activeSsid: 'mock wifi ssid', connectedWifiAuthType: 'none', - handleNetworkPress: jest.fn(), - handleJoinAnotherNetwork: jest.fn(), + handleNetworkPress: vi.fn(), + handleJoinAnotherNetwork: vi.fn(), } - mockGetLocalRobot.mockReturnValue({ + vi.mocked(getLocalRobot).mockReturnValue({ name: ROBOT_NAME, } as any) - when(mockGetNetworkInterfaces) + when(getNetworkInterfaces) .calledWith({} as State, ROBOT_NAME) - .mockReturnValue({ + .thenReturn({ wifi: initialMockWifi, ethernet: null, }) - mockNetworkDetailsModal.mockReturnValue(
mock NetworkDetailsModal
) - }) - afterEach(() => { - resetAllWhenMocks() - jest.clearAllMocks() + vi.mocked(NetworkDetailsModal).mockReturnValue( +
mock NetworkDetailsModal
+ ) }) it('should render text and button with icon when connected to a network', () => { diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/hooks.test.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/hooks.test.tsx index 2f9cacd205c..223c2d25457 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/hooks.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/__tests__/hooks.test.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { renderHook } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { Provider } from 'react-redux' import { createStore } from 'redux' @@ -12,17 +13,9 @@ import { useIsUnboxingFlowOngoing } from '../hooks' import type { Store } from 'redux' import type { State } from '../../../../redux/types' -jest.mock('../../../../redux/config') +vi.mock('../../../../redux/config') -const mockGetOnDeviceDisplaySettings = getOnDeviceDisplaySettings as jest.MockedFunction< - typeof getOnDeviceDisplaySettings -> - -const mockGetIsOnDevice = getIsOnDevice as jest.MockedFunction< - typeof getIsOnDevice -> - -const store: Store = createStore(jest.fn(), {}) +const store: Store = createStore(vi.fn(), {}) const mockDisplaySettings = { sleepMs: 604800000, @@ -35,16 +28,12 @@ describe('useIsUnboxingFlowOngoing', () => { let wrapper: React.FunctionComponent<{ children: React.ReactNode }> beforeEach(() => { wrapper = ({ children }) => {children} - mockGetOnDeviceDisplaySettings.mockReturnValue(mockDisplaySettings) - mockGetIsOnDevice.mockReturnValue(true) - }) - - afterEach(() => { - jest.resetAllMocks() + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue(mockDisplaySettings) + vi.mocked(getIsOnDevice).mockReturnValue(true) }) it('should return true if unfinishedUnboxingFlowRoute is /welcome', () => { - mockGetOnDeviceDisplaySettings.mockReturnValue({ + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue({ ...mockDisplaySettings, unfinishedUnboxingFlowRoute: '/welcome', }) @@ -55,7 +44,7 @@ describe('useIsUnboxingFlowOngoing', () => { }) it('should return true if unfinishedUnboxingFlowRoute is /emergency-stop', () => { - mockGetOnDeviceDisplaySettings.mockReturnValue({ + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue({ ...mockDisplaySettings, unfinishedUnboxingFlowRoute: '/emergency-stop', }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/DeviceReset.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/DeviceReset.test.tsx index 208f8da5ad3..2d6fd56f066 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/DeviceReset.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/DeviceReset.test.tsx @@ -1,8 +1,9 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { getResetConfigOptions, resetConfig } from '../../../redux/robot-admin' import { useDispatchApiRequest } from '../../../redux/robot-api' @@ -10,8 +11,8 @@ import { DeviceReset } from '../DeviceReset' import type { DispatchApiRequestType } from '../../../redux/robot-api' -jest.mock('../../../redux/robot-admin') -jest.mock('../../../redux/robot-api') +vi.mock('../../../redux/robot-admin') +vi.mock('../../../redux/robot-api') const mockResetConfigOptions = [ { @@ -46,14 +47,6 @@ const mockResetConfigOptions = [ }, ] -const mockGetResetConfigOptions = getResetConfigOptions as jest.MockedFunction< - typeof getResetConfigOptions -> -const mockUseDispatchApiRequest = useDispatchApiRequest as jest.MockedFunction< - typeof useDispatchApiRequest -> -const mockResetConfig = resetConfig as jest.MockedFunction - const render = (props: React.ComponentProps) => { return renderWithProviders( , @@ -69,36 +62,36 @@ describe('DeviceReset', () => { beforeEach(() => { props = { robotName: 'mockRobot', - setCurrentOption: jest.fn(), + setCurrentOption: vi.fn(), } - mockGetResetConfigOptions.mockReturnValue(mockResetConfigOptions) - dispatchApiRequest = jest.fn() - mockUseDispatchApiRequest.mockReturnValue([dispatchApiRequest, []]) - }) - - afterEach(() => { - jest.resetAllMocks() + vi.mocked(getResetConfigOptions).mockReturnValue(mockResetConfigOptions) + dispatchApiRequest = vi.fn() + vi.mocked(useDispatchApiRequest).mockReturnValue([dispatchApiRequest, []]) }) it('should render text and button', () => { - const [{ getByText, getByTestId, queryByText }] = render(props) - getByText('Clear pipette calibration') - getByText('Clear gripper calibration') - getByText('Clear module calibration') - getByText('Clear protocol run history') - getByText('Clears information about past runs of all protocols.') - getByText('Clear all stored data') - getByText( + render(props) + screen.getByText('Clear pipette calibration') + screen.getByText('Clear gripper calibration') + screen.getByText('Clear module calibration') + screen.getByText('Clear protocol run history') + screen.getByText('Clears information about past runs of all protocols.') + screen.getByText('Clear all stored data') + screen.getByText( 'Clears calibrations, protocols, and all settings except robot name and network settings.' ) - expect(queryByText('Clear the ssh authorized keys')).not.toBeInTheDocument() - expect(getByTestId('DeviceReset_clear_data_button')).toBeDisabled() + expect( + screen.queryByText('Clear the ssh authorized keys') + ).not.toBeInTheDocument() + expect(screen.getByTestId('DeviceReset_clear_data_button')).toBeDisabled() }) it('when tapping a option button, the clear button is enabled', () => { - const [{ getByText, getByTestId }] = render(props) - fireEvent.click(getByText('Clear pipette calibration')) - expect(getByTestId('DeviceReset_clear_data_button')).not.toBeDisabled() + render(props) + fireEvent.click(screen.getByText('Clear pipette calibration')) + expect( + screen.getByTestId('DeviceReset_clear_data_button') + ).not.toBeDisabled() }) it('when tapping a option button and tapping the clear button, a mock function is called', () => { @@ -107,16 +100,16 @@ describe('DeviceReset', () => { moduleCalibration: true, runsHistory: true, } - const [{ getByText }] = render(props) - fireEvent.click(getByText('Clear pipette calibration')) - fireEvent.click(getByText('Clear protocol run history')) - fireEvent.click(getByText('Clear module calibration')) - const clearButton = getByText('Clear data and restart robot') + render(props) + fireEvent.click(screen.getByText('Clear pipette calibration')) + fireEvent.click(screen.getByText('Clear protocol run history')) + fireEvent.click(screen.getByText('Clear module calibration')) + const clearButton = screen.getByText('Clear data and restart robot') fireEvent.click(clearButton) - getByText('Are you sure you want to reset your device?') - fireEvent.click(getByText('Confirm')) + screen.getByText('Are you sure you want to reset your device?') + fireEvent.click(screen.getByText('Confirm')) expect(dispatchApiRequest).toBeCalledWith( - mockResetConfig('mockRobot', clearMockResetOptions) + resetConfig('mockRobot', clearMockResetOptions) ) }) @@ -131,14 +124,14 @@ describe('DeviceReset', () => { deckConfiguration: true, } - const [{ getByText }] = render(props) - fireEvent.click(getByText('Clear all stored data')) - const clearButton = getByText('Clear data and restart robot') + render(props) + fireEvent.click(screen.getByText('Clear all stored data')) + const clearButton = screen.getByText('Clear data and restart robot') fireEvent.click(clearButton) - getByText('Are you sure you want to reset your device?') - fireEvent.click(getByText('Confirm')) + screen.getByText('Are you sure you want to reset your device?') + fireEvent.click(screen.getByText('Confirm')) expect(dispatchApiRequest).toBeCalledWith( - mockResetConfig('mockRobot', clearMockResetOptions) + resetConfig('mockRobot', clearMockResetOptions) ) }) @@ -153,17 +146,17 @@ describe('DeviceReset', () => { deckConfiguration: true, } - const [{ getByText }] = render(props) - fireEvent.click(getByText('Clear pipette calibration')) - fireEvent.click(getByText('Clear gripper calibration')) - fireEvent.click(getByText('Clear module calibration')) - fireEvent.click(getByText('Clear protocol run history')) - const clearButton = getByText('Clear data and restart robot') + render(props) + fireEvent.click(screen.getByText('Clear pipette calibration')) + fireEvent.click(screen.getByText('Clear gripper calibration')) + fireEvent.click(screen.getByText('Clear module calibration')) + fireEvent.click(screen.getByText('Clear protocol run history')) + const clearButton = screen.getByText('Clear data and restart robot') fireEvent.click(clearButton) - getByText('Are you sure you want to reset your device?') - fireEvent.click(getByText('Confirm')) + screen.getByText('Are you sure you want to reset your device?') + fireEvent.click(screen.getByText('Confirm')) expect(dispatchApiRequest).toBeCalledWith( - mockResetConfig('mockRobot', clearMockResetOptions) + resetConfig('mockRobot', clearMockResetOptions) ) }) @@ -178,15 +171,15 @@ describe('DeviceReset', () => { deckConfiguration: false, } - const [{ getByText }] = render(props) - fireEvent.click(getByText('Clear all stored data')) - fireEvent.click(getByText('Clear pipette calibration')) - const clearButton = getByText('Clear data and restart robot') + render(props) + fireEvent.click(screen.getByText('Clear all stored data')) + fireEvent.click(screen.getByText('Clear pipette calibration')) + const clearButton = screen.getByText('Clear data and restart robot') fireEvent.click(clearButton) - getByText('Are you sure you want to reset your device?') - fireEvent.click(getByText('Confirm')) + screen.getByText('Are you sure you want to reset your device?') + fireEvent.click(screen.getByText('Confirm')) expect(dispatchApiRequest).toBeCalledWith( - mockResetConfig('mockRobot', clearMockResetOptions) + resetConfig('mockRobot', clearMockResetOptions) ) }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/Privacy.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/Privacy.test.tsx index a2943526a76..cdb5653e002 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/Privacy.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/Privacy.test.tsx @@ -1,25 +1,17 @@ import * as React from 'react' import { fireEvent, screen } from '@testing-library/react' -import { renderWithProviders } from '@opentrons/components' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { toggleAnalyticsOptedIn } from '../../../redux/analytics' import { getRobotSettings, updateSetting } from '../../../redux/robot-settings' import { Privacy } from '../Privacy' -jest.mock('../../../redux/analytics') -jest.mock('../../../redux/robot-settings') - -const mockGetRobotSettings = getRobotSettings as jest.MockedFunction< - typeof getRobotSettings -> -const mockUpdateSetting = updateSetting as jest.MockedFunction< - typeof updateSetting -> -const mockToggleAnalyticsOptedIn = toggleAnalyticsOptedIn as jest.MockedFunction< - typeof toggleAnalyticsOptedIn -> +vi.mock('../../../redux/analytics') +vi.mock('../../../redux/robot-settings') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -32,13 +24,9 @@ describe('Privacy', () => { beforeEach(() => { props = { robotName: 'Otie', - setCurrentOption: jest.fn(), + setCurrentOption: vi.fn(), } - mockGetRobotSettings.mockReturnValue([]) - }) - - afterEach(() => { - jest.clearAllMocks() + vi.mocked(getRobotSettings).mockReturnValue([]) }) it('should render text and buttons', () => { @@ -56,16 +44,12 @@ describe('Privacy', () => { it('should toggle display usage sharing on click', () => { render(props) fireEvent.click(screen.getByText('Share display usage')) - expect(mockToggleAnalyticsOptedIn).toBeCalled() + expect(toggleAnalyticsOptedIn).toBeCalled() }) it('should toggle robot logs sharing on click', () => { render(props) fireEvent.click(screen.getByText('Share robot logs')) - expect(mockUpdateSetting).toBeCalledWith( - 'Otie', - 'disableLogAggregation', - true - ) + expect(updateSetting).toBeCalledWith('Otie', 'disableLogAggregation', true) }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersion.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersion.test.tsx index 9f3e62d5bb5..c7ddba35831 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersion.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersion.test.tsx @@ -1,21 +1,18 @@ import * as React from 'react' import { MemoryRouter } from 'react-router-dom' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { RobotSystemVersion } from '../RobotSystemVersion' import { RobotSystemVersionModal } from '../RobotSystemVersionModal' -jest.mock('../../../redux/shell') -jest.mock('../RobotSystemVersionModal') - -const mockBack = jest.fn() +vi.mock('../../../redux/shell') +vi.mock('../RobotSystemVersionModal') -const mockRobotSystemVersionModal = RobotSystemVersionModal as jest.MockedFunction< - typeof RobotSystemVersionModal -> +const mockBack = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders( @@ -38,23 +35,19 @@ describe('RobotSystemVersion', () => { setCurrentOption: mockBack, robotUpdateInfo: null, } - mockRobotSystemVersionModal.mockReturnValue( + vi.mocked(RobotSystemVersionModal).mockReturnValue(
mock RobotSystemVersionModal
) }) - afterEach(() => { - jest.clearAllMocks() - }) - it('should render text when there is no available update', () => { - const [{ getByText }] = render(props) - getByText('Robot System Version') - getByText( + render(props) + screen.getByText('Robot System Version') + screen.getByText( 'View latest release notes at https://github.com/Opentrons/opentrons/releases' ) - getByText('Current Version') - getByText('mock7.0.0') + screen.getByText('Current Version') + screen.getByText('mock7.0.0') }) it('should render text when there is available update', () => { @@ -67,9 +60,9 @@ describe('RobotSystemVersion', () => { releaseNotes: null, }, } - const [{ getByText }] = render(props) - getByText('Update available') - getByText('View update') + render(props) + screen.getByText('Update available') + screen.getByText('View update') }) it('should render mock robot system version modal when tapping view update', () => { @@ -77,14 +70,14 @@ describe('RobotSystemVersion', () => { ...props, isUpdateAvailable: true, } - const [{ getByText }] = render(props) - fireEvent.click(getByText('View update')) - getByText('mock RobotSystemVersionModal') + render(props) + fireEvent.click(screen.getByText('View update')) + screen.getByText('mock RobotSystemVersionModal') }) it('should call a mock function when tapping Back button', () => { - const [{ getByRole }] = render(props) - fireEvent.click(getByRole('button')) + render(props) + fireEvent.click(screen.getByRole('button')) expect(mockBack).toHaveBeenCalled() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersionModal.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersionModal.test.tsx index 5ef00b1ae84..6e6f4780e0d 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersionModal.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/RobotSystemVersionModal.test.tsx @@ -1,16 +1,18 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { RobotSystemVersionModal } from '../RobotSystemVersionModal' +import type * as Dom from 'react-router-dom' -const mockFn = jest.fn() -const mockPush = jest.fn() +const mockFn = vi.fn() +const mockPush = vi.fn() -jest.mock('react-router-dom', () => { - const reactRouterDom = jest.requireActual('react-router-dom') +vi.mock('react-router-dom', async importOriginal => { + const reactRouterDom = await importOriginal() return { ...reactRouterDom, useHistory: () => ({ push: mockPush } as any), @@ -36,27 +38,26 @@ describe('RobotSystemVersionModal', () => { } }) - afterEach(() => { - jest.clearAllMocks() - }) it('should render text and buttons', () => { - const [{ getByText }] = render(props) - getByText('Robot System Version mockVersion available') - getByText('Updating the robot software requires restarting the robot') - getByText('mockReleaseNote') - getByText('Not now') - getByText('Update') + render(props) + screen.getByText('Robot System Version mockVersion available') + screen.getByText( + 'Updating the robot software requires restarting the robot' + ) + screen.getByText('mockReleaseNote') + screen.getByText('Not now') + screen.getByText('Update') }) it('should close the modal when tapping remind me later', () => { - const [{ getByText }] = render(props) - fireEvent.click(getByText('Update')) + render(props) + fireEvent.click(screen.getByText('Update')) expect(mockPush).toHaveBeenCalledWith('/robot-settings/update-robot') }) it('should call the mock function when tapping update', () => { - const [{ getByText }] = render(props) - fireEvent.click(getByText('Not now')) + render(props) + fireEvent.click(screen.getByText('Not now')) expect(mockFn).toHaveBeenCalled() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/TextSize.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/TextSize.test.tsx index ffbefa6a97e..bbe8ccba0d7 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/TextSize.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/TextSize.test.tsx @@ -1,13 +1,12 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' - +import { renderWithProviders } from '../../../__testing-utils__' import { TextSize } from '../TextSize' -const mockFunc = jest.fn() +const mockFunc = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { i18nInstance: i18n, @@ -24,10 +23,10 @@ describe('TextSize', () => { }) it('should render text and buttons', () => { - const [{ getByTestId }] = render(props) - getByTestId('DisplayTextSize_back_button') - getByTestId('DisplayTextSize_decrease') - getByTestId('DisplayTextSize_increase') + render(props) + screen.getByTestId('DisplayTextSize_back_button') + screen.getByTestId('DisplayTextSize_decrease') + screen.getByTestId('DisplayTextSize_increase') }) // ToDo (kj:03/03/2023) These cases will be added when text size change method is decided @@ -35,8 +34,8 @@ describe('TextSize', () => { it.todo('should call mock function when tapping minus button') it('should call mock function when tapping back button', () => { - const [{ getByTestId }] = render(props) - const button = getByTestId('DisplayTextSize_back_button') + render(props) + const button = screen.getByTestId('DisplayTextSize_back_button') fireEvent.click(button) expect(mockFunc).toHaveBeenCalled() }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/TouchScreenSleep.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/TouchScreenSleep.test.tsx index 0913ae292f0..c27c2fd112b 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/TouchScreenSleep.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/TouchScreenSleep.test.tsx @@ -1,18 +1,15 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' import { updateConfigValue } from '../../../redux/config' import { TouchScreenSleep } from '../TouchScreenSleep' +import { renderWithProviders } from '../../../__testing-utils__' -jest.mock('../../../redux/config') +vi.mock('../../../redux/config') // Note (kj:06/28/2023) this line is to avoid causing errors for scrollIntoView -window.HTMLElement.prototype.scrollIntoView = jest.fn() -const mockUpdateConfigValue = updateConfigValue as jest.MockedFunction< - typeof updateConfigValue -> +window.HTMLElement.prototype.scrollIntoView = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -25,26 +22,26 @@ describe('TouchScreenSleep', () => { beforeEach(() => { props = { - setCurrentOption: jest.fn(), + setCurrentOption: vi.fn(), } }) it('should render text and buttons', () => { - const [{ getByText }] = render(props) - getByText('Touchscreen Sleep') - getByText('Never') - getByText('3 minutes') - getByText('5 minutes') - getByText('10 minutes') - getByText('15 minutes') - getByText('30 minutes') - getByText('1 hour') + render(props) + screen.getByText('Touchscreen Sleep') + screen.getByText('Never') + screen.getByText('3 minutes') + screen.getByText('5 minutes') + screen.getByText('10 minutes') + screen.getByText('15 minutes') + screen.getByText('30 minutes') + screen.getByText('1 hour') }) it('should call a mock function when changing the sleep option', () => { - const [{ getByText }] = render(props) - const button = getByText('10 minutes') + render(props) + const button = screen.getByText('10 minutes') fireEvent.click(button) - expect(mockUpdateConfigValue).toHaveBeenCalled() + expect(updateConfigValue).toHaveBeenCalled() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/TouchscreenBrightness.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/TouchscreenBrightness.test.tsx index db2c2ed64d8..dce842b1691 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/TouchscreenBrightness.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/TouchscreenBrightness.test.tsx @@ -1,25 +1,18 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' import { i18n } from '../../../i18n' import { getOnDeviceDisplaySettings, updateConfigValue, } from '../../../redux/config' +import { renderWithProviders } from '../../../__testing-utils__' import { TouchscreenBrightness } from '../TouchscreenBrightness' -jest.mock('../../../redux/config') - -const mockFunc = jest.fn() +vi.mock('../../../redux/config') -const mockGetOnDeviceDisplaySettings = getOnDeviceDisplaySettings as jest.MockedFunction< - typeof getOnDeviceDisplaySettings -> -const mockUpdateConfigValue = updateConfigValue as jest.MockedFunction< - typeof updateConfigValue -> +const mockFunc = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -34,57 +27,53 @@ describe('TouchscreenBrightness', () => { props = { setCurrentOption: mockFunc, } - mockGetOnDeviceDisplaySettings.mockReturnValue({ + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue({ sleepMS: 1, brightness: 4, textSize: 1, } as any) }) - afterEach(() => { - jest.clearAllMocks() - }) - it('should render text and buttons', () => { - const [{ getByText, getByTestId }] = render(props) - getByText('Touchscreen Brightness') - getByTestId('TouchscreenBrightness_decrease') - getByTestId('TouchscreenBrightness_increase') + render(props) + screen.getByText('Touchscreen Brightness') + screen.getByTestId('TouchscreenBrightness_decrease') + screen.getByTestId('TouchscreenBrightness_increase') }) it('plus button should be disabled when brightness max(1)', () => { - mockGetOnDeviceDisplaySettings.mockReturnValue({ + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue({ sleepMS: 1, brightness: 1, textSize: 1, } as any) - const [{ getByTestId }] = render(props) - const button = getByTestId('TouchscreenBrightness_increase') + render(props) + const button = screen.getByTestId('TouchscreenBrightness_increase') expect(button).toBeDisabled() }) it('plus button should be disabled when brightness min(6)', () => { - mockGetOnDeviceDisplaySettings.mockReturnValue({ + vi.mocked(getOnDeviceDisplaySettings).mockReturnValue({ sleepMS: 1, brightness: 6, textSize: 1, } as any) - const [{ getByTestId }] = render(props) - const button = getByTestId('TouchscreenBrightness_decrease') + render(props) + const button = screen.getByTestId('TouchscreenBrightness_decrease') expect(button).toBeDisabled() }) it('should call mock function when tapping plus button', () => { - const [{ getByTestId }] = render(props) - const button = getByTestId('TouchscreenBrightness_increase') + render(props) + const button = screen.getByTestId('TouchscreenBrightness_increase') fireEvent.click(button) - expect(mockUpdateConfigValue).toHaveBeenCalled() + expect(updateConfigValue).toHaveBeenCalled() }) it('should call mock function when tapping minus button', () => { - const [{ getByTestId }] = render(props) - const button = getByTestId('TouchscreenBrightness_decrease') + render(props) + const button = screen.getByTestId('TouchscreenBrightness_decrease') fireEvent.click(button) - expect(mockUpdateConfigValue).toHaveBeenCalled() + expect(updateConfigValue).toHaveBeenCalled() }) }) diff --git a/app/src/organisms/RobotSettingsDashboard/__tests__/UpdateChannel.test.tsx b/app/src/organisms/RobotSettingsDashboard/__tests__/UpdateChannel.test.tsx index 2e462834a41..7ed9db3fc0f 100644 --- a/app/src/organisms/RobotSettingsDashboard/__tests__/UpdateChannel.test.tsx +++ b/app/src/organisms/RobotSettingsDashboard/__tests__/UpdateChannel.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' import { @@ -9,10 +9,11 @@ import { getUpdateChannelOptions, updateConfigValue, } from '../../../redux/config' +import { renderWithProviders } from '../../../__testing-utils__' import { UpdateChannel } from '../UpdateChannel' -jest.mock('../../../redux/config') +vi.mock('../../../redux/config') const mockChannelOptions = [ { @@ -23,17 +24,7 @@ const mockChannelOptions = [ { label: 'Alpha', value: 'alpha' }, ] -const mockhandleBackPress = jest.fn() - -const mockGetChannelOptions = getUpdateChannelOptions as jest.MockedFunction< - typeof getUpdateChannelOptions -> -const mockUpdateConfigValue = updateConfigValue as jest.MockedFunction< - typeof updateConfigValue -> -const mockGetDevtoolsEnabled = getDevtoolsEnabled as jest.MockedFunction< - typeof getDevtoolsEnabled -> +const mockhandleBackPress = vi.fn() const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -47,48 +38,44 @@ describe('UpdateChannel', () => { props = { handleBackPress: mockhandleBackPress, } - mockGetChannelOptions.mockReturnValue(mockChannelOptions) - }) - - afterEach(() => { - jest.clearAllMocks() + vi.mocked(getUpdateChannelOptions).mockReturnValue(mockChannelOptions) }) it('should render text and buttons', () => { - const [{ getByText, queryByText }] = render(props) - getByText('Update Channel') - getByText( + render(props) + screen.getByText('Update Channel') + screen.getByText( 'Stable receives the latest stable releases. Beta allows you to try out new in-progress features before they launch in Stable channel, but they have not completed testing yet.' ) - getByText('Stable') - getByText('Beta') - expect(queryByText('Alpha')).not.toBeInTheDocument() + screen.getByText('Stable') + screen.getByText('Beta') + expect(screen.queryByText('Alpha')).not.toBeInTheDocument() expect( - queryByText( + screen.queryByText( 'Warning: alpha releases are feature-complete but may contain significant bugs.' ) ).not.toBeInTheDocument() }) it('should render alpha when dev tools on', () => { - mockGetDevtoolsEnabled.mockReturnValue(true) - const [{ getByText }] = render(props) - getByText('Alpha') - getByText( + vi.mocked(getDevtoolsEnabled).mockReturnValue(true) + render(props) + screen.getByText('Alpha') + screen.getByText( 'Warning: alpha releases are feature-complete but may contain significant bugs.' ) }) it('should call mock function when tapping a channel button', () => { - const [{ getByText }] = render(props) - const button = getByText('Stable') + render(props) + const button = screen.getByText('Stable') fireEvent.click(button) - expect(mockUpdateConfigValue).toHaveBeenCalled() + expect(updateConfigValue).toHaveBeenCalled() }) it('should call mock function when tapping back button', () => { - const [{ getByRole }] = render(props) - const button = getByRole('button') + render(props) + const button = screen.getByRole('button') fireEvent.click(button) expect(props.handleBackPress).toHaveBeenCalled() }) diff --git a/app/src/organisms/RunDetails/__tests__/ConfirmCancelModal.test.tsx b/app/src/organisms/RunDetails/__tests__/ConfirmCancelModal.test.tsx index ed73d19abe3..c1f6113ca83 100644 --- a/app/src/organisms/RunDetails/__tests__/ConfirmCancelModal.test.tsx +++ b/app/src/organisms/RunDetails/__tests__/ConfirmCancelModal.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' -import { renderWithProviders } from '@opentrons/components' -import { fireEvent } from '@testing-library/react' +import { when } from 'vitest-when' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { RUN_STATUS_RUNNING, RUN_STATUS_STOPPED, @@ -12,27 +13,22 @@ import { useStopRunMutation } from '@opentrons/react-api-client' import { i18n } from '../../../i18n' import { useTrackProtocolRunEvent } from '../../../organisms/Devices/hooks' import { useTrackEvent } from '../../../redux/analytics' +import { renderWithProviders } from '../../../__testing-utils__' import { ConfirmCancelModal } from '../../../organisms/RunDetails/ConfirmCancelModal' import { useRunStatus } from '../../RunTimeControl/hooks' +import type * as ApiClient from '@opentrons/react-api-client' -jest.mock('@opentrons/react-api-client') -jest.mock('../../RunTimeControl/hooks') -jest.mock('../../../organisms/Devices/hooks') -jest.mock('../../../redux/analytics') -jest.mock('../../../redux/config') - -const mockUseTrackProtocolRunEvent = useTrackProtocolRunEvent as jest.MockedFunction< - typeof useTrackProtocolRunEvent -> -const mockUseTrackEvent = useTrackEvent as jest.MockedFunction< - typeof useTrackEvent -> -const mockUseRunStatus = useRunStatus as jest.MockedFunction< - typeof useRunStatus -> -const mockUseStopRunMutation = useStopRunMutation as jest.MockedFunction< - typeof useStopRunMutation -> +vi.mock('@opentrons/react-api-client', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useStopRunMutation: vi.fn(), + } +}) +vi.mock('../../RunTimeControl/hooks') +vi.mock('../../../organisms/Devices/hooks') +vi.mock('../../../redux/analytics') +vi.mock('../../../redux/config') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -41,73 +37,68 @@ const render = (props: React.ComponentProps) => { } const RUN_ID = 'mockRunId' -let mockStopRun: jest.Mock -let mockTrackEvent: jest.Mock -let mockTrackProtocolRunEvent: jest.Mock +let mockStopRun: any +let mockTrackEvent: any +let mockTrackProtocolRunEvent: any describe('ConfirmCancelModal', () => { let props: React.ComponentProps beforeEach(() => { - mockTrackEvent = jest.fn() - mockStopRun = jest.fn((_runId, opts) => opts.onSuccess()) - mockTrackProtocolRunEvent = jest.fn( - () => new Promise(resolve => resolve({})) - ) - mockUseStopRunMutation.mockReturnValue({ stopRun: mockStopRun } as any) - mockUseRunStatus.mockReturnValue(RUN_STATUS_RUNNING) - mockUseTrackEvent.mockReturnValue(mockTrackEvent) - when(mockUseTrackProtocolRunEvent).calledWith(RUN_ID).mockReturnValue({ + mockTrackEvent = vi.fn() + mockStopRun = vi.fn((_runId, opts) => opts.onSuccess()) + mockTrackProtocolRunEvent = vi.fn(() => new Promise(resolve => resolve({}))) + vi.mocked(useStopRunMutation).mockReturnValue({ + stopRun: mockStopRun, + } as any) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_RUNNING) + vi.mocked(useTrackEvent).mockReturnValue(mockTrackEvent) + when(useTrackProtocolRunEvent).calledWith(RUN_ID).thenReturn({ trackProtocolRunEvent: mockTrackProtocolRunEvent, }) - props = { onClose: jest.fn(), runId: RUN_ID } - }) - - afterEach(() => { - resetAllWhenMocks() - jest.restoreAllMocks() + props = { onClose: vi.fn(), runId: RUN_ID } }) it('should render the correct title', () => { - const { getByText } = render(props) - getByText('Are you sure you want to cancel this run?') + render(props) + screen.getByText('Are you sure you want to cancel this run?') }) it('should render the correct body', () => { - const { getByText } = render(props) - getByText( + render(props) + screen.getByText( 'Doing so will terminate this run, drop any attached tips in the trash container and home your robot.' ) - getByText( + screen.getByText( 'Additionally, any hardware modules used within the protocol will remain active and maintain their current states until deactivated.' ) }) it('should render both buttons', () => { - const { getByRole } = render(props) + render(props) expect(props.onClose).not.toHaveBeenCalled() - getByRole('button', { name: 'Yes, cancel run' }) - getByRole('button', { name: 'No, go back' }) + screen.getByRole('button', { name: 'Yes, cancel run' }) + screen.getByRole('button', { name: 'No, go back' }) }) it('should call yes cancel run button', () => { - const { getByRole } = render(props) + render(props) expect(props.onClose).not.toHaveBeenCalled() - const closeButton = getByRole('button', { name: 'Yes, cancel run' }) + const closeButton = screen.getByRole('button', { name: 'Yes, cancel run' }) fireEvent.click(closeButton) expect(mockStopRun).toHaveBeenCalled() expect(mockTrackProtocolRunEvent).toHaveBeenCalled() }) it('should close modal if run status becomes stop-requested', () => { - mockUseRunStatus.mockReturnValue(RUN_STATUS_STOP_REQUESTED) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_STOP_REQUESTED) render(props) expect(props.onClose).toHaveBeenCalled() }) it('should close modal if run status becomes stopped', () => { - mockUseRunStatus.mockReturnValue(RUN_STATUS_STOPPED) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_STOPPED) render(props) expect(props.onClose).toHaveBeenCalled() }) it('should call No go back button', () => { - const { getByRole } = render(props) - const closeButton = getByRole('button', { name: 'No, go back' }) + render(props) + const closeButton = screen.getByRole('button', { name: 'No, go back' }) fireEvent.click(closeButton) expect(props.onClose).toHaveBeenCalled() }) diff --git a/app/src/organisms/RunProgressMeter/__tests__/InterventionTicks.test.tsx b/app/src/organisms/RunProgressMeter/__tests__/InterventionTicks.test.tsx index ab263fe3ea9..60f6fb9ecce 100644 --- a/app/src/organisms/RunProgressMeter/__tests__/InterventionTicks.test.tsx +++ b/app/src/organisms/RunProgressMeter/__tests__/InterventionTicks.test.tsx @@ -1,14 +1,13 @@ import * as React from 'react' -import { resetAllWhenMocks } from 'jest-when' -import { renderWithProviders } from '@opentrons/components' - +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { InterventionTicks } from '../InterventionTicks' import { Tick } from '../Tick' -jest.mock('../Tick') - -const mockTick = Tick as jest.MockedFunction +vi.mock('../Tick') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -19,22 +18,17 @@ const render = (props: React.ComponentProps) => { describe('InterventionTicks', () => { let props: React.ComponentProps beforeEach(() => { - mockTick.mockImplementation(({ index }) => ( + vi.mocked(Tick).mockImplementation(({ index }) => (
MOCK TICK at index: {index}
)) props = { analysisCommands: [], - makeHandleJumpToStep: jest.fn(), + makeHandleJumpToStep: vi.fn(), } }) - afterEach(() => { - resetAllWhenMocks() - jest.restoreAllMocks() - }) - it('should show one tick for waitForResume command', () => { - const { getByText } = render({ + render({ ...props, analysisCommands: [ { @@ -59,10 +53,10 @@ describe('InterventionTicks', () => { }, ], }) - expect(getByText('MOCK TICK at index: 1')).toBeTruthy() + expect(screen.getByText('MOCK TICK at index: 1')).toBeTruthy() }) it('should show tick only for moveLabware commands if strategy is moveManualWithPause', () => { - const { getByText } = render({ + render({ ...props, analysisCommands: [ { @@ -109,6 +103,6 @@ describe('InterventionTicks', () => { }, ], }) - expect(getByText('MOCK TICK at index: 2')).toBeTruthy() + expect(screen.getByText('MOCK TICK at index: 2')).toBeTruthy() }) }) diff --git a/app/src/organisms/RunProgressMeter/__tests__/RunProgressMeter.test.tsx b/app/src/organisms/RunProgressMeter/__tests__/RunProgressMeter.test.tsx index 64b82379ece..d4657b06174 100644 --- a/app/src/organisms/RunProgressMeter/__tests__/RunProgressMeter.test.tsx +++ b/app/src/organisms/RunProgressMeter/__tests__/RunProgressMeter.test.tsx @@ -1,6 +1,8 @@ import * as React from 'react' -import { when, resetAllWhenMocks } from 'jest-when' -import { renderWithProviders } from '@opentrons/components' +import { when } from 'vitest-when' +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { useAllCommandsQuery, useCommandQuery, @@ -30,41 +32,24 @@ import { } from '../../InterventionModal/__fixtures__' import { RunProgressMeter } from '..' import { useNotifyRunQuery } from '../../../resources/runs/useNotifyRunQuery' +import { renderWithProviders } from '../../../__testing-utils__' +import type * as ApiClient from '@opentrons/react-api-client' -jest.mock('@opentrons/react-api-client') -jest.mock('../../RunTimeControl/hooks') -jest.mock('../../LabwarePositionCheck/useMostRecentCompletedAnalysis') -jest.mock('../../../resources/runs/useNotifyLastRunCommandKey') -jest.mock('../../Devices/hooks') -jest.mock('../../../atoms/ProgressBar') -jest.mock('../../InterventionModal') -jest.mock('../../../resources/runs/useNotifyRunQuery') - -const mockUseRunStatus = useRunStatus as jest.MockedFunction< - typeof useRunStatus -> -const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< - typeof useNotifyRunQuery -> -const mockUseMostRecentCompletedAnalysis = useMostRecentCompletedAnalysis as jest.MockedFunction< - typeof useMostRecentCompletedAnalysis -> -const mockUseAllCommandsQuery = useAllCommandsQuery as jest.MockedFunction< - typeof useAllCommandsQuery -> -const mockUseCommandQuery = useCommandQuery as jest.MockedFunction< - typeof useCommandQuery -> -const mockUseDownloadRunLog = useDownloadRunLog as jest.MockedFunction< - typeof useDownloadRunLog -> -const mockUseNotifyLastRunCommandKey = useNotifyLastRunCommandKey as jest.MockedFunction< - typeof useNotifyLastRunCommandKey -> -const mockProgressBar = ProgressBar as jest.MockedFunction -const mockInterventionModal = InterventionModal as jest.MockedFunction< - typeof InterventionModal -> +vi.mock('@opentrons/react-api-client', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useAllCommandsQuery: vi.fn(), + useCommandQuery: vi.fn(), + } +}) +vi.mock('../../RunTimeControl/hooks') +vi.mock('../../LabwarePositionCheck/useMostRecentCompletedAnalysis') +vi.mock('../../../resources/runs/useNotifyLastRunCommandKey') +vi.mock('../../Devices/hooks') +vi.mock('../../../atoms/ProgressBar') +vi.mock('../../InterventionModal') +vi.mock('../../../resources/runs/useNotifyRunQuery') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -78,87 +63,83 @@ const ROBOT_NAME = 'otie' describe('RunProgressMeter', () => { let props: React.ComponentProps beforeEach(() => { - mockProgressBar.mockReturnValue(
MOCK PROGRESS BAR
) - mockInterventionModal.mockReturnValue(
MOCK INTERVENTION MODAL
) - mockUseRunStatus.mockReturnValue(RUN_STATUS_RUNNING) - when(mockUseMostRecentCompletedAnalysis) + vi.mocked(ProgressBar).mockReturnValue(
MOCK PROGRESS BAR
) + vi.mocked(InterventionModal).mockReturnValue( +
MOCK INTERVENTION MODAL
+ ) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_RUNNING) + when(useMostRecentCompletedAnalysis) .calledWith(NON_DETERMINISTIC_RUN_ID) - .mockReturnValue(null) - when(mockUseAllCommandsQuery) + .thenReturn(null) + when(useAllCommandsQuery) .calledWith(NON_DETERMINISTIC_RUN_ID, { cursor: null, pageLength: 1 }) - .mockReturnValue(mockUseAllCommandsResponseNonDeterministic) - when(mockUseCommandQuery) + .thenReturn(mockUseAllCommandsResponseNonDeterministic) + when(useCommandQuery) .calledWith(NON_DETERMINISTIC_RUN_ID, NON_DETERMINISTIC_COMMAND_KEY) - .mockReturnValue(mockUseCommandResultNonDeterministic) - mockUseDownloadRunLog.mockReturnValue({ - downloadRunLog: jest.fn(), + .thenReturn(mockUseCommandResultNonDeterministic) + vi.mocked(useDownloadRunLog).mockReturnValue({ + downloadRunLog: vi.fn(), isRunLogLoading: false, }) - when(mockUseNotifyLastRunCommandKey) + when(useNotifyLastRunCommandKey) .calledWith(NON_DETERMINISTIC_RUN_ID, { refetchInterval: 1000 }) - .mockReturnValue(NON_DETERMINISTIC_COMMAND_KEY) - mockUseNotifyRunQuery.mockReturnValue({ data: null } as any) + .thenReturn(NON_DETERMINISTIC_COMMAND_KEY) + + vi.mocked(useNotifyRunQuery).mockReturnValue({ data: null } as any) props = { runId: NON_DETERMINISTIC_RUN_ID, robotName: ROBOT_NAME, - makeHandleJumpToStep: jest.fn(), - resumeRunHandler: jest.fn(), + makeHandleJumpToStep: vi.fn(), + resumeRunHandler: vi.fn(), } }) - afterEach(() => { - resetAllWhenMocks() - jest.restoreAllMocks() - }) - it('should show only the total count of commands in run and not show the meter when protocol is non-deterministic', () => { - mockUseCommandQuery.mockReturnValue({ data: null } as any) - const { getByText, queryByText } = render(props) - expect(getByText('Current Step 42/?')).toBeTruthy() - expect(queryByText('MOCK PROGRESS BAR')).toBeFalsy() + vi.mocked(useCommandQuery).mockReturnValue({ data: null } as any) + render(props) + expect(screen.getByText('Current Step 42/?')).toBeTruthy() + expect(screen.queryByText('MOCK PROGRESS BAR')).toBeFalsy() }) it('should give the correct info when run status is idle', () => { - mockUseCommandQuery.mockReturnValue({ data: null } as any) - mockUseRunStatus.mockReturnValue(RUN_STATUS_IDLE) - const { getByText } = render(props) - getByText('Current Step:') - getByText('Not started yet') - getByText('Download run log') + vi.mocked(useCommandQuery).mockReturnValue({ data: null } as any) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_IDLE) + render(props) + screen.getByText('Current Step:') + screen.getByText('Not started yet') + screen.getByText('Download run log') }) - it('should render an intervention modal when lastRunCommand is a pause command', async () => { - mockUseAllCommandsQuery.mockReturnValue({ + it('should render an intervention modal when lastRunCommand is a pause command', () => { + vi.mocked(useAllCommandsQuery).mockReturnValue({ data: { data: [mockPauseCommandWithStartTime], meta: { totalLength: 1 } }, } as any) - mockUseNotifyRunQuery.mockReturnValue({ + vi.mocked(useNotifyRunQuery).mockReturnValue({ data: { data: { labware: [] } }, } as any) - mockUseCommandQuery.mockReturnValue({ data: null } as any) - mockUseMostRecentCompletedAnalysis.mockReturnValue({} as any) - const { findByText } = render(props) - expect(await findByText('MOCK INTERVENTION MODAL')).toBeTruthy() + vi.mocked(useCommandQuery).mockReturnValue({ data: null } as any) + vi.mocked(useMostRecentCompletedAnalysis).mockReturnValue({} as any) + render(props) }) - it('should render an intervention modal when lastRunCommand is a move labware command', async () => { - mockUseAllCommandsQuery.mockReturnValue({ + it('should render an intervention modal when lastRunCommand is a move labware command', () => { + vi.mocked(useAllCommandsQuery).mockReturnValue({ data: { data: [mockMoveLabwareCommandFromSlot], meta: { totalLength: 1 }, }, } as any) - mockUseNotifyRunQuery.mockReturnValue({ + vi.mocked(useNotifyRunQuery).mockReturnValue({ data: { data: mockRunData }, } as any) - mockUseCommandQuery.mockReturnValue({ data: null } as any) - mockUseMostRecentCompletedAnalysis.mockReturnValue({} as any) - const { findByText } = render(props) - expect(await findByText('MOCK INTERVENTION MODAL')).toBeTruthy() + vi.mocked(useCommandQuery).mockReturnValue({ data: null } as any) + vi.mocked(useMostRecentCompletedAnalysis).mockReturnValue({} as any) + render(props) }) it('should render the correct run status when run status is completed', () => { - mockUseCommandQuery.mockReturnValue({ data: null } as any) - mockUseRunStatus.mockReturnValue(RUN_STATUS_SUCCEEDED) - const { getByText } = render(props) - getByText('Final Step 42/?') + vi.mocked(useCommandQuery).mockReturnValue({ data: null } as any) + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_SUCCEEDED) + render(props) + screen.getByText('Final Step 42/?') }) }) diff --git a/app/src/organisms/RunTimeControl/__tests__/formatInterval.test.tsx b/app/src/organisms/RunTimeControl/__tests__/formatInterval.test.tsx index 24ac007d2a8..b5aa8543e0e 100644 --- a/app/src/organisms/RunTimeControl/__tests__/formatInterval.test.tsx +++ b/app/src/organisms/RunTimeControl/__tests__/formatInterval.test.tsx @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest' import { formatDuration, formatInterval } from '../utils' describe('formatInterval', () => { diff --git a/app/src/organisms/RunTimeControl/__tests__/hooks.test.tsx b/app/src/organisms/RunTimeControl/__tests__/hooks.test.tsx index dc927196c68..79a631aef6e 100644 --- a/app/src/organisms/RunTimeControl/__tests__/hooks.test.tsx +++ b/app/src/organisms/RunTimeControl/__tests__/hooks.test.tsx @@ -1,6 +1,8 @@ -import { when, resetAllWhenMocks } from 'jest-when' +import { when } from 'vitest-when' import { UseQueryResult } from 'react-query' import { act, renderHook } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { useRunActionMutations } from '@opentrons/react-api-client' import { @@ -30,48 +32,37 @@ import { } from '../__fixtures__' import type { Run } from '@opentrons/api-client' +import type * as ApiClient from '@opentrons/react-api-client' + +vi.mock('@opentrons/react-api-client', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useRunActionMutations: vi.fn(), + } +}) -jest.mock('@opentrons/react-api-client') -jest.mock('../../ProtocolUpload/hooks') -jest.mock('../../../resources/runs/useNotifyRunQuery') - -const mockUseCloneRun = useCloneRun as jest.MockedFunction -const mockUseRunCommands = useRunCommands as jest.MockedFunction< - typeof useRunCommands -> -const mockUseCurrentRunId = useCurrentRunId as jest.MockedFunction< - typeof useCurrentRunId -> -const mockUseRunActionMutations = useRunActionMutations as jest.MockedFunction< - typeof useRunActionMutations -> -const mockUseNotifyRunQuery = useNotifyRunQuery as jest.MockedFunction< - typeof useNotifyRunQuery -> +vi.mock('../../ProtocolUpload/hooks') +vi.mock('../../../resources/runs/useNotifyRunQuery') describe('useRunControls hook', () => { - afterEach(() => { - resetAllWhenMocks() - }) it('returns run controls hooks', () => { - const mockPlayRun = jest.fn() - const mockPauseRun = jest.fn() - const mockStopRun = jest.fn() - const mockCloneRun = jest.fn() - - when(mockUseRunActionMutations) - .calledWith(mockPausedRun.id) - .mockReturnValue({ - playRun: mockPlayRun, - pauseRun: mockPauseRun, - stopRun: mockStopRun, - isPlayRunActionLoading: false, - isPauseRunActionLoading: false, - isStopRunActionLoading: false, - }) - when(mockUseCloneRun) + const mockPlayRun = vi.fn() + const mockPauseRun = vi.fn() + const mockStopRun = vi.fn() + const mockCloneRun = vi.fn() + + when(useRunActionMutations).calledWith(mockPausedRun.id).thenReturn({ + playRun: mockPlayRun, + pauseRun: mockPauseRun, + stopRun: mockStopRun, + isPlayRunActionLoading: false, + isPauseRunActionLoading: false, + isStopRunActionLoading: false, + }) + when(useCloneRun) .calledWith(mockPausedRun.id, undefined) - .mockReturnValue({ cloneRun: mockCloneRun, isLoading: false }) + .thenReturn({ cloneRun: mockCloneRun, isLoading: false }) const { result } = renderHook(() => useRunControls(mockPausedRun.id)) @@ -87,14 +78,10 @@ describe('useRunControls hook', () => { }) describe('useRunStatus hook', () => { - afterEach(() => { - resetAllWhenMocks() - }) - it('returns the run status of the run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun }, } as unknown) as UseQueryResult) @@ -103,9 +90,9 @@ describe('useRunStatus hook', () => { }) it('returns a "idle" run status if idle and run unstarted', () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockIdleUnstartedRun }, } as unknown) as UseQueryResult) @@ -114,9 +101,9 @@ describe('useRunStatus hook', () => { }) it('returns a "running" run status if idle and run started', () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockIdleStartedRun }, } as unknown) as UseQueryResult) @@ -127,16 +114,13 @@ describe('useRunStatus hook', () => { describe('useCurrentRunStatus hook', () => { beforeEach(() => { - when(mockUseCurrentRunId).calledWith().mockReturnValue(RUN_ID_2) - }) - afterEach(() => { - resetAllWhenMocks() + when(useCurrentRunId).calledWith().thenReturn(RUN_ID_2) }) it('returns the run status of the current run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun }, } as unknown) as UseQueryResult) @@ -145,9 +129,9 @@ describe('useCurrentRunStatus hook', () => { }) it('returns a "idle" run status if idle and run unstarted', () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockIdleUnstartedRun }, } as unknown) as UseQueryResult) @@ -156,9 +140,9 @@ describe('useCurrentRunStatus hook', () => { }) it('returns a "running" run status if idle and run started', () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockIdleStartedRun }, } as unknown) as UseQueryResult) @@ -169,18 +153,15 @@ describe('useCurrentRunStatus hook', () => { describe('useRunTimestamps hook', () => { beforeEach(() => { - when(mockUseRunCommands) + when(useRunCommands) .calledWith(RUN_ID_2, { cursor: null, pageLength: 1 }, expect.any(Object)) - .mockReturnValue([mockCommand.data as any]) - }) - afterEach(() => { - resetAllWhenMocks() + .thenReturn([mockCommand.data as any]) }) it('returns the start time of the current run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun }, } as unknown) as UseQueryResult) @@ -189,9 +170,9 @@ describe('useRunTimestamps hook', () => { }) it('returns null when pause is not the last action', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun }, } as unknown) as UseQueryResult) @@ -200,9 +181,9 @@ describe('useRunTimestamps hook', () => { }) it('returns the pause time of the current run when pause is the last action', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockPausedRun }, } as unknown) as UseQueryResult) @@ -211,9 +192,9 @@ describe('useRunTimestamps hook', () => { }) it('returns stopped time null when stop is not the last action', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun }, } as unknown) as UseQueryResult) @@ -222,9 +203,9 @@ describe('useRunTimestamps hook', () => { }) it('returns the stop time of the current run when stop is the last action', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockStoppedRun }, } as unknown) as UseQueryResult) @@ -233,9 +214,9 @@ describe('useRunTimestamps hook', () => { }) it('returns the complete time of a successful current run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockSucceededRun }, } as unknown) as UseQueryResult) @@ -244,9 +225,9 @@ describe('useRunTimestamps hook', () => { }) it('returns the complete time of a failed current run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockFailedRun }, } as unknown) as UseQueryResult) @@ -255,9 +236,9 @@ describe('useRunTimestamps hook', () => { }) it('returns the complete time of a stopped current run', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockStoppedRun }, } as unknown) as UseQueryResult) @@ -267,10 +248,6 @@ describe('useRunTimestamps hook', () => { }) describe('useRunErrors hook', () => { - afterEach(() => { - resetAllWhenMocks() - }) - it('returns errors if present', async () => { const fixtureErrors = [ { @@ -288,9 +265,9 @@ describe('useRunErrors hook', () => { "ErrorResponse [line 40]: /dev/ot_module_thermocycler0: 'Received error response 'Error:Plate temperature is not uniform. T1: 35.1097\tT2: 35.8139\tT3: 35.6139\tT4: 35.9809\tT5: 35.4347\tT6: 35.5264\tT.Lid: 20.2052\tT.sink: 19.8993\tT_error: 0.0000\t\r\nLid:open'", }, ] - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: { ...mockRunningRun, @@ -304,9 +281,9 @@ describe('useRunErrors hook', () => { }) it('returns no errors if no errors present', async () => { - when(mockUseNotifyRunQuery) + when(useNotifyRunQuery) .calledWith(RUN_ID_2, expect.any(Object)) - .mockReturnValue(({ + .thenReturn(({ data: { data: mockRunningRun, errors: undefined, diff --git a/app/src/organisms/SendProtocolToFlexSlideout/__tests__/SendProtocolToFlexSlideout.test.tsx b/app/src/organisms/SendProtocolToFlexSlideout/__tests__/SendProtocolToFlexSlideout.test.tsx index 77ffa5426b6..531e9763025 100644 --- a/app/src/organisms/SendProtocolToFlexSlideout/__tests__/SendProtocolToFlexSlideout.test.tsx +++ b/app/src/organisms/SendProtocolToFlexSlideout/__tests__/SendProtocolToFlexSlideout.test.tsx @@ -1,8 +1,9 @@ import * as React from 'react' -import { renderWithProviders } from '@opentrons/components' import { fireEvent, screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { StaticRouter } from 'react-router-dom' -import { when, resetAllWhenMocks } from 'jest-when' +import { when } from 'vitest-when' import { mockOT3HealthResponse, @@ -22,6 +23,8 @@ import { ROBOT_MODEL_OT2, ROBOT_MODEL_OT3, } from '../../../redux/discovery' +import { getValidCustomLabwareFiles } from '../../../redux/custom-labware' +import { renderWithProviders } from '../../../__testing-utils__' import { getRobotUpdateDisplayInfo } from '../../../redux/robot-update' import { mockConnectableRobot, @@ -34,50 +37,22 @@ import { storedProtocolData as storedProtocolDataFixture } from '../../../redux/ import { SendProtocolToFlexSlideout } from '..' import { useNotifyAllRunsQuery } from '../../../resources/runs/useNotifyAllRunsQuery' -import type { State } from '../../../redux/types' -import { getValidCustomLabwareFiles } from '../../../redux/custom-labware' - -jest.mock('@opentrons/react-api-client') -jest.mock('../../../organisms/ToasterOven') -jest.mock('../../../redux/robot-update') -jest.mock('../../../redux/discovery') -jest.mock('../../../redux/networking') -jest.mock('../../../redux/custom-labware') -jest.mock('../../../redux/protocol-storage/selectors') -jest.mock('../../../resources/runs/useNotifyAllRunsQuery') +import type * as ApiClient from '@opentrons/react-api-client' -const mockGetBuildrootUpdateDisplayInfo = getRobotUpdateDisplayInfo as jest.MockedFunction< - typeof getRobotUpdateDisplayInfo -> -const mockGetConnectableRobots = getConnectableRobots as jest.MockedFunction< - typeof getConnectableRobots -> -const mockGetReachableRobots = getReachableRobots as jest.MockedFunction< - typeof getReachableRobots -> -const mockGetUnreachableRobots = getUnreachableRobots as jest.MockedFunction< - typeof getUnreachableRobots -> -const mockGetScanning = getScanning as jest.MockedFunction -const mockStartDiscovery = startDiscovery as jest.MockedFunction< - typeof startDiscovery -> -const mockUseToaster = useToaster as jest.MockedFunction -const mockUseNotifyAllRunsQuery = useNotifyAllRunsQuery as jest.MockedFunction< - typeof useNotifyAllRunsQuery -> -const mockUseCreateProtocolMutation = useCreateProtocolMutation as jest.MockedFunction< - typeof useCreateProtocolMutation -> -const mockGetIsProtocolAnalysisInProgress = getIsProtocolAnalysisInProgress as jest.MockedFunction< - typeof getIsProtocolAnalysisInProgress -> -const mockGetNetworkInterfaces = getNetworkInterfaces as jest.MockedFunction< - typeof getNetworkInterfaces -> -const mockGetValidCustomLabwareFiles = getValidCustomLabwareFiles as jest.MockedFunction< - typeof getValidCustomLabwareFiles -> +vi.mock('@opentrons/react-api-client', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useCreateProtocolMutation: vi.fn(), + } +}) +vi.mock('../../../organisms/ToasterOven') +vi.mock('../../../redux/robot-update') +vi.mock('../../../redux/discovery') +vi.mock('../../../redux/networking') +vi.mock('../../../redux/custom-labware') +vi.mock('../../../redux/protocol-storage/selectors') +vi.mock('../../../resources/runs/useNotifyAllRunsQuery') const render = ( props: React.ComponentProps @@ -111,58 +86,55 @@ const mockUnreachableOT3 = { robotModel: ROBOT_MODEL_OT3, } -const mockMakeSnackbar = jest.fn() -const mockMakeToast = jest.fn() -const mockEatToast = jest.fn() -const mockMutateAsync = jest.fn() +const mockMakeSnackbar = vi.fn() +const mockMakeToast = vi.fn() +const mockEatToast = vi.fn() +const mockMutateAsync = vi.fn() const mockCustomLabwareFile: File = { path: 'fake_custom_labware_path' } as any describe('SendProtocolToFlexSlideout', () => { beforeEach(() => { - mockGetBuildrootUpdateDisplayInfo.mockReturnValue({ + vi.mocked(getRobotUpdateDisplayInfo).mockReturnValue({ autoUpdateAction: '', autoUpdateDisabledReason: null, updateFromFileDisabledReason: null, }) - mockGetConnectableRobots.mockReturnValue([mockConnectableOT3]) - mockGetUnreachableRobots.mockReturnValue([mockUnreachableOT3]) - mockGetReachableRobots.mockReturnValue([mockReachableOT3]) - mockGetScanning.mockReturnValue(false) - mockStartDiscovery.mockReturnValue({ type: 'mockStartDiscovery' } as any) - mockGetIsProtocolAnalysisInProgress.mockReturnValue(false) - when(mockUseToaster).calledWith().mockReturnValue({ + vi.mocked(getConnectableRobots).mockReturnValue([mockConnectableOT3]) + vi.mocked(getUnreachableRobots).mockReturnValue([mockUnreachableOT3]) + vi.mocked(getReachableRobots).mockReturnValue([mockReachableOT3]) + vi.mocked(getScanning).mockReturnValue(false) + vi.mocked(startDiscovery).mockReturnValue({ + type: 'mockStartDiscovery', + } as any) + vi.mocked(getIsProtocolAnalysisInProgress).mockReturnValue(false) + vi.mocked(useToaster).mockReturnValue({ makeSnackbar: mockMakeSnackbar, makeToast: mockMakeToast, eatToast: mockEatToast, }) - when(mockUseNotifyAllRunsQuery) - .calledWith(expect.any(Object), expect.any(Object), expect.any(Object)) - .mockReturnValue( - mockSuccessQueryResults({ - data: [], - links: {}, - }) - ) - when(mockUseCreateProtocolMutation) - .calledWith(expect.any(Object), expect.any(Object)) - .mockReturnValue({ mutateAsync: mockMutateAsync } as any) - when(mockMutateAsync).mockImplementation(() => Promise.resolve()) - when(mockGetNetworkInterfaces) - .calledWith({} as State, expect.any(String)) - .mockReturnValue({ wifi: null, ethernet: null }) - when(mockGetValidCustomLabwareFiles) - .calledWith({} as State) - .mockReturnValue([mockCustomLabwareFile]) - }) - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() + vi.mocked(useNotifyAllRunsQuery).mockReturnValue( + mockSuccessQueryResults({ + data: [], + links: {}, + }) + ) + vi.mocked(useCreateProtocolMutation).mockReturnValue({ + mutateAsync: mockMutateAsync, + } as any) + vi.mocked(mockMutateAsync).mockImplementation(() => Promise.resolve()) + vi.mocked(getNetworkInterfaces).mockReturnValue({ + wifi: null, + ethernet: null, + }) + vi.mocked(getValidCustomLabwareFiles).mockReturnValue([ + mockCustomLabwareFile, + ]) }) it('renders slideout title and button', () => { render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) screen.getByText('Send protocol to Opentrons Flex') @@ -172,38 +144,34 @@ describe('SendProtocolToFlexSlideout', () => { it('renders an available robot option for every connectable OT-3, and link for other robots', () => { render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) - mockGetUnreachableRobots.mockReturnValue([ + vi.mocked(getUnreachableRobots).mockReturnValue([ { ...mockUnreachableRobot, robotModel: 'OT-3 Standard' }, ]) - mockGetReachableRobots.mockReturnValue([ + vi.mocked(getReachableRobots).mockReturnValue([ { ...mockReachableRobot, robotModel: 'OT-3 Standard' }, ]) screen.getByText('opentrons-robot-name') screen.getByText('2 unavailable robots are not listed.') }) it('does render a robot option for a busy OT-3', () => { - when(mockUseNotifyAllRunsQuery) - .calledWith(expect.any(Object), expect.any(Object), { - hostname: mockConnectableOT3.ip, + vi.mocked(useNotifyAllRunsQuery).mockReturnValue( + mockSuccessQueryResults({ + data: [], + links: { current: { href: 'a current run' } }, }) - .mockReturnValue( - mockSuccessQueryResults({ - data: [], - links: { current: { href: 'a current run' } }, - }) - ) + ) render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) expect(screen.getByText('opentrons-robot-name')).toBeInTheDocument() }) it('does not render an available robot option for a connectable OT-2', () => { - mockGetConnectableRobots.mockReturnValue([ + vi.mocked(getConnectableRobots).mockReturnValue([ mockConnectableOT3, { ...mockConnectableRobot, @@ -213,16 +181,16 @@ describe('SendProtocolToFlexSlideout', () => { ]) render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) expect(screen.queryByText('ot-2-robot-name')).not.toBeInTheDocument() }) it('if scanning, show robots, but do not show link to other devices', () => { - mockGetScanning.mockReturnValue(true) + vi.mocked(getScanning).mockReturnValue(true) render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) screen.getByText('opentrons-robot-name') @@ -233,22 +201,22 @@ describe('SendProtocolToFlexSlideout', () => { it('if not scanning, show refresh button, start discovery if clicked', () => { const { dispatch } = render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, })[1] const refresh = screen.getByRole('button', { name: 'refresh' }) fireEvent.click(refresh) - expect(mockStartDiscovery).toHaveBeenCalled() + expect(startDiscovery).toHaveBeenCalled() expect(dispatch).toHaveBeenCalledWith({ type: 'mockStartDiscovery' }) }) it('defaults to first available robot and allows an available robot to be selected', () => { - mockGetConnectableRobots.mockReturnValue([ + vi.mocked(getConnectableRobots).mockReturnValue([ { ...mockConnectableOT3, name: 'otherRobot', ip: 'otherIp' }, mockConnectableOT3, ]) render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) const proceedButton = screen.getByRole('button', { name: 'Send' }) @@ -266,16 +234,14 @@ describe('SendProtocolToFlexSlideout', () => { }) }) it('if selected robot is on a different version of the software than the app, disable CTA and show link to device details in options', () => { - when(mockGetBuildrootUpdateDisplayInfo) - .calledWith(({} as any) as State, 'opentrons-robot-name') - .mockReturnValue({ - autoUpdateAction: 'upgrade', - autoUpdateDisabledReason: null, - updateFromFileDisabledReason: null, - }) + vi.mocked(getRobotUpdateDisplayInfo).mockReturnValue({ + autoUpdateAction: 'upgrade', + autoUpdateDisabledReason: null, + updateFromFileDisabledReason: null, + }) render({ storedProtocolData: storedProtocolDataFixture, - onCloseClick: jest.fn(), + onCloseClick: vi.fn(), isExpanded: true, }) const proceedButton = screen.getByRole('button', { name: 'Send' }) diff --git a/app/src/organisms/TakeoverModal/__tests__/MaintenanceRunTakeover.test.tsx b/app/src/organisms/TakeoverModal/__tests__/MaintenanceRunTakeover.test.tsx index 0824ec6f82e..f4416fa8a9f 100644 --- a/app/src/organisms/TakeoverModal/__tests__/MaintenanceRunTakeover.test.tsx +++ b/app/src/organisms/TakeoverModal/__tests__/MaintenanceRunTakeover.test.tsx @@ -1,17 +1,17 @@ import * as React from 'react' import { screen } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' - +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { useMaintenanceRunTakeover } from '../useMaintenanceRunTakeover' import { MaintenanceRunTakeover } from '../MaintenanceRunTakeover' import { useNotifyCurrentMaintenanceRun } from '../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun' import type { MaintenanceRunStatus } from '../MaintenanceRunStatusProvider' -jest.mock('../useMaintenanceRunTakeover') -jest.mock('../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun') +vi.mock('../useMaintenanceRunTakeover') +vi.mock('../../../resources/maintenance_runs/useNotifyCurrentMaintenanceRun') const MOCK_MAINTENANCE_RUN: MaintenanceRunStatus = { getRunIds: () => ({ @@ -21,13 +21,6 @@ const MOCK_MAINTENANCE_RUN: MaintenanceRunStatus = { setOddRunIds: () => null, } -const mockUseMaintenanceRunTakeover = useMaintenanceRunTakeover as jest.MockedFunction< - typeof useMaintenanceRunTakeover -> -const useMockNotifyCurrentMaintenanceRun = useNotifyCurrentMaintenanceRun as jest.MockedFunction< - typeof useNotifyCurrentMaintenanceRun -> - const render = (props: React.ComponentProps) => { return renderWithProviders(, { i18nInstance: i18n, @@ -40,8 +33,8 @@ describe('MaintenanceRunTakeover', () => { beforeEach(() => { props = { children: [testComponent] } - mockUseMaintenanceRunTakeover.mockReturnValue(MOCK_MAINTENANCE_RUN) - useMockNotifyCurrentMaintenanceRun.mockReturnValue({ + vi.mocked(useMaintenanceRunTakeover).mockReturnValue(MOCK_MAINTENANCE_RUN) + vi.mocked(useNotifyCurrentMaintenanceRun).mockReturnValue({ data: { data: { id: 'test', @@ -70,7 +63,7 @@ describe('MaintenanceRunTakeover', () => { }), } - mockUseMaintenanceRunTakeover.mockReturnValue(MOCK_ODD_RUN) + vi.mocked(useMaintenanceRunTakeover).mockReturnValue(MOCK_ODD_RUN) render(props) expect(screen.queryByText('Robot is busy')).not.toBeInTheDocument() @@ -85,9 +78,8 @@ describe('MaintenanceRunTakeover', () => { }), } - mockUseMaintenanceRunTakeover.mockReturnValue(MOCK_DESKTOP_RUN) + vi.mocked(useMaintenanceRunTakeover).mockReturnValue(MOCK_DESKTOP_RUN) render(props) - screen.getByText('Robot is busy') }) }) diff --git a/app/src/organisms/TakeoverModal/__tests__/TakeoverModal.test.tsx b/app/src/organisms/TakeoverModal/__tests__/TakeoverModal.test.tsx index af4b72ffef1..0e09b3096a3 100644 --- a/app/src/organisms/TakeoverModal/__tests__/TakeoverModal.test.tsx +++ b/app/src/organisms/TakeoverModal/__tests__/TakeoverModal.test.tsx @@ -1,7 +1,9 @@ import * as React from 'react' import { fireEvent, screen } from '@testing-library/react' -import { renderWithProviders } from '@opentrons/components' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { TakeoverModal } from '../TakeoverModal' const render = (props: React.ComponentProps) => { @@ -15,8 +17,8 @@ describe('TakeoverModal', () => { beforeEach(() => { props = { showConfirmTerminateModal: false, - setShowConfirmTerminateModal: jest.fn(), - confirmTerminate: jest.fn(), + setShowConfirmTerminateModal: vi.fn(), + confirmTerminate: vi.fn(), terminateInProgress: false, } }) diff --git a/app/src/organisms/UpdateAppModal/__tests__/UpdateAppModal.test.tsx b/app/src/organisms/UpdateAppModal/__tests__/UpdateAppModal.test.tsx index 2e38c579982..933f4c49e69 100644 --- a/app/src/organisms/UpdateAppModal/__tests__/UpdateAppModal.test.tsx +++ b/app/src/organisms/UpdateAppModal/__tests__/UpdateAppModal.test.tsx @@ -1,36 +1,40 @@ import * as React from 'react' -import { when } from 'jest-when' import { screen, fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' import * as Shell from '../../../redux/shell' +import { renderWithProviders } from '../../../__testing-utils__' import { useRemoveActiveAppUpdateToast } from '../../Alerts' import { UpdateAppModal, UpdateAppModalProps, RELEASE_NOTES_URL_BASE } from '..' import type { State } from '../../../redux/types' import type { ShellUpdateState } from '../../../redux/shell/types' +import type * as ShellState from '../../../redux/shell' +import type * as Dom from 'react-router-dom' + +vi.mock('../../../redux/shell/update', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + getShellUpdateState: vi.fn(), + } +}) -jest.mock('../../../redux/shell/update', () => ({ - ...jest.requireActual<{}>('../../../redux/shell/update'), - getShellUpdateState: jest.fn(), -})) +vi.mock('react-router-dom', async importOriginal => { + const actual = await importOriginal() + return { + ...actual, + useHistory: () => ({ + push: vi.fn(), + }), + } +}) -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useHistory: () => ({ - push: jest.fn(), - }), -})) -jest.mock('../../Alerts') +vi.mock('../../Alerts') -const getShellUpdateState = Shell.getShellUpdateState as jest.MockedFunction< - typeof Shell.getShellUpdateState -> -const mockUseRemoveActiveAppUpdateToast = useRemoveActiveAppUpdateToast as jest.MockedFunction< - typeof useRemoveActiveAppUpdateToast -> +const getShellUpdateState = Shell.getShellUpdateState const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -46,9 +50,9 @@ describe('UpdateAppModal', () => { beforeEach(() => { props = { - closeModal: jest.fn(), + closeModal: vi.fn(), } as UpdateAppModalProps - getShellUpdateState.mockImplementation((state: State) => { + vi.mocked(getShellUpdateState).mockImplementation((state: State) => { return { downloading: false, available: true, @@ -61,15 +65,11 @@ describe('UpdateAppModal', () => { }, } as ShellUpdateState }) - when(mockUseRemoveActiveAppUpdateToast).calledWith().mockReturnValue({ - removeActiveAppUpdateToast: jest.fn(), + vi.mocked(useRemoveActiveAppUpdateToast).mockReturnValue({ + removeActiveAppUpdateToast: vi.fn(), }) }) - afterEach(() => { - jest.resetAllMocks() - }) - it('renders update available title and release notes when update is available', () => { render(props) expect( @@ -78,7 +78,7 @@ describe('UpdateAppModal', () => { expect(screen.getByText('this is a release')).toBeInTheDocument() }) it('closes modal when "remind me later" button is clicked', () => { - const closeModal = jest.fn() + const closeModal = vi.fn() render({ ...props, closeModal }) fireEvent.click(screen.getByText('Remind me later')) expect(closeModal).toHaveBeenCalled() @@ -92,7 +92,7 @@ describe('UpdateAppModal', () => { }) it('shows error modal on error', () => { - getShellUpdateState.mockReturnValue({ + vi.mocked(getShellUpdateState).mockReturnValue({ error: { message: 'Could not get code signature for running application', name: 'Error', @@ -102,7 +102,7 @@ describe('UpdateAppModal', () => { expect(screen.getByText('Update Error')).toBeInTheDocument() }) it('shows a download progress bar when downloading', () => { - getShellUpdateState.mockReturnValue({ + vi.mocked(getShellUpdateState).mockReturnValue({ downloading: true, downloadPercentage: 50, } as ShellUpdateState) @@ -111,7 +111,7 @@ describe('UpdateAppModal', () => { expect(screen.getByRole('progressbar')).toBeInTheDocument() }) it('renders download complete text when download is finished', () => { - getShellUpdateState.mockReturnValue({ + vi.mocked(getShellUpdateState).mockReturnValue({ downloading: false, downloaded: true, } as ShellUpdateState) @@ -125,7 +125,7 @@ describe('UpdateAppModal', () => { ) }) it('renders an error message when an error occurs', () => { - getShellUpdateState.mockReturnValue({ + vi.mocked(getShellUpdateState).mockReturnValue({ error: { name: 'Update Error' }, } as ShellUpdateState) render(props) diff --git a/app/src/organisms/UpdateRobotBanner/__tests__/UpdateRobotBanner.test.tsx b/app/src/organisms/UpdateRobotBanner/__tests__/UpdateRobotBanner.test.tsx index a439dc10c02..11a395d74bc 100644 --- a/app/src/organisms/UpdateRobotBanner/__tests__/UpdateRobotBanner.test.tsx +++ b/app/src/organisms/UpdateRobotBanner/__tests__/UpdateRobotBanner.test.tsx @@ -1,7 +1,9 @@ import * as React from 'react' -import { renderWithProviders } from '@opentrons/components' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { fireEvent, screen } from '@testing-library/react' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import * as Buildroot from '../../../redux/robot-update' import { mockConnectableRobot, @@ -10,15 +12,11 @@ import { import { handleUpdateBuildroot } from '../../Devices/RobotSettings/UpdateBuildroot' import { UpdateRobotBanner } from '..' -jest.mock('../../../redux/robot-update') -jest.mock('../../Devices/RobotSettings/UpdateBuildroot') +vi.mock('../../../redux/robot-update') +vi.mock('../../Devices/RobotSettings/UpdateBuildroot') + +const getUpdateDisplayInfo = Buildroot.getRobotUpdateDisplayInfo -const getRobotUpdateDisplayInfo = Buildroot.getRobotUpdateDisplayInfo as jest.MockedFunction< - typeof Buildroot.getRobotUpdateDisplayInfo -> -const mockUpdateBuildroot = handleUpdateBuildroot as jest.MockedFunction< - typeof handleUpdateBuildroot -> const render = (props: React.ComponentProps) => { return renderWithProviders(, { i18nInstance: i18n, @@ -32,17 +30,13 @@ describe('UpdateRobotBanner', () => { props = { robot: mockConnectableRobot, } - getRobotUpdateDisplayInfo.mockReturnValue({ + vi.mocked(getUpdateDisplayInfo).mockReturnValue({ autoUpdateAction: 'upgrade', autoUpdateDisabledReason: null, updateFromFileDisabledReason: null, }) }) - afterEach(() => { - jest.resetAllMocks() - }) - it('should display correct information', () => { const { getByText, getByRole } = render(props) getByText( @@ -50,11 +44,11 @@ describe('UpdateRobotBanner', () => { ) const btn = getByRole('button', { name: 'View update' }) fireEvent.click(btn) - expect(mockUpdateBuildroot).toHaveBeenCalled() + expect(handleUpdateBuildroot).toHaveBeenCalled() }) it('should render nothing if update is not available when autoUpdateAction returns reinstall', () => { - getRobotUpdateDisplayInfo.mockReturnValue({ + vi.mocked(getUpdateDisplayInfo).mockReturnValue({ autoUpdateAction: 'reinstall', autoUpdateDisabledReason: null, updateFromFileDisabledReason: null, @@ -66,7 +60,7 @@ describe('UpdateRobotBanner', () => { }) it('should render nothing if update is not available when autoUpdateAction returns downgrade', () => { - getRobotUpdateDisplayInfo.mockReturnValue({ + vi.mocked(getUpdateDisplayInfo).mockReturnValue({ autoUpdateAction: 'downgrade', autoUpdateDisabledReason: null, updateFromFileDisabledReason: null, diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/CheckUpdates.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/CheckUpdates.test.tsx index b94614f9112..a9611b8b456 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/CheckUpdates.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/CheckUpdates.test.tsx @@ -1,5 +1,7 @@ import * as React from 'react' -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it } from 'vitest' +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { CheckUpdates } from '../CheckUpdates' @@ -10,7 +12,7 @@ const render = () => describe('CheckUpdates', () => { it('should render text', () => { - const [{ getByText }] = render() - getByText('Checking for updates') + render() + screen.getByText('Checking for updates') }) }) diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/CompleteUpdateSoftware.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/CompleteUpdateSoftware.test.tsx index 86dfe9778c4..f06f48a5f85 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/CompleteUpdateSoftware.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/CompleteUpdateSoftware.test.tsx @@ -1,9 +1,12 @@ import * as React from 'react' -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, expect, vi, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' import { i18n } from '../../../i18n' +import { renderWithProviders } from '../../../__testing-utils__' import { CompleteUpdateSoftware } from '../CompleteUpdateSoftware' -jest.mock('../../../redux/robot-admin') +vi.mock('../../../redux/robot-admin') const render = (props: React.ComponentProps) => { return renderWithProviders(, { @@ -21,10 +24,10 @@ describe('CompleteUpdateSoftware', () => { }) it('should render text, progress bar and button', () => { - const [{ getByText, getByTestId }] = render(props) - getByText('Update complete!') - getByText('Install complete, robot restarting...') - const bar = getByTestId('ProgressBar_Bar') + render(props) + screen.getByText('Update complete!') + screen.getByText('Install complete, robot restarting...') + const bar = screen.getByTestId('ProgressBar_Bar') expect(bar).toHaveStyle('width: 100%') }) }) diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/ErrorUpdateSoftware.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/ErrorUpdateSoftware.test.tsx index 08527220a46..bc5f690a1d7 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/ErrorUpdateSoftware.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/ErrorUpdateSoftware.test.tsx @@ -1,5 +1,8 @@ import * as React from 'react' -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, beforeEach } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { ErrorUpdateSoftware } from '../ErrorUpdateSoftware' @@ -24,12 +27,12 @@ describe('ErrorUpdateSoftware', () => { }) it('should render text', () => { - const [{ getByText }] = render(props) - getByText('Software update error') - getByText('mock error message') + render(props) + screen.getByText('Software update error') + screen.getByText('mock error message') }) it('should render provided children', () => { - const [{ getByText }] = render(props) - getByText('mock child') + render(props) + screen.getByText('mock child') }) }) diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/NoUpdateFound.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/NoUpdateFound.test.tsx index 791e258861b..66a0daab9b0 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/NoUpdateFound.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/NoUpdateFound.test.tsx @@ -1,12 +1,13 @@ import * as React from 'react' -import { fireEvent } from '@testing-library/react' - -import { renderWithProviders } from '@opentrons/components' +import { fireEvent, screen } from '@testing-library/react' +import { describe, it, vi, expect } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import { NoUpdateFound } from '../NoUpdateFound' -const mockOnContinue = jest.fn() +const mockOnContinue = vi.fn() const render = () => { return renderWithProviders(, { @@ -16,15 +17,17 @@ const render = () => { describe('NoUpdateFound', () => { it('should render text, icon and button', () => { - const [{ getByText, getByTestId }] = render() - getByText('Your software is already up to date!') - expect(getByTestId('NoUpdateFound_check_circle_icon')).toBeInTheDocument() - getByText('Continue') + render() + screen.getByText('Your software is already up to date!') + expect( + screen.getByTestId('NoUpdateFound_check_circle_icon') + ).toBeInTheDocument() + screen.getByText('Continue') }) it('should call mock function when tapping next button', () => { - const [{ getByText }] = render() - fireEvent.click(getByText('Continue')) + render() + fireEvent.click(screen.getByText('Continue')) expect(mockOnContinue).toBeCalled() }) }) diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateRobotSoftware.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateRobotSoftware.test.tsx index 1f3531347dc..242b40c4be8 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateRobotSoftware.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateRobotSoftware.test.tsx @@ -1,7 +1,8 @@ import * as React from 'react' -import { resetAllWhenMocks } from 'jest-when' - -import { renderWithProviders } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, vi, beforeEach, expect } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { renderWithProviders } from '../../../__testing-utils__' import { i18n } from '../../../i18n' import * as RobotUpdate from '../../../redux/robot-update' @@ -13,24 +14,16 @@ import { import type { State } from '../../../redux/types' -jest.mock('../../../redux/discovery') -jest.mock('../../../redux/robot-update') -jest.mock('../../../organisms/UpdateRobotSoftware/CheckUpdates') -jest.mock('../../../organisms/UpdateRobotSoftware/CompleteUpdateSoftware') -jest.mock('../../../organisms/UpdateRobotSoftware/ErrorUpdateSoftware') -jest.mock('../../../organisms/UpdateRobotSoftware/NoUpdateFound') -jest.mock('../../../organisms/UpdateRobotSoftware/UpdateSoftware') - -const mockCompleteUpdateSoftware = CompleteUpdateSoftware as jest.MockedFunction< - typeof CompleteUpdateSoftware -> -const mockUpdateSoftware = UpdateSoftware as jest.MockedFunction< - typeof UpdateSoftware -> - -const mockGetRobotUpdateSession = RobotUpdate.getRobotUpdateSession as jest.MockedFunction< - typeof RobotUpdate.getRobotUpdateSession -> +vi.mock('../../../redux/discovery') +vi.mock('../../../redux/robot-update') +vi.mock('../../../organisms/UpdateRobotSoftware/CheckUpdates') +vi.mock('../../../organisms/UpdateRobotSoftware/CompleteUpdateSoftware') +vi.mock('../../../organisms/UpdateRobotSoftware/ErrorUpdateSoftware') +vi.mock('../../../organisms/UpdateRobotSoftware/NoUpdateFound') +vi.mock('../../../organisms/UpdateRobotSoftware/UpdateSoftware') + +const getRobotUpdateSession = RobotUpdate.getRobotUpdateSession + const MOCK_STATE: State = { discovery: { robot: { connection: { connectedTo: null } }, @@ -77,8 +70,8 @@ const mockSession = { error: null, } -const mockAfterError = jest.fn() -const mockBeforeCommitting = jest.fn() +const mockAfterError = vi.fn() +const mockBeforeCommitting = vi.fn() const render = () => { return renderWithProviders( @@ -96,23 +89,18 @@ const render = () => { describe('UpdateRobotSoftware', () => { beforeEach(() => { - jest.useFakeTimers() - mockCompleteUpdateSoftware.mockReturnValue( + vi.useFakeTimers() + vi.mocked(CompleteUpdateSoftware).mockReturnValue(
mock CompleteUpdateSoftware
) - mockUpdateSoftware.mockReturnValue(
mock UpdateSoftware
) - }) - - afterEach(() => { - jest.resetAllMocks() - resetAllWhenMocks() + vi.mocked(UpdateSoftware).mockReturnValue(
mock UpdateSoftware
) }) it('should render complete screen when finished', () => { const mockCompleteSession = { ...mockSession, step: RobotUpdate.FINISHED } - mockGetRobotUpdateSession.mockReturnValue(mockCompleteSession) - const [{ getByText }] = render() - getByText('mock CompleteUpdateSoftware') + vi.mocked(getRobotUpdateSession).mockReturnValue(mockCompleteSession) + render() + screen.getByText('mock CompleteUpdateSoftware') }) it('should call beforeCommittingSuccessFulUpdate before installing', () => { @@ -121,21 +109,21 @@ describe('UpdateRobotSoftware', () => { step: RobotUpdate.COMMIT_UPDATE, stage: RobotUpdate.READY_FOR_RESTART, } - mockGetRobotUpdateSession.mockReturnValue(mockAboutToCommitSession) - const [{ getByText }] = render() + vi.mocked(getRobotUpdateSession).mockReturnValue(mockAboutToCommitSession) + render() expect(mockBeforeCommitting).toBeCalled() - expect(mockUpdateSoftware).toBeCalledWith( + expect(UpdateSoftware).toBeCalledWith( { updateType: 'installing', processProgress: 0 }, expect.anything() ) - getByText('mock UpdateSoftware') + screen.getByText('mock UpdateSoftware') }) it('should call afterError if there is an error', () => { const mockErrorSession = { ...mockSession, error: 'oh no!' } - mockGetRobotUpdateSession.mockReturnValue(mockErrorSession) - const [{ getByText }] = render() + vi.mocked(getRobotUpdateSession).mockReturnValue(mockErrorSession) + render() expect(mockAfterError).toBeCalled() - getByText('mock UpdateSoftware') + screen.getByText('mock UpdateSoftware') }) it('should render mock Update Robot Software for downloading', () => { @@ -143,10 +131,10 @@ describe('UpdateRobotSoftware', () => { ...mockSession, step: RobotUpdate.RESTART, } - mockGetRobotUpdateSession.mockReturnValue(mockDownloadSession) - const [{ getByText }] = render() - jest.advanceTimersByTime(11000) - getByText('mock UpdateSoftware') + vi.mocked(getRobotUpdateSession).mockReturnValue(mockDownloadSession) + render() + vi.advanceTimersByTime(11000) + screen.getByText('mock UpdateSoftware') }) it('should render mock Update Software for sending file', () => { @@ -155,10 +143,10 @@ describe('UpdateRobotSoftware', () => { step: RobotUpdate.GET_TOKEN, stage: RobotUpdate.VALIDATING, } - mockGetRobotUpdateSession.mockReturnValue(mockSendingFileSession) - const [{ getByText }] = render() - jest.advanceTimersByTime(11000) - getByText('mock UpdateSoftware') + vi.mocked(getRobotUpdateSession).mockReturnValue(mockSendingFileSession) + render() + vi.advanceTimersByTime(11000) + screen.getByText('mock UpdateSoftware') }) it('should render mock Update Software for validating', () => { @@ -166,10 +154,10 @@ describe('UpdateRobotSoftware', () => { ...mockSession, step: RobotUpdate.PROCESS_FILE, } - mockGetRobotUpdateSession.mockReturnValue(mockValidatingSession) - const [{ getByText }] = render() - jest.advanceTimersByTime(11000) - getByText('mock UpdateSoftware') + vi.mocked(getRobotUpdateSession).mockReturnValue(mockValidatingSession) + render() + vi.advanceTimersByTime(11000) + screen.getByText('mock UpdateSoftware') }) it('should render mock Update Software for installing', () => { @@ -177,9 +165,9 @@ describe('UpdateRobotSoftware', () => { ...mockSession, step: RobotUpdate.COMMIT_UPDATE, } - mockGetRobotUpdateSession.mockReturnValue(mockInstallingSession) - const [{ getByText }] = render() - jest.advanceTimersByTime(11000) - getByText('mock UpdateSoftware') + vi.mocked(getRobotUpdateSession).mockReturnValue(mockInstallingSession) + render() + vi.advanceTimersByTime(11000) + screen.getByText('mock UpdateSoftware') }) }) diff --git a/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateSoftware.test.tsx b/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateSoftware.test.tsx index 170cf9b6d40..913f2c26dea 100644 --- a/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateSoftware.test.tsx +++ b/app/src/organisms/UpdateRobotSoftware/__tests__/UpdateSoftware.test.tsx @@ -1,5 +1,9 @@ import * as React from 'react' -import { renderWithProviders, COLORS } from '@opentrons/components' +import { screen } from '@testing-library/react' +import { describe, it, beforeEach, expect } from 'vitest' +import '@testing-library/jest-dom/vitest' +import { renderWithProviders } from '../../../__testing-utils__' +import { COLORS } from '@opentrons/components' import { i18n } from '../../../i18n' import { UpdateSoftware } from '../UpdateSoftware' @@ -18,9 +22,9 @@ describe('UpdateSoftware', () => { } }) it('should render text and progressbar - downloading software', () => { - const [{ getByText, getByTestId }] = render(props) - getByText('Downloading software...') - const bar = getByTestId('ProgressBar_Bar') + render(props) + screen.getByText('Downloading software...') + const bar = screen.getByTestId('ProgressBar_Bar') expect(bar).toHaveStyle(`background: ${String(COLORS.blue50)}`) expect(bar).toHaveStyle('width: 50%') }) @@ -30,9 +34,9 @@ describe('UpdateSoftware', () => { processProgress: 20, updateType: 'sendingFile', } - const [{ getByText, getByTestId }] = render(props) - getByText('Sending software...') - const bar = getByTestId('ProgressBar_Bar') + render(props) + screen.getByText('Sending software...') + const bar = screen.getByTestId('ProgressBar_Bar') expect(bar).toHaveStyle('width: 20%') }) it('should render text and progressbar - validating software', () => { @@ -41,9 +45,9 @@ describe('UpdateSoftware', () => { processProgress: 80, updateType: 'validating', } - const [{ getByText, getByTestId }] = render(props) - getByText('Validating software...') - const bar = getByTestId('ProgressBar_Bar') + render(props) + screen.getByText('Validating software...') + const bar = screen.getByTestId('ProgressBar_Bar') expect(bar).toHaveStyle('width: 80%') }) it('should render text and progressbar - installing software', () => { @@ -52,9 +56,9 @@ describe('UpdateSoftware', () => { processProgress: 5, updateType: 'installing', } - const [{ getByText, getByTestId }] = render(props) - getByText('Installing software...') - const bar = getByTestId('ProgressBar_Bar') + render(props) + screen.getByText('Installing software...') + const bar = screen.getByTestId('ProgressBar_Bar') expect(bar).toHaveStyle('width: 5%') }) })