Skip to content

Commit ccb499d

Browse files
authored
feat: add pre-screenshot actions (#33)
1 parent 76ea4ca commit ccb499d

32 files changed

+2079
-61
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'heroshot': minor
3+
---
4+
5+
Add pre-screenshot actions for interacting with pages before capture. Supports click, type, hover, select_option, press_key, drag, wait, navigate, evaluate, fill_form, handle_dialog, file_upload, and resize actions aligned with Playwright API.

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,39 @@ jobs:
269269
path: editor/test-results/
270270
retention-days: 7
271271

272+
# Verify API reference docs are up-to-date with Zod schemas
273+
generate-docs:
274+
needs: changes
275+
if: github.event_name == 'pull_request' && needs.changes.outputs.code == 'true'
276+
runs-on: ubuntu-latest
277+
steps:
278+
- uses: actions/checkout@v4
279+
280+
- uses: pnpm/action-setup@v4
281+
282+
- uses: actions/setup-node@v4
283+
with:
284+
node-version: 20
285+
cache: pnpm
286+
287+
- name: Install dependencies
288+
run: pnpm install --frozen-lockfile
289+
290+
- name: Generate API reference docs
291+
run: |
292+
pnpm docs:generate
293+
pnpm prettier --write docs/docs/*-reference.md
294+
295+
- name: Verify docs are up-to-date
296+
run: |
297+
if [ -n "$(git status --porcelain docs/docs/*-reference.md)" ]; then
298+
echo "::error::API reference docs are out of date. Run 'pnpm docs:generate' and commit the changes."
299+
git diff docs/docs/*-reference.md
300+
exit 1
301+
else
302+
echo "Docs are up-to-date"
303+
fi
304+
272305
# CLI integration tests - run in parallel with everything else
273306
cli-tests:
274307
needs: install

docs/.vitepress/config.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,19 @@ export default defineConfig({
146146
],
147147
},
148148
{
149-
text: 'CLI',
149+
text: 'Reference',
150150
items: [
151-
{ text: 'CLI Reference', link: '/docs/cli' },
152-
{ text: 'Configuration', link: '/docs/config' },
151+
{ text: 'CLI', link: '/docs/cli' },
152+
{
153+
text: 'Configuration',
154+
link: '/docs/config',
155+
items: [
156+
{ text: 'Global Config', link: '/docs/config-reference' },
157+
{ text: 'Screenshot', link: '/docs/screenshot-reference' },
158+
{ text: 'Browser', link: '/docs/browser-reference' },
159+
{ text: 'Actions', link: '/docs/actions-reference' },
160+
],
161+
},
153162
],
154163
},
155164
{

docs/docs/actions-reference.md

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
---
2+
description: Complete reference for all pre-screenshot actions with properties and examples.
3+
---
4+
5+
# Actions API Reference
6+
7+
Back to [Configuration overview](./config#actions).
8+
9+
### `click`
10+
11+
Click an element. Use to dismiss cookie banners, open menus, expand dropdowns, toggle UI state, or trigger any clickable interaction before capturing.
12+
13+
| Property | Type | Required | Description |
14+
| ------------- | ------------------------------------------------------------------------ | -------- | --------------------------------------- |
15+
| `selector` | string | yes | CSS selector of the element to click |
16+
| `doubleClick` | boolean | no | Whether to perform a double click |
17+
| `button` | `"left"` \| `"right"` \| `"middle"` | no | Mouse button to click, defaults to left |
18+
| `modifiers` | (`"Alt"` \| `"Control"` \| `"ControlOrMeta"` \| `"Meta"` \| `"Shift"`)[] | no | Modifier keys to hold during click |
19+
20+
```json
21+
// minimal
22+
{
23+
"type": "click",
24+
"selector": ".my-element"
25+
}
26+
27+
// with options
28+
{
29+
"type": "click",
30+
"selector": ".my-element",
31+
"doubleClick": true,
32+
"button": "right",
33+
"modifiers": [
34+
"Control"
35+
]
36+
}
37+
```
38+
39+
### `type`
40+
41+
Type text into an input, textarea, or contenteditable element. Use to populate forms with demo data, enter search queries, or fill in sample content for screenshots.
42+
43+
| Property | Type | Required | Description |
44+
| ---------- | ------- | -------- | -------------------------------------------------------------------------------------------- |
45+
| `selector` | string | yes | CSS selector of the input element |
46+
| `text` | string | yes | Text to type into the element |
47+
| `submit` | boolean | no | Whether to press Enter after typing (submit form) |
48+
| `slowly` | boolean | no | Whether to type one character at a time. Useful for triggering key handlers or autocomplete. |
49+
50+
```json
51+
// minimal
52+
{
53+
"type": "type",
54+
"selector": ".my-element",
55+
"text": "Hello world"
56+
}
57+
58+
// with options
59+
{
60+
"type": "type",
61+
"selector": ".my-element",
62+
"text": "Hello world",
63+
"submit": true,
64+
"slowly": true
65+
}
66+
```
67+
68+
### `hover`
69+
70+
Hover over an element to trigger :hover states, show tooltips, or reveal hidden menus before capturing.
71+
72+
| Property | Type | Required | Description |
73+
| ---------- | ------ | -------- | ----------------------------------------- |
74+
| `selector` | string | yes | CSS selector of the element to hover over |
75+
76+
```json
77+
{
78+
"type": "hover",
79+
"selector": ".my-element"
80+
}
81+
```
82+
83+
### `select_option`
84+
85+
Select one or more options in a native <select> dropdown to show a specific selection state.
86+
87+
| Property | Type | Required | Description |
88+
| ---------- | -------- | -------- | --------------------------------------------------------------------- |
89+
| `selector` | string | yes | CSS selector of the <select> element |
90+
| `values` | string[] | yes | Option values to select. Supports multiple for multi-select elements. |
91+
92+
```json
93+
{
94+
"type": "select_option",
95+
"selector": ".my-element",
96+
"values": ["option-1", "option-2"]
97+
}
98+
```
99+
100+
### `press_key`
101+
102+
Press a keyboard key or combination. Use to close modals (Escape), submit forms (Enter), navigate focus (Tab), trigger shortcuts, or activate keyboard-driven UI.
103+
104+
| Property | Type | Required | Description |
105+
| -------- | ------ | -------- | ------------------------------------------------------------------------------ |
106+
| `key` | string | yes | Key to press, e.g. "Enter", "Escape", "ArrowDown", "Control+a", "Meta+Shift+k" |
107+
108+
```json
109+
{
110+
"type": "press_key",
111+
"key": "Enter"
112+
}
113+
```
114+
115+
### `drag`
116+
117+
Drag an element and drop it onto another. Use to show reordering or drag-and-drop interaction mid-state.
118+
119+
| Property | Type | Required | Description |
120+
| -------- | ------ | -------- | ----------------------------------- |
121+
| `from` | string | yes | CSS selector of the element to drag |
122+
| `to` | string | yes | CSS selector of the drop target |
123+
124+
```json
125+
{
126+
"type": "drag",
127+
"from": ".draggable-item",
128+
"to": ".drop-zone"
129+
}
130+
```
131+
132+
### `wait`
133+
134+
Pause execution until a condition is met. Wait for a fixed duration, for specific text to appear (e.g. after async loading), or for text to disappear (e.g. loading spinners).
135+
136+
| Property | Type | Required | Description |
137+
| ---------- | ------ | -------- | --------------------------------------------- |
138+
| `time` | number | no | Time to wait in seconds (max 30s) |
139+
| `text` | string | no | Wait for this text to appear on the page |
140+
| `textGone` | string | no | Wait for this text to disappear from the page |
141+
142+
```json
143+
// minimal
144+
{
145+
"type": "wait"
146+
}
147+
148+
// with options
149+
{
150+
"type": "wait",
151+
"time": 0.5,
152+
"text": "Hello world",
153+
"textGone": "Loading..."
154+
}
155+
```
156+
157+
### `navigate`
158+
159+
Navigate to a different URL or go back in history. Use to reach a specific page state after login, follow a multi-step flow, or return to a previous page.
160+
161+
| Property | Type | Required | Description |
162+
| -------- | ------- | -------- | ----------------------------------------- |
163+
| `url` | string | no | URL to navigate to (absolute or relative) |
164+
| `back` | boolean | no | Navigate back to the previous page |
165+
166+
```json
167+
// minimal
168+
{
169+
"type": "navigate"
170+
}
171+
172+
// with options
173+
{
174+
"type": "navigate",
175+
"url": "/dashboard",
176+
"back": true
177+
}
178+
```
179+
180+
### `evaluate`
181+
182+
Run arbitrary JavaScript in the browser context. Use as an escape hatch for DOM manipulation not covered by other actions: removing elements, changing styles, modifying text, or setting up complex page state.
183+
184+
| Property | Type | Required | Description |
185+
| ---------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------- |
186+
| `function` | string | yes | JavaScript function to evaluate. Use () => { ... } for page-level, or (el) => { ... } when selector is provided. |
187+
| `selector` | string | no | CSS selector of element to pass as the first argument to the function |
188+
189+
```json
190+
// minimal
191+
{
192+
"type": "evaluate",
193+
"function": "() => { document.querySelector(\".ad\").remove() }"
194+
}
195+
196+
// with options
197+
{
198+
"type": "evaluate",
199+
"function": "() => { document.querySelector(\".ad\").remove() }",
200+
"selector": ".my-element"
201+
}
202+
```
203+
204+
### `fill_form`
205+
206+
Fill multiple form fields in one action. Supports text inputs, checkboxes, radio buttons, dropdowns (combobox), and sliders. Use to show a completed form state in screenshots.
207+
208+
| Property | Type | Required | Description |
209+
| ---------------------- | ---------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------- |
210+
| `fields` | object[] | yes | Array of fields to fill |
211+
|`fields[].selector` | string | yes | CSS selector of the form field |
212+
|`fields[].value` | string | yes | Value to fill. For checkboxes use "true"/"false". For combobox use the option label text. |
213+
|`fields[].fieldType` | `"textbox"` \| `"checkbox"` \| `"radio"` \| `"combobox"` \| `"slider"` | yes | Type of the form field |
214+
215+
```json
216+
{
217+
"type": "fill_form",
218+
"fields": [
219+
{
220+
"selector": "#email",
221+
"value": "[email protected]",
222+
"fieldType": "textbox"
223+
}
224+
]
225+
}
226+
```
227+
228+
### `handle_dialog`
229+
230+
Set up a handler for the next browser dialog (alert, confirm, or prompt). Place this action BEFORE the action that triggers the dialog. It will automatically accept or dismiss when the dialog appears.
231+
232+
| Property | Type | Required | Description |
233+
| ------------ | ------- | -------- | ---------------------------------------- |
234+
| `accept` | boolean | yes | Whether to accept the dialog |
235+
| `promptText` | string | no | Text to enter in case of a prompt dialog |
236+
237+
```json
238+
// minimal
239+
{
240+
"type": "handle_dialog",
241+
"accept": true
242+
}
243+
244+
// with options
245+
{
246+
"type": "handle_dialog",
247+
"accept": true,
248+
"promptText": "my answer"
249+
}
250+
```
251+
252+
### `file_upload`
253+
254+
Upload one or more files through a file input element. Use to show file upload previews, populated upload zones, or attachment states.
255+
256+
| Property | Type | Required | Description |
257+
| ---------- | -------- | -------- | ---------------------------------------------------------- |
258+
| `selector` | string | yes | CSS selector of the file input element |
259+
| `paths` | string[] | yes | File paths to upload (absolute or relative to config file) |
260+
261+
```json
262+
{
263+
"type": "file_upload",
264+
"selector": ".my-element",
265+
"paths": ["./screenshot.png"]
266+
}
267+
```
268+
269+
### `resize`
270+
271+
Resize the browser viewport mid-flow. Use when you need a different viewport for a specific action (e.g. trigger responsive breakpoints) before capturing.
272+
273+
| Property | Type | Required | Description |
274+
| -------- | ------ | -------- | ------------------------- |
275+
| `width` | number | yes | Viewport width in pixels |
276+
| `height` | number | yes | Viewport height in pixels |
277+
278+
```json
279+
{
280+
"type": "resize",
281+
"width": 375,
282+
"height": 667
283+
}
284+
```

docs/docs/browser-reference.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
description: All browser configuration options for viewport, color scheme, and device scale.
3+
---
4+
5+
# Browser Settings Reference
6+
7+
Back to [Configuration overview](./config#browser-settings).
8+
9+
| Property | Type | Default | Description |
10+
| ------------------- | --------------------- | ------- | ---------------------------------------------------------------------- |
11+
| `viewport` | object | - | Browser viewport dimensions |
12+
|`viewport.width` | number | `1280` | Browser viewport width in pixels |
13+
|`viewport.height` | number | `800` | Browser viewport height in pixels |
14+
| `colorScheme` | `"light"` \| `"dark"` | - | Color scheme for capture. Omit to capture both light and dark variants |
15+
| `deviceScaleFactor` | number | - | Device pixel ratio (1 = standard, 2 = retina, 3 = ultra-high DPI) |
16+
17+
## Example
18+
19+
```json
20+
{
21+
"viewport": {},
22+
"colorScheme": "light",
23+
"deviceScaleFactor": 2
24+
}
25+
```

0 commit comments

Comments
 (0)