Skip to content

Commit

Permalink
correct typing unions for function steps
Browse files Browse the repository at this point in the history
  • Loading branch information
y3rsh committed Feb 10, 2025
1 parent 550c289 commit a5cc6a0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
22 changes: 19 additions & 3 deletions protocol-designer/cypress/support/SetupSteps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export enum SetupLocators {
DoneButtonLabwareSelection = '[data-testid="Toolbox_confirmButton"]',
}

// #region Functions
// The alternative to enums is defining functions

function selectLabwareByDisplayName(displayName: string): void {
Expand All @@ -158,10 +159,22 @@ function selectLabwareByDisplayName(displayName: string): void {
// all function definitions must be added here
export const setupFunctions = {
selectLabwareByDisplayName,
// Add more functions here
}

export type SetupFunction = typeof setupFunctions[keyof typeof setupFunctions]

export type SetupFunctionMap = {
[K in keyof typeof setupFunctions]: {
name: K
param: Parameters<typeof setupFunctions[K]>[0]
}
}[keyof typeof setupFunctions]
// This becomes a union of { name: 'selectLabwareByDisplayName', param: string }
// and { name: 'anotherFn', param: number }, etc.

// #endregion Functions

const chooseDeckSlot = (
slot: string
): Cypress.Chainable<JQuery<HTMLElement>> => {
Expand Down Expand Up @@ -248,15 +261,18 @@ const selectWells = (wells: string[]): void => {
// selectWells(['A1', 'B3', 'H12'])

export const executeSetupSteps = (action: StepListItem): void => {
if (typeof action.step === 'function') {
action.step(action.params)
if (action.type === 'function') {
const fn = setupFunctions[action.step]
if (action.params === undefined || action.params === null) {
throw new Error(`Function ${action.step} requires a parameter.`)
}
fn(action.params)
return
}
switch (action.step) {
case SetupActions.SelectFlex:
cy.contains(SetupContent.OpentronsFlex).should('be.visible').click()
break

case SetupActions.SelectOT2:
cy.contains(SetupContent.OpentronsOT2).should('be.visible').click()
break
Expand Down
27 changes: 20 additions & 7 deletions protocol-designer/cypress/support/StepExecution.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { executeUniversalAction, UniversalActions } from './universalActions'
import { isEnumValue } from './utils'
import { isEnumValue, isFunctionInRecord } from './utils'
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import {
SetupActions,
SetupVerifications,
executeVerificationStep,
executeSetupSteps,
SetupFunction,
SetupFunctionMap,
setupFunctions,
} from './SetupSteps'
import {
ModActions,
Expand All @@ -15,17 +16,29 @@ import {
executeVerifyModStep,
} from './SupportModules'

export interface StepListItem {
export interface EnumBasedStep {
type: 'enum'
step:
| SetupActions
| SetupVerifications
| UniversalActions
| ModActions
| ModVerifications
| SetupFunction
params?: string | string[] | number | boolean | undefined
params?: string | string[] | number | boolean
}

export interface FunctionBasedStep {
type: 'function'

step: SetupFunctionMap['name']
// add other support modules function maps here

// This is optional because we want to allow functions that don't take any parameters
params?: SetupFunctionMap['param']
// add other support modules function maps here
}

export type StepListItem = FunctionBasedStep | EnumBasedStep
export type StepsList = StepListItem[]

export const runSteps = (steps: StepsList): void => {
Expand All @@ -50,8 +63,8 @@ export const runSteps = (steps: StepsList): void => {

steps.forEach(item => {
if (
isEnumValue([SetupActions], item.step) ||
typeof item.step === 'function'
(item.type === 'enum' && isEnumValue([SetupActions], item.step)) ||
(item.type === 'function' && isFunctionInRecord(setupFunctions, item.step))
) {
executeSetupSteps(item)
} else if (isEnumValue([SetupVerifications], item.step)) {
Expand Down
7 changes: 7 additions & 0 deletions protocol-designer/cypress/support/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ export const isEnumValue = <T extends object>(
)
)
}

export function isFunctionInRecord(
functionMap: Record<string, any>,
step: string
): boolean {
return Object.keys(functionMap).includes(step)
}

0 comments on commit a5cc6a0

Please sign in to comment.