Skip to content

Commit cd164a1

Browse files
internal(browser): Add Check/Uncheck action to Browser Test Editor (#1163)
1 parent f8f61f7 commit cd164a1

File tree

8 files changed

+162
-5
lines changed

8 files changed

+162
-5
lines changed

src/codegen/browser/test.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,24 @@ function buildBrowserNodeGraphFromActions(
396396
locator: getLocator(action.locator),
397397
},
398398
}
399+
case 'locator.check':
400+
return {
401+
type: 'check',
402+
nodeId: crypto.randomUUID(),
403+
checked: true,
404+
inputs: {
405+
locator: getLocator(action.locator),
406+
},
407+
}
408+
case 'locator.uncheck':
409+
return {
410+
type: 'check',
411+
nodeId: crypto.randomUUID(),
412+
checked: false,
413+
inputs: {
414+
locator: getLocator(action.locator),
415+
},
416+
}
399417
case 'locator.fill':
400418
return {
401419
type: 'type-text',
@@ -410,8 +428,6 @@ function buildBrowserNodeGraphFromActions(
410428
case 'page.*':
411429
case 'locator.dblclick':
412430
case 'locator.type':
413-
case 'locator.check':
414-
case 'locator.uncheck':
415431
case 'locator.selectOption':
416432
case 'locator.hover':
417433
case 'locator.setChecked':
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Grid } from '@radix-ui/themes'
2+
3+
import { LocatorCheckAction } from '@/main/runner/schema'
4+
5+
import { LocatorForm } from '../../ActionForms/forms/LocatorForm'
6+
import { WithEditorMetadata } from '../../types'
7+
8+
const CHECK_ROLES = ['checkbox', 'radio', 'switch']
9+
10+
interface CheckActionBodyProps {
11+
action: WithEditorMetadata<LocatorCheckAction>
12+
onChange: (action: WithEditorMetadata<LocatorCheckAction>) => void
13+
}
14+
15+
export function CheckActionBody({ action, onChange }: CheckActionBodyProps) {
16+
const handleChangeLocator = (
17+
locator: WithEditorMetadata<LocatorCheckAction>['locator']
18+
) => {
19+
onChange({ ...action, locator })
20+
}
21+
22+
return (
23+
<Grid
24+
columns="max-content minmax(0, max-content) 1fr"
25+
gap="2"
26+
align="center"
27+
width="100%"
28+
>
29+
Check input
30+
<LocatorForm state={action.locator} suggestedRoles={CHECK_ROLES} onChange={handleChangeLocator} />
31+
</Grid>
32+
)
33+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './CheckActionBody'
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Grid } from '@radix-ui/themes'
2+
3+
import { LocatorUncheckAction } from '@/main/runner/schema'
4+
5+
import { LocatorForm } from '../../ActionForms/forms/LocatorForm'
6+
import { WithEditorMetadata } from '../../types'
7+
8+
const UNCHECK_ROLES = ['checkbox', 'radio', 'switch']
9+
10+
interface UncheckActionBodyProps {
11+
action: WithEditorMetadata<LocatorUncheckAction>
12+
onChange: (action: WithEditorMetadata<LocatorUncheckAction>) => void
13+
}
14+
15+
export function UncheckActionBody({
16+
action,
17+
onChange,
18+
}: UncheckActionBodyProps) {
19+
const handleChangeLocator = (
20+
locator: WithEditorMetadata<LocatorUncheckAction>['locator']
21+
) => {
22+
onChange({ ...action, locator })
23+
}
24+
25+
return (
26+
<Grid
27+
columns="max-content minmax(0, max-content) 1fr"
28+
gap="2"
29+
align="center"
30+
width="100%"
31+
>
32+
Uncheck input
33+
<LocatorForm state={action.locator} suggestedRoles={UNCHECK_ROLES} onChange={handleChangeLocator} />
34+
</Grid>
35+
)
36+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './UncheckActionBody'
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
export * from './CheckAction'
12
export * from './ClickAction'
23
export * from './FillAction'
34
export * from './GoToAction'
45
export * from './PageReloadAction'
6+
export * from './UncheckAction'
57
export * from './WaitForAction'

src/views/BrowserTestEditor/EditableBrowserActionList.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,38 @@ function NewActionMenu({ onAddAction }: NewActionMenuProps) {
9090
>
9191
Fill input
9292
</DropdownMenu.Item>
93+
<DropdownMenu.Separator />
9394
<DropdownMenu.Item
9495
onClick={() => {
95-
onAddAction('page.goto')
96+
onAddAction('locator.check')
9697
}}
9798
>
98-
Navigate to URL
99+
Check input
100+
</DropdownMenu.Item>
101+
<DropdownMenu.Item
102+
onClick={() => {
103+
onAddAction('locator.uncheck')
104+
}}
105+
>
106+
Uncheck input
99107
</DropdownMenu.Item>
108+
<DropdownMenu.Separator />
109+
100110
<DropdownMenu.Item
101111
onClick={() => {
102112
onAddAction('locator.waitFor')
103113
}}
104114
>
105115
Wait for element
106116
</DropdownMenu.Item>
117+
<DropdownMenu.Separator />
118+
<DropdownMenu.Item
119+
onClick={() => {
120+
onAddAction('page.goto')
121+
}}
122+
>
123+
Navigate to URL
124+
</DropdownMenu.Item>
107125
<DropdownMenu.Item
108126
onClick={() => {
109127
onAddAction('page.reload')

src/views/BrowserTestEditor/actionEditorRegistry.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ import {
44
GlobeIcon,
55
MousePointerClickIcon,
66
RefreshCwIcon,
7+
SquareCheckBigIcon,
8+
SquareIcon,
79
TextCursorInputIcon,
810
TimerIcon,
911
} from 'lucide-react'
1012
import { ReactElement, ReactNode } from 'react'
1113

1214
import {
15+
CheckActionBody,
1316
ClickActionBody,
1417
FillActionBody,
1518
GoToActionBody,
1619
PageReloadActionBody,
20+
UncheckActionBody,
1721
WaitForActionBody,
1822
} from './Actions'
1923
import { BrowserActionInstance } from './types'
@@ -58,6 +62,44 @@ const notImplementedCreate = <M extends BrowserActionInstance['method']>(
5862
}
5963

6064
const actionEditors: ActionEditorRegistry = {
65+
'locator.check': {
66+
icon: <SquareCheckBigIcon aria-hidden="true" />,
67+
render: ({ action, onChange }) => (
68+
<CheckActionBody action={action} onChange={onChange} />
69+
),
70+
create: () => ({
71+
id: crypto.randomUUID(),
72+
method: 'locator.check',
73+
locator: {
74+
current: 'role',
75+
values: {
76+
role: {
77+
type: 'role',
78+
role: 'checkbox',
79+
},
80+
},
81+
},
82+
}),
83+
},
84+
'locator.uncheck': {
85+
icon: <SquareIcon aria-hidden="true" />,
86+
render: ({ action, onChange }) => (
87+
<UncheckActionBody action={action} onChange={onChange} />
88+
),
89+
create: () => ({
90+
id: crypto.randomUUID(),
91+
method: 'locator.uncheck',
92+
locator: {
93+
current: 'role',
94+
values: {
95+
role: {
96+
type: 'role',
97+
role: 'checkbox',
98+
},
99+
},
100+
},
101+
}),
102+
},
61103
'locator.click': {
62104
icon: <MousePointerClickIcon aria-hidden="true" />,
63105
render: ({ action, onChange }) => (
@@ -78,7 +120,15 @@ const actionEditors: ActionEditorRegistry = {
78120
id: crypto.randomUUID(),
79121
method: 'locator.fill',
80122
value: '',
81-
locator: createDefaultLocatorOptions(),
123+
locator: {
124+
current: 'role',
125+
values: {
126+
role: {
127+
type: 'role',
128+
role: 'textbox',
129+
},
130+
},
131+
},
82132
}),
83133
},
84134
'page.goto': {

0 commit comments

Comments
 (0)