Skip to content

Commit a5cc6a0

Browse files
committed
correct typing unions for function steps
1 parent 550c289 commit a5cc6a0

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

protocol-designer/cypress/support/SetupSteps.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export enum SetupLocators {
148148
DoneButtonLabwareSelection = '[data-testid="Toolbox_confirmButton"]',
149149
}
150150

151+
// #region Functions
151152
// The alternative to enums is defining functions
152153

153154
function selectLabwareByDisplayName(displayName: string): void {
@@ -158,10 +159,22 @@ function selectLabwareByDisplayName(displayName: string): void {
158159
// all function definitions must be added here
159160
export const setupFunctions = {
160161
selectLabwareByDisplayName,
162+
// Add more functions here
161163
}
162164

163165
export type SetupFunction = typeof setupFunctions[keyof typeof setupFunctions]
164166

167+
export type SetupFunctionMap = {
168+
[K in keyof typeof setupFunctions]: {
169+
name: K
170+
param: Parameters<typeof setupFunctions[K]>[0]
171+
}
172+
}[keyof typeof setupFunctions]
173+
// This becomes a union of { name: 'selectLabwareByDisplayName', param: string }
174+
// and { name: 'anotherFn', param: number }, etc.
175+
176+
// #endregion Functions
177+
165178
const chooseDeckSlot = (
166179
slot: string
167180
): Cypress.Chainable<JQuery<HTMLElement>> => {
@@ -248,15 +261,18 @@ const selectWells = (wells: string[]): void => {
248261
// selectWells(['A1', 'B3', 'H12'])
249262

250263
export const executeSetupSteps = (action: StepListItem): void => {
251-
if (typeof action.step === 'function') {
252-
action.step(action.params)
264+
if (action.type === 'function') {
265+
const fn = setupFunctions[action.step]
266+
if (action.params === undefined || action.params === null) {
267+
throw new Error(`Function ${action.step} requires a parameter.`)
268+
}
269+
fn(action.params)
253270
return
254271
}
255272
switch (action.step) {
256273
case SetupActions.SelectFlex:
257274
cy.contains(SetupContent.OpentronsFlex).should('be.visible').click()
258275
break
259-
260276
case SetupActions.SelectOT2:
261277
cy.contains(SetupContent.OpentronsOT2).should('be.visible').click()
262278
break

protocol-designer/cypress/support/StepExecution.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { executeUniversalAction, UniversalActions } from './universalActions'
2-
import { isEnumValue } from './utils'
2+
import { isEnumValue, isFunctionInRecord } from './utils'
33
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
44
import {
55
SetupActions,
66
SetupVerifications,
77
executeVerificationStep,
88
executeSetupSteps,
9-
SetupFunction,
9+
SetupFunctionMap,
10+
setupFunctions,
1011
} from './SetupSteps'
1112
import {
1213
ModActions,
@@ -15,17 +16,29 @@ import {
1516
executeVerifyModStep,
1617
} from './SupportModules'
1718

18-
export interface StepListItem {
19+
export interface EnumBasedStep {
20+
type: 'enum'
1921
step:
2022
| SetupActions
2123
| SetupVerifications
2224
| UniversalActions
2325
| ModActions
2426
| ModVerifications
25-
| SetupFunction
26-
params?: string | string[] | number | boolean | undefined
27+
params?: string | string[] | number | boolean
2728
}
2829

30+
export interface FunctionBasedStep {
31+
type: 'function'
32+
33+
step: SetupFunctionMap['name']
34+
// add other support modules function maps here
35+
36+
// This is optional because we want to allow functions that don't take any parameters
37+
params?: SetupFunctionMap['param']
38+
// add other support modules function maps here
39+
}
40+
41+
export type StepListItem = FunctionBasedStep | EnumBasedStep
2942
export type StepsList = StepListItem[]
3043

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

5164
steps.forEach(item => {
5265
if (
53-
isEnumValue([SetupActions], item.step) ||
54-
typeof item.step === 'function'
66+
(item.type === 'enum' && isEnumValue([SetupActions], item.step)) ||
67+
(item.type === 'function' && isFunctionInRecord(setupFunctions, item.step))
5568
) {
5669
executeSetupSteps(item)
5770
} else if (isEnumValue([SetupVerifications], item.step)) {

protocol-designer/cypress/support/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ export const isEnumValue = <T extends object>(
99
)
1010
)
1111
}
12+
13+
export function isFunctionInRecord(
14+
functionMap: Record<string, any>,
15+
step: string
16+
): boolean {
17+
return Object.keys(functionMap).includes(step)
18+
}

0 commit comments

Comments
 (0)