Skip to content

Commit

Permalink
fix(app): fix recovery error screen during Error Recovery on desktop (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mjhuff authored Aug 12, 2024
1 parent b99e7c2 commit 3ab4773
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,13 @@ const buildMoveToAACommand = (

export const buildLoadPipetteCommand = (
pipetteName: PipetteModelSpecs['name'],
mount: PipetteData['mount']
mount: PipetteData['mount'],
pipetteId?: string | null
): CreateCommand => {
return {
commandType: 'loadPipette',
params: {
pipetteId: MANAGED_PIPETTE_ID,
pipetteId: pipetteId ?? MANAGED_PIPETTE_ID,
mount,
pipetteName,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,15 @@ function useRegisterPipetteFixitType({
instrumentModelSpecs,
issuedCommandsType,
chainRunCommands,
fixitCommandTypeUtils,
}: UseRegisterPipetteFixitType): void {
React.useEffect(() => {
if (issuedCommandsType === 'fixit') {
const command = buildLoadPipetteCommand(instrumentModelSpecs.name, mount)
const command = buildLoadPipetteCommand(
instrumentModelSpecs.name,
mount,
fixitCommandTypeUtils?.pipetteId
)
void chainRunCommands([command], true)
}
}, [])
Expand Down
1 change: 1 addition & 0 deletions app/src/organisms/DropTipWizardFlows/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface DropTipWizardRouteOverride {
export interface FixitCommandTypeUtils {
runId: string
failedCommandId: string
pipetteId: string | null
copyOverrides: CopyOverrides
errorOverrides: ErrorOverrides
buttonOverrides: ButtonOverrides
Expand Down
43 changes: 30 additions & 13 deletions app/src/organisms/ErrorRecoveryFlows/RecoveryError.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'

import {
COLORS,
Expand All @@ -10,13 +11,21 @@ import {
SPACING,
ALIGN_CENTER,
JUSTIFY_END,
PrimaryButton,
JUSTIFY_CENTER,
RESPONSIVENESS,
} from '@opentrons/components'

import { RECOVERY_MAP } from './constants'
import { SmallButton } from '../../atoms/buttons'
import { RecoverySingleColumnContentWrapper } from './shared'
import {
DESKTOP_ONLY,
ICON_SIZE_ALERT_INFO_STYLE,
ODD_ONLY,
RECOVERY_MAP,
} from './constants'

import type { RecoveryContentProps } from './types'
import { SmallButton } from '../../atoms/buttons'

export function RecoveryError(props: RecoveryContentProps): JSX.Element {
const { recoveryMap } = props
Expand Down Expand Up @@ -155,7 +164,6 @@ export function RecoveryDropTipFlowErrors({
}

export function ErrorContent({
isOnDevice,
title,
subTitle,
btnText,
Expand All @@ -169,19 +177,12 @@ export function ErrorContent({
}): JSX.Element | null {
return (
<RecoverySingleColumnContentWrapper>
<Flex
padding={SPACING.spacing40}
gridGap={SPACING.spacing24}
flexDirection={DIRECTION_COLUMN}
alignItems={ALIGN_CENTER}
justifyContent={ALIGN_CENTER}
flex="1"
>
<Flex css={CONTAINER_STYLE}>
<Icon
name="alert-circle"
size={SPACING.spacing60}
color={COLORS.red50}
data-testid="recovery_error_alert_icon"
css={ICON_SIZE_ALERT_INFO_STYLE}
/>
<Flex
gridGap={SPACING.spacing4}
Expand All @@ -204,8 +205,24 @@ export function ErrorContent({
</Flex>
</Flex>
<Flex justifyContent={JUSTIFY_END}>
<SmallButton onClick={btnOnClick} buttonText={btnText} />
<SmallButton onClick={btnOnClick} buttonText={btnText} css={ODD_ONLY} />
<PrimaryButton onClick={btnOnClick} css={DESKTOP_ONLY}>
{btnText}
</PrimaryButton>
</Flex>
</RecoverySingleColumnContentWrapper>
)
}

const CONTAINER_STYLE = css`
padding: ${SPACING.spacing40};
grid-gap: ${SPACING.spacing16};
flex-direction: ${DIRECTION_COLUMN};
align-items: ${ALIGN_CENTER};
justify-content: ${JUSTIFY_CENTER};
flex: 1;
@media (${RESPONSIVENESS.touchscreenMediaQuerySpecs}) {
grid-gap: ${SPACING.spacing24};
}
`
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,17 @@ export function useDropTipFlowUtils({
}
}

const pipetteId =
failedCommand != null &&
'params' in failedCommand.byRunRecord &&
'pipetteId' in failedCommand.byRunRecord.params
? failedCommand.byRunRecord.params.pipetteId
: null

return {
runId,
failedCommandId,
pipetteId,
copyOverrides: buildCopyOverrides(),
errorOverrides: buildErrorOverrides(),
buttonOverrides: buildButtonOverrides(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable testing-library/prefer-presence-queries */
import * as React from 'react'
import { describe, it, vi, expect, beforeEach } from 'vitest'
import { screen, fireEvent } from '@testing-library/react'
Expand Down Expand Up @@ -48,63 +49,63 @@ describe('RecoveryError', () => {
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.RECOVERY_ACTION_FAILED
render(props)

expect(screen.getByText('Retry step failed')).toBeInTheDocument()
expect(screen.queryAllByText('Retry step failed')[0]).toBeInTheDocument()
expect(
screen.getByText(
screen.queryAllByText(
'Next, you can try another recovery action or cancel the run.'
)
)[0]
).toBeInTheDocument()
expect(screen.getByText('Back to menu')).toBeInTheDocument()
expect(screen.queryAllByText('Back to menu')[0]).toBeInTheDocument()
})

it(`renders RecoveryDropTipFlowErrors when step is ${ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_GENERAL_ERROR}`, () => {
props.recoveryMap.step =
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_GENERAL_ERROR
render(props)

expect(screen.getByText('Retry step failed')).toBeInTheDocument()
expect(screen.queryAllByText('Retry step failed')[0]).toBeInTheDocument()
expect(
screen.getByText(
screen.queryAllByText(
'Next, you can try another recovery action or cancel the run.'
)
)[0]
).toBeInTheDocument()
expect(screen.getByText('Return to menu')).toBeInTheDocument()
expect(screen.queryAllByText('Return to menu')[0]).toBeInTheDocument()
})

it(`renders RecoveryDropTipFlowErrors when step is ${ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_BLOWOUT_FAILED}`, () => {
props.recoveryMap.step =
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_BLOWOUT_FAILED
render(props)

expect(screen.getByText('Blowout failed')).toBeInTheDocument()
expect(screen.queryAllByText('Blowout failed')[0]).toBeInTheDocument()
expect(
screen.getByText(
screen.queryAllByText(
'You can still drop the attached tips before proceeding to tip selection.'
)
)[0]
).toBeInTheDocument()
expect(screen.getByText('Continue to drop tip')).toBeInTheDocument()
expect(screen.queryAllByText('Continue to drop tip')[0]).toBeInTheDocument()
})

it(`renders RecoveryDropTipFlowErrors when step is ${ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_TIP_DROP_FAILED}`, () => {
props.recoveryMap.step =
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_TIP_DROP_FAILED
render(props)

expect(screen.getByText('Tip drop failed')).toBeInTheDocument()
expect(screen.queryAllByText('Tip drop failed')[0]).toBeInTheDocument()
expect(
screen.getByText(
screen.queryAllByText(
'Next, you can try another recovery action or cancel the run.'
)
)[0]
).toBeInTheDocument()
expect(screen.getByText('Return to menu')).toBeInTheDocument()
expect(screen.queryAllByText('Return to menu')[0]).toBeInTheDocument()
})

it(`calls proceedToRouteAndStep with ${RECOVERY_MAP.OPTION_SELECTION.ROUTE} when the "Back to menu" button is clicked in ErrorRecoveryFlowError`, () => {
props.recoveryMap.step =
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.RECOVERY_ACTION_FAILED
render(props)

fireEvent.click(screen.getByText('Back to menu'))
fireEvent.click(screen.queryAllByText('Back to menu')[0])

expect(proceedToRouteAndStepMock).toHaveBeenCalledWith(
RECOVERY_MAP.OPTION_SELECTION.ROUTE
Expand All @@ -116,7 +117,7 @@ describe('RecoveryError', () => {
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_GENERAL_ERROR
render(props)

fireEvent.click(screen.getByText('Return to menu'))
fireEvent.click(screen.queryAllByText('Return to menu')[0])

expect(proceedToRouteAndStepMock).toHaveBeenCalledWith(
RECOVERY_MAP.OPTION_SELECTION.ROUTE
Expand All @@ -128,7 +129,7 @@ describe('RecoveryError', () => {
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_TIP_DROP_FAILED
render(props)

fireEvent.click(screen.getByText('Return to menu'))
fireEvent.click(screen.queryAllByText('Return to menu')[0])

expect(proceedToRouteAndStepMock).toHaveBeenCalledWith(
RECOVERY_MAP.OPTION_SELECTION.ROUTE
Expand All @@ -140,7 +141,7 @@ describe('RecoveryError', () => {
RECOVERY_MAP.ERROR_WHILE_RECOVERING.STEPS.DROP_TIP_BLOWOUT_FAILED
render(props)

fireEvent.click(screen.getByText('Continue to drop tip'))
fireEvent.click(screen.queryAllByText('Continue to drop tip')[0])

expect(proceedToRouteAndStepMock).toHaveBeenCalledWith(
RECOVERY_MAP.DROP_TIP_FLOWS.ROUTE,
Expand Down

0 comments on commit 3ab4773

Please sign in to comment.