screencli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/agent/loop.d.ts +21 -0
- package/dist/src/agent/loop.d.ts.map +1 -0
- package/dist/src/agent/loop.js +119 -0
- package/dist/src/agent/loop.js.map +1 -0
- package/dist/src/agent/system-prompt.d.ts +2 -0
- package/dist/src/agent/system-prompt.d.ts.map +1 -0
- package/dist/src/agent/system-prompt.js +43 -0
- package/dist/src/agent/system-prompt.js.map +1 -0
- package/dist/src/agent/tool-handlers.d.ts +44 -0
- package/dist/src/agent/tool-handlers.d.ts.map +1 -0
- package/dist/src/agent/tool-handlers.js +242 -0
- package/dist/src/agent/tool-handlers.js.map +1 -0
- package/dist/src/agent/tools.d.ts +5 -0
- package/dist/src/agent/tools.d.ts.map +1 -0
- package/dist/src/agent/tools.js +251 -0
- package/dist/src/agent/tools.js.map +1 -0
- package/dist/src/browser/accessibility.d.ts +28 -0
- package/dist/src/browser/accessibility.d.ts.map +1 -0
- package/dist/src/browser/accessibility.js +47 -0
- package/dist/src/browser/accessibility.js.map +1 -0
- package/dist/src/browser/actions.d.ts +32 -0
- package/dist/src/browser/actions.d.ts.map +1 -0
- package/dist/src/browser/actions.js +122 -0
- package/dist/src/browser/actions.js.map +1 -0
- package/dist/src/browser/auth.d.ts +12 -0
- package/dist/src/browser/auth.d.ts.map +1 -0
- package/dist/src/browser/auth.js +53 -0
- package/dist/src/browser/auth.js.map +1 -0
- package/dist/src/browser/resolve-locator.d.ts +15 -0
- package/dist/src/browser/resolve-locator.d.ts.map +1 -0
- package/dist/src/browser/resolve-locator.js +27 -0
- package/dist/src/browser/resolve-locator.js.map +1 -0
- package/dist/src/browser/session.d.ts +16 -0
- package/dist/src/browser/session.d.ts.map +1 -0
- package/dist/src/browser/session.js +47 -0
- package/dist/src/browser/session.js.map +1 -0
- package/dist/src/cli/commands/export.d.ts +3 -0
- package/dist/src/cli/commands/export.d.ts.map +1 -0
- package/dist/src/cli/commands/export.js +76 -0
- package/dist/src/cli/commands/export.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts +8 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -0
- package/dist/src/cli/commands/init.js +64 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/record.d.ts +3 -0
- package/dist/src/cli/commands/record.d.ts.map +1 -0
- package/dist/src/cli/commands/record.js +215 -0
- package/dist/src/cli/commands/record.js.map +1 -0
- package/dist/src/cli/options.d.ts +24 -0
- package/dist/src/cli/options.d.ts.map +1 -0
- package/dist/src/cli/options.js +35 -0
- package/dist/src/cli/options.js.map +1 -0
- package/dist/src/cli/output.d.ts +10 -0
- package/dist/src/cli/output.d.ts.map +1 -0
- package/dist/src/cli/output.js +29 -0
- package/dist/src/cli/output.js.map +1 -0
- package/dist/src/export/exporter.d.ts +16 -0
- package/dist/src/export/exporter.d.ts.map +1 -0
- package/dist/src/export/exporter.js +66 -0
- package/dist/src/export/exporter.js.map +1 -0
- package/dist/src/export/gif.d.ts +3 -0
- package/dist/src/export/gif.d.ts.map +1 -0
- package/dist/src/export/gif.js +36 -0
- package/dist/src/export/gif.js.map +1 -0
- package/dist/src/export/presets.d.ts +4 -0
- package/dist/src/export/presets.d.ts.map +1 -0
- package/dist/src/export/presets.js +68 -0
- package/dist/src/export/presets.js.map +1 -0
- package/dist/src/export/smart-crop.d.ts +10 -0
- package/dist/src/export/smart-crop.d.ts.map +1 -0
- package/dist/src/export/smart-crop.js +50 -0
- package/dist/src/export/smart-crop.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/recording/chapters.d.ts +3 -0
- package/dist/src/recording/chapters.d.ts.map +1 -0
- package/dist/src/recording/chapters.js +37 -0
- package/dist/src/recording/chapters.js.map +1 -0
- package/dist/src/recording/event-log.d.ts +20 -0
- package/dist/src/recording/event-log.d.ts.map +1 -0
- package/dist/src/recording/event-log.js +37 -0
- package/dist/src/recording/event-log.js.map +1 -0
- package/dist/src/recording/metadata.d.ts +4 -0
- package/dist/src/recording/metadata.d.ts.map +1 -0
- package/dist/src/recording/metadata.js +8 -0
- package/dist/src/recording/metadata.js.map +1 -0
- package/dist/src/recording/types.d.ts +81 -0
- package/dist/src/recording/types.d.ts.map +1 -0
- package/dist/src/recording/types.js +2 -0
- package/dist/src/recording/types.js.map +1 -0
- package/dist/src/utils/config.d.ts +13 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/config.js +37 -0
- package/dist/src/utils/config.js.map +1 -0
- package/dist/src/utils/errors.d.ts +20 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +39 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/logger.d.ts +9 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +40 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/paths.d.ts +9 -0
- package/dist/src/utils/paths.d.ts.map +1 -0
- package/dist/src/utils/paths.js +28 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/video/background.d.ts +39 -0
- package/dist/src/video/background.d.ts.map +1 -0
- package/dist/src/video/background.js +141 -0
- package/dist/src/video/background.js.map +1 -0
- package/dist/src/video/compose.d.ts +14 -0
- package/dist/src/video/compose.d.ts.map +1 -0
- package/dist/src/video/compose.js +149 -0
- package/dist/src/video/compose.js.map +1 -0
- package/dist/src/video/cursor.d.ts +10 -0
- package/dist/src/video/cursor.d.ts.map +1 -0
- package/dist/src/video/cursor.js +31 -0
- package/dist/src/video/cursor.js.map +1 -0
- package/dist/src/video/ffmpeg.d.ts +10 -0
- package/dist/src/video/ffmpeg.d.ts.map +1 -0
- package/dist/src/video/ffmpeg.js +71 -0
- package/dist/src/video/ffmpeg.js.map +1 -0
- package/dist/src/video/highlight.d.ts +3 -0
- package/dist/src/video/highlight.d.ts.map +1 -0
- package/dist/src/video/highlight.js +21 -0
- package/dist/src/video/highlight.js.map +1 -0
- package/dist/src/video/trim.d.ts +19 -0
- package/dist/src/video/trim.d.ts.map +1 -0
- package/dist/src/video/trim.js +47 -0
- package/dist/src/video/trim.js.map +1 -0
- package/dist/src/video/zoom.d.ts +11 -0
- package/dist/src/video/zoom.d.ts.map +1 -0
- package/dist/src/video/zoom.js +88 -0
- package/dist/src/video/zoom.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
const elementTargetProps = {
|
|
2
|
+
role: { type: 'string', description: 'ARIA role (e.g. "button", "link", "textbox"). Preferred targeting method.' },
|
|
3
|
+
name: { type: 'string', description: 'Accessible name of the element. Use with role.' },
|
|
4
|
+
text: { type: 'string', description: 'Visible text content to match. Fallback if role+name unavailable.' },
|
|
5
|
+
selector: { type: 'string', description: 'CSS selector. Last resort.' },
|
|
6
|
+
};
|
|
7
|
+
export const tools = [
|
|
8
|
+
// Observation tools
|
|
9
|
+
{
|
|
10
|
+
name: 'screenshot',
|
|
11
|
+
description: 'Capture a screenshot of the current viewport. Use to observe the page state.',
|
|
12
|
+
input_schema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {},
|
|
15
|
+
required: [],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'get_accessibility_tree',
|
|
20
|
+
description: 'Get the ARIA accessibility tree of the page. Shows all interactive elements with roles and names. Use this to identify elements to interact with.',
|
|
21
|
+
input_schema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {},
|
|
24
|
+
required: [],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'get_page_info',
|
|
29
|
+
description: 'Get current page URL, title, viewport size, and loading state.',
|
|
30
|
+
input_schema: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {},
|
|
33
|
+
required: [],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
// Action tools
|
|
37
|
+
{
|
|
38
|
+
name: 'click',
|
|
39
|
+
description: 'Click an element on the page. Returns a screenshot after clicking.',
|
|
40
|
+
input_schema: {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
...elementTargetProps,
|
|
44
|
+
click_type: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: ['left', 'right', 'double'],
|
|
47
|
+
description: 'Type of click. Default: left.',
|
|
48
|
+
},
|
|
49
|
+
description: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: 'Human-readable description of what this click does. Required.',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
required: ['description'],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'type',
|
|
59
|
+
description: 'Type text into an input element. Returns a screenshot after typing.',
|
|
60
|
+
input_schema: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
properties: {
|
|
63
|
+
...elementTargetProps,
|
|
64
|
+
text: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'The text to type (overrides text-targeting if also used for element matching).',
|
|
67
|
+
},
|
|
68
|
+
target_text: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Text content to match for element targeting (when "text" is used for the value to type).',
|
|
71
|
+
},
|
|
72
|
+
clear_first: {
|
|
73
|
+
type: 'boolean',
|
|
74
|
+
description: 'Clear the input before typing. Default: false.',
|
|
75
|
+
},
|
|
76
|
+
character_by_character: {
|
|
77
|
+
type: 'boolean',
|
|
78
|
+
description: 'Type one character at a time with delay. Default: false.',
|
|
79
|
+
},
|
|
80
|
+
description: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: 'Human-readable description of what this typing does. Required.',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
required: ['text', 'description'],
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'press_key',
|
|
90
|
+
description: 'Press a keyboard key or key combination. Examples: "Enter", "Tab", "Control+a", "Meta+c".',
|
|
91
|
+
input_schema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
key: {
|
|
95
|
+
type: 'string',
|
|
96
|
+
description: 'Key or key combination to press.',
|
|
97
|
+
},
|
|
98
|
+
description: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
description: 'Human-readable description of what this key press does. Required.',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
required: ['key', 'description'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'scroll',
|
|
108
|
+
description: 'Scroll the page or scroll to a specific element.',
|
|
109
|
+
input_schema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
direction: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
enum: ['up', 'down', 'left', 'right'],
|
|
115
|
+
description: 'Scroll direction. Used with amount.',
|
|
116
|
+
},
|
|
117
|
+
amount: {
|
|
118
|
+
type: 'number',
|
|
119
|
+
description: 'Pixels to scroll. Default: 500.',
|
|
120
|
+
},
|
|
121
|
+
to_role: { type: 'string', description: 'Scroll to element with this ARIA role.' },
|
|
122
|
+
to_name: { type: 'string', description: 'Scroll to element with this accessible name.' },
|
|
123
|
+
to_text: { type: 'string', description: 'Scroll to element containing this text.' },
|
|
124
|
+
to_selector: { type: 'string', description: 'Scroll to element matching this CSS selector.' },
|
|
125
|
+
description: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
description: 'Human-readable description. Required.',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
required: ['description'],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'hover',
|
|
135
|
+
description: 'Hover over an element to reveal tooltips, menus, etc. Returns a screenshot.',
|
|
136
|
+
input_schema: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
...elementTargetProps,
|
|
140
|
+
description: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
description: 'Human-readable description. Required.',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
required: ['description'],
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'navigate',
|
|
150
|
+
description: 'Navigate to a URL.',
|
|
151
|
+
input_schema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
url: {
|
|
155
|
+
type: 'string',
|
|
156
|
+
description: 'The URL to navigate to.',
|
|
157
|
+
},
|
|
158
|
+
description: {
|
|
159
|
+
type: 'string',
|
|
160
|
+
description: 'Human-readable description. Required.',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
required: ['url', 'description'],
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'wait',
|
|
168
|
+
description: 'Wait for a condition: time, element visible/hidden, or network idle.',
|
|
169
|
+
input_schema: {
|
|
170
|
+
type: 'object',
|
|
171
|
+
properties: {
|
|
172
|
+
time: {
|
|
173
|
+
type: 'number',
|
|
174
|
+
description: 'Milliseconds to wait.',
|
|
175
|
+
},
|
|
176
|
+
element_visible: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: elementTargetProps,
|
|
179
|
+
description: 'Wait for this element to become visible.',
|
|
180
|
+
},
|
|
181
|
+
element_hidden: {
|
|
182
|
+
type: 'object',
|
|
183
|
+
properties: elementTargetProps,
|
|
184
|
+
description: 'Wait for this element to become hidden.',
|
|
185
|
+
},
|
|
186
|
+
network_idle: {
|
|
187
|
+
type: 'boolean',
|
|
188
|
+
description: 'Wait for network to be idle.',
|
|
189
|
+
},
|
|
190
|
+
description: {
|
|
191
|
+
type: 'string',
|
|
192
|
+
description: 'Human-readable description. Required.',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
required: ['description'],
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: 'select_option',
|
|
200
|
+
description: 'Select an option from a dropdown/select element.',
|
|
201
|
+
input_schema: {
|
|
202
|
+
type: 'object',
|
|
203
|
+
properties: {
|
|
204
|
+
...elementTargetProps,
|
|
205
|
+
option_label: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'The visible label of the option to select.',
|
|
208
|
+
},
|
|
209
|
+
option_value: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
description: 'The value attribute of the option to select.',
|
|
212
|
+
},
|
|
213
|
+
description: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
description: 'Human-readable description. Required.',
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
required: ['description'],
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
// Control tools
|
|
222
|
+
{
|
|
223
|
+
name: 'done',
|
|
224
|
+
description: 'Signal that the task is complete. Call this when you have finished all actions.',
|
|
225
|
+
input_schema: {
|
|
226
|
+
type: 'object',
|
|
227
|
+
properties: {
|
|
228
|
+
summary: {
|
|
229
|
+
type: 'string',
|
|
230
|
+
description: 'Summary of what was accomplished.',
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
required: ['summary'],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: 'narrate',
|
|
238
|
+
description: 'Add a narration caption/subtitle at the current timestamp. Use before major sections to label what is happening for the viewer.',
|
|
239
|
+
input_schema: {
|
|
240
|
+
type: 'object',
|
|
241
|
+
properties: {
|
|
242
|
+
text: {
|
|
243
|
+
type: 'string',
|
|
244
|
+
description: 'Narration text to display.',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
required: ['text'],
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/agent/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
export interface AccessibilityNode {
|
|
3
|
+
role: string;
|
|
4
|
+
name: string;
|
|
5
|
+
children?: AccessibilityNode[];
|
|
6
|
+
value?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
checked?: boolean | 'mixed';
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
expanded?: boolean;
|
|
11
|
+
level?: number;
|
|
12
|
+
pressed?: boolean | 'mixed';
|
|
13
|
+
selected?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function getAccessibilityTree(page: Page): Promise<{
|
|
16
|
+
tree: string;
|
|
17
|
+
elementCount: number;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function getPageInfo(page: Page): Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
title: string;
|
|
22
|
+
viewport: {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
};
|
|
26
|
+
loading: boolean;
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=accessibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../../../src/browser/accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CA4BD;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAeD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export async function getAccessibilityTree(page) {
|
|
2
|
+
// Use Playwright's ariaSnapshot for modern versions, fall back to locator-based approach
|
|
3
|
+
try {
|
|
4
|
+
const snapshot = await page.locator('body').ariaSnapshot();
|
|
5
|
+
const lineCount = snapshot.split('\n').length;
|
|
6
|
+
return { tree: snapshot, elementCount: lineCount };
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
// Fallback: use page.evaluate with string function to avoid DOM type issues
|
|
10
|
+
const tree = await page.evaluate(`
|
|
11
|
+
(function() {
|
|
12
|
+
function walk(el, depth) {
|
|
13
|
+
var role = el.getAttribute('role') || el.tagName.toLowerCase();
|
|
14
|
+
var name = el.getAttribute('aria-label') || el.getAttribute('title') || (el.innerText || '').slice(0, 50);
|
|
15
|
+
var prefix = ' '.repeat(depth);
|
|
16
|
+
var line = prefix + '- ' + role;
|
|
17
|
+
if (name) line += ' "' + name.replace(/"/g, '\\\\"') + '"';
|
|
18
|
+
var lines = [line];
|
|
19
|
+
for (var i = 0; i < el.children.length; i++) {
|
|
20
|
+
lines.push(walk(el.children[i], depth + 1));
|
|
21
|
+
}
|
|
22
|
+
return lines.join('\\n');
|
|
23
|
+
}
|
|
24
|
+
return walk(document.body, 0);
|
|
25
|
+
})()
|
|
26
|
+
`);
|
|
27
|
+
const lineCount = tree.split('\n').length;
|
|
28
|
+
return { tree, elementCount: lineCount };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function getPageInfo(page) {
|
|
32
|
+
const viewport = page.viewportSize() ?? { width: 0, height: 0 };
|
|
33
|
+
let loading = false;
|
|
34
|
+
try {
|
|
35
|
+
loading = await page.evaluate(`document.readyState !== 'complete'`);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
loading = true;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
url: page.url(),
|
|
42
|
+
title: await page.title(),
|
|
43
|
+
viewport,
|
|
44
|
+
loading,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=accessibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../../src/browser/accessibility.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAU;IAInD,yFAAyF;IACzF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;QAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC9C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;;;;;;;;;;;;;;;;KAgBhC,CAAW,CAAC;QACb,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAU;IAM1C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAChE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,oCAAoC,CAAY,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;QACf,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE;QACzB,QAAQ;QACR,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import { type ElementTarget } from './resolve-locator.js';
|
|
3
|
+
import type { BoundingBox } from '../recording/types.js';
|
|
4
|
+
export interface ActionResult {
|
|
5
|
+
bounding_box?: BoundingBox;
|
|
6
|
+
screenshot: Buffer;
|
|
7
|
+
url: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function click(page: Page, target: ElementTarget, clickType?: 'left' | 'right' | 'double', delayMs?: number): Promise<ActionResult>;
|
|
10
|
+
export declare function type(page: Page, target: ElementTarget, text: string, options?: {
|
|
11
|
+
clearFirst?: boolean;
|
|
12
|
+
characterByCharacter?: boolean;
|
|
13
|
+
}, delayMs?: number): Promise<ActionResult>;
|
|
14
|
+
export declare function pressKey(page: Page, key: string, delayMs?: number): Promise<ActionResult>;
|
|
15
|
+
export declare function scroll(page: Page, options: {
|
|
16
|
+
direction?: 'up' | 'down' | 'left' | 'right';
|
|
17
|
+
amount?: number;
|
|
18
|
+
toElement?: ElementTarget;
|
|
19
|
+
}, delayMs?: number): Promise<ActionResult>;
|
|
20
|
+
export declare function hover(page: Page, target: ElementTarget, delayMs?: number): Promise<ActionResult>;
|
|
21
|
+
export declare function navigate(page: Page, url: string, delayMs?: number): Promise<ActionResult>;
|
|
22
|
+
export declare function waitFor(page: Page, condition: {
|
|
23
|
+
time?: number;
|
|
24
|
+
elementVisible?: ElementTarget;
|
|
25
|
+
elementHidden?: ElementTarget;
|
|
26
|
+
networkIdle?: boolean;
|
|
27
|
+
}): Promise<ActionResult>;
|
|
28
|
+
export declare function selectOption(page: Page, target: ElementTarget, option: {
|
|
29
|
+
label?: string;
|
|
30
|
+
value?: string;
|
|
31
|
+
}, delayMs?: number): Promise<ActionResult>;
|
|
32
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/browser/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAkC,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAOD,wBAAsB,KAAK,CACzB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,SAAS,GAAE,MAAM,GAAG,OAAO,GAAG,QAAiB,EAC/C,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAavB;AAED,wBAAsB,IAAI,CACxB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAO,EACtE,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED,wBAAsB,MAAM,CAC1B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IACP,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B,EACD,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAiCvB;AAED,wBAAsB,KAAK,CACzB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAQvB;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED,wBAAsB,OAAO,CAC3B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE;IACT,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC,YAAY,CAAC,CAiBvB;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1C,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,YAAY,CAAC,CAavB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { resolveLocator, getBoundingBox } from './resolve-locator.js';
|
|
2
|
+
async function captureState(page) {
|
|
3
|
+
const screenshot = await page.screenshot({ type: 'png' });
|
|
4
|
+
return { screenshot, url: page.url() };
|
|
5
|
+
}
|
|
6
|
+
export async function click(page, target, clickType = 'left', delayMs = 0) {
|
|
7
|
+
const locator = resolveLocator(page, target);
|
|
8
|
+
const bounding_box = await getBoundingBox(locator);
|
|
9
|
+
if (clickType === 'double') {
|
|
10
|
+
await locator.dblclick({ timeout: 10000 });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
await locator.click({ button: clickType, timeout: 10000 });
|
|
14
|
+
}
|
|
15
|
+
if (delayMs > 0)
|
|
16
|
+
await page.waitForTimeout(delayMs);
|
|
17
|
+
const state = await captureState(page);
|
|
18
|
+
return { bounding_box, ...state };
|
|
19
|
+
}
|
|
20
|
+
export async function type(page, target, text, options = {}, delayMs = 0) {
|
|
21
|
+
const locator = resolveLocator(page, target);
|
|
22
|
+
const bounding_box = await getBoundingBox(locator);
|
|
23
|
+
if (options.clearFirst) {
|
|
24
|
+
await locator.clear({ timeout: 10000 });
|
|
25
|
+
}
|
|
26
|
+
if (options.characterByCharacter) {
|
|
27
|
+
await locator.pressSequentially(text, { delay: 50, timeout: 30000 });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
await locator.fill(text, { timeout: 10000 });
|
|
31
|
+
}
|
|
32
|
+
if (delayMs > 0)
|
|
33
|
+
await page.waitForTimeout(delayMs);
|
|
34
|
+
const state = await captureState(page);
|
|
35
|
+
return { bounding_box, ...state };
|
|
36
|
+
}
|
|
37
|
+
export async function pressKey(page, key, delayMs = 0) {
|
|
38
|
+
await page.keyboard.press(key);
|
|
39
|
+
if (delayMs > 0)
|
|
40
|
+
await page.waitForTimeout(delayMs);
|
|
41
|
+
const state = await captureState(page);
|
|
42
|
+
return { ...state };
|
|
43
|
+
}
|
|
44
|
+
export async function scroll(page, options, delayMs = 0) {
|
|
45
|
+
let bounding_box;
|
|
46
|
+
if (options.toElement) {
|
|
47
|
+
const locator = resolveLocator(page, options.toElement);
|
|
48
|
+
bounding_box = await getBoundingBox(locator);
|
|
49
|
+
await locator.scrollIntoViewIfNeeded({ timeout: 10000 });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const amount = options.amount ?? 500;
|
|
53
|
+
const deltaX = options.direction === 'left' ? -amount : options.direction === 'right' ? amount : 0;
|
|
54
|
+
const deltaY = options.direction === 'up' ? -amount : options.direction === 'down' ? amount : 0;
|
|
55
|
+
// Smooth scroll: break into small increments over ~400ms
|
|
56
|
+
const STEP_PX = 40;
|
|
57
|
+
const STEP_DELAY_MS = 16; // ~60fps
|
|
58
|
+
const totalX = Math.abs(deltaX);
|
|
59
|
+
const totalY = Math.abs(deltaY);
|
|
60
|
+
const total = Math.max(totalX, totalY);
|
|
61
|
+
const steps = Math.max(1, Math.ceil(total / STEP_PX));
|
|
62
|
+
const stepX = deltaX / steps;
|
|
63
|
+
const stepY = deltaY / steps;
|
|
64
|
+
for (let i = 0; i < steps; i++) {
|
|
65
|
+
await page.mouse.wheel(stepX, stepY);
|
|
66
|
+
await page.waitForTimeout(STEP_DELAY_MS);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (delayMs > 0)
|
|
70
|
+
await page.waitForTimeout(delayMs);
|
|
71
|
+
const state = await captureState(page);
|
|
72
|
+
return { bounding_box, ...state };
|
|
73
|
+
}
|
|
74
|
+
export async function hover(page, target, delayMs = 0) {
|
|
75
|
+
const locator = resolveLocator(page, target);
|
|
76
|
+
const bounding_box = await getBoundingBox(locator);
|
|
77
|
+
await locator.hover({ timeout: 10000 });
|
|
78
|
+
if (delayMs > 0)
|
|
79
|
+
await page.waitForTimeout(delayMs);
|
|
80
|
+
const state = await captureState(page);
|
|
81
|
+
return { bounding_box, ...state };
|
|
82
|
+
}
|
|
83
|
+
export async function navigate(page, url, delayMs = 0) {
|
|
84
|
+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
85
|
+
if (delayMs > 0)
|
|
86
|
+
await page.waitForTimeout(delayMs);
|
|
87
|
+
const state = await captureState(page);
|
|
88
|
+
return { ...state };
|
|
89
|
+
}
|
|
90
|
+
export async function waitFor(page, condition) {
|
|
91
|
+
if (condition.time) {
|
|
92
|
+
await page.waitForTimeout(condition.time);
|
|
93
|
+
}
|
|
94
|
+
if (condition.elementVisible) {
|
|
95
|
+
const locator = resolveLocator(page, condition.elementVisible);
|
|
96
|
+
await locator.waitFor({ state: 'visible', timeout: 15000 });
|
|
97
|
+
}
|
|
98
|
+
if (condition.elementHidden) {
|
|
99
|
+
const locator = resolveLocator(page, condition.elementHidden);
|
|
100
|
+
await locator.waitFor({ state: 'hidden', timeout: 15000 });
|
|
101
|
+
}
|
|
102
|
+
if (condition.networkIdle) {
|
|
103
|
+
await page.waitForLoadState('networkidle', { timeout: 15000 });
|
|
104
|
+
}
|
|
105
|
+
const state = await captureState(page);
|
|
106
|
+
return { ...state };
|
|
107
|
+
}
|
|
108
|
+
export async function selectOption(page, target, option, delayMs = 0) {
|
|
109
|
+
const locator = resolveLocator(page, target);
|
|
110
|
+
const bounding_box = await getBoundingBox(locator);
|
|
111
|
+
if (option.label) {
|
|
112
|
+
await locator.selectOption({ label: option.label }, { timeout: 10000 });
|
|
113
|
+
}
|
|
114
|
+
else if (option.value) {
|
|
115
|
+
await locator.selectOption({ value: option.value }, { timeout: 10000 });
|
|
116
|
+
}
|
|
117
|
+
if (delayMs > 0)
|
|
118
|
+
await page.waitForTimeout(delayMs);
|
|
119
|
+
const state = await captureState(page);
|
|
120
|
+
return { bounding_box, ...state };
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/browser/actions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAS1F,KAAK,UAAU,YAAY,CAAC,IAAU;IACpC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAU,EACV,MAAqB,EACrB,YAAyC,MAAM,EAC/C,UAAkB,CAAC;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAEnD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,IAAU,EACV,MAAqB,EACrB,IAAY,EACZ,UAAoE,EAAE,EACtE,UAAkB,CAAC;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAEnD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACjC,MAAM,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAU,EACV,GAAW,EACX,UAAkB,CAAC;IAEnB,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,IAAU,EACV,OAIC,EACD,UAAkB,CAAC;IAEnB,IAAI,YAAqC,CAAC;IAE1C,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACxD,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,OAAO,CAAC,sBAAsB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;QACrC,MAAM,MAAM,GACV,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,MAAM,GACV,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnF,yDAAyD;QACzD,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,EAAE,CAAC,CAAC,SAAS;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;QAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrC,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAU,EACV,MAAqB,EACrB,UAAkB,CAAC;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAExC,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAU,EACV,GAAW,EACX,UAAkB,CAAC;IAEnB,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAU,EACV,SAKC;IAED,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,SAAS,CAAC,cAAc,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;QAC/D,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9D,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAU,EACV,MAAqB,EACrB,MAA0C,EAC1C,UAAkB,CAAC;IAEnB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IAEnD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;SAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Viewport } from '../recording/types.js';
|
|
2
|
+
export declare function authStatePath(name: string): string;
|
|
3
|
+
export declare function hasAuthState(name: string): boolean;
|
|
4
|
+
export declare function saveAuthState(name: string, state: object): void;
|
|
5
|
+
export declare function loadAuthState(name: string): object | null;
|
|
6
|
+
/**
|
|
7
|
+
* Open a visible browser for the user to log in manually.
|
|
8
|
+
* Returns the Playwright storageState (cookies, localStorage, sessionStorage)
|
|
9
|
+
* after the user presses Enter in the terminal.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runLoginFlow(url: string, viewport: Viewport): Promise<object>;
|
|
12
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/browser/auth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKtD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzD;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBnF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { chromium } from 'playwright';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { createInterface } from 'node:readline';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
const AUTH_DIR = join(homedir(), '.screencli', 'auth');
|
|
8
|
+
export function authStatePath(name) {
|
|
9
|
+
return join(AUTH_DIR, `${name}.json`);
|
|
10
|
+
}
|
|
11
|
+
export function hasAuthState(name) {
|
|
12
|
+
return existsSync(authStatePath(name));
|
|
13
|
+
}
|
|
14
|
+
export function saveAuthState(name, state) {
|
|
15
|
+
mkdirSync(AUTH_DIR, { recursive: true });
|
|
16
|
+
writeFileSync(authStatePath(name), JSON.stringify(state, null, 2));
|
|
17
|
+
logger.info(`Auth state saved to ${authStatePath(name)}`);
|
|
18
|
+
}
|
|
19
|
+
export function loadAuthState(name) {
|
|
20
|
+
const path = authStatePath(name);
|
|
21
|
+
if (!existsSync(path))
|
|
22
|
+
return null;
|
|
23
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Open a visible browser for the user to log in manually.
|
|
27
|
+
* Returns the Playwright storageState (cookies, localStorage, sessionStorage)
|
|
28
|
+
* after the user presses Enter in the terminal.
|
|
29
|
+
*/
|
|
30
|
+
export async function runLoginFlow(url, viewport) {
|
|
31
|
+
const browser = await chromium.launch({ headless: false });
|
|
32
|
+
const context = await browser.newContext({
|
|
33
|
+
viewport,
|
|
34
|
+
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
35
|
+
});
|
|
36
|
+
const page = await context.newPage();
|
|
37
|
+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
38
|
+
await waitForEnter();
|
|
39
|
+
const state = await context.storageState();
|
|
40
|
+
await context.close();
|
|
41
|
+
await browser.close();
|
|
42
|
+
return state;
|
|
43
|
+
}
|
|
44
|
+
function waitForEnter() {
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
47
|
+
rl.question('', () => {
|
|
48
|
+
rl.close();
|
|
49
|
+
resolve();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/browser/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;AAEvD,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,CAAC,uBAAuB,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,QAAkB;IAChE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ;QACR,SAAS,EACP,uHAAuH;KAC1H,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAErC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAExE,MAAM,YAAY,EAAE,CAAC;IAErB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;IAC3C,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IAEtB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE;YACnB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Page, Locator } from 'playwright';
|
|
2
|
+
export interface ElementTarget {
|
|
3
|
+
role?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
selector?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveLocator(page: Page, target: ElementTarget): Locator;
|
|
9
|
+
export declare function getBoundingBox(locator: Locator): Promise<{
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
} | undefined>;
|
|
15
|
+
//# sourceMappingURL=resolve-locator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-locator.d.ts","sourceRoot":"","sources":["../../../src/browser/resolve-locator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAczE;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAQ9E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function resolveLocator(page, target) {
|
|
2
|
+
if (target.role && target.name) {
|
|
3
|
+
return page.getByRole(target.role, { name: target.name });
|
|
4
|
+
}
|
|
5
|
+
if (target.role) {
|
|
6
|
+
return page.getByRole(target.role);
|
|
7
|
+
}
|
|
8
|
+
if (target.text) {
|
|
9
|
+
return page.getByText(target.text);
|
|
10
|
+
}
|
|
11
|
+
if (target.selector) {
|
|
12
|
+
return page.locator(target.selector);
|
|
13
|
+
}
|
|
14
|
+
throw new Error('No valid target provided. Use role+name, text, or selector.');
|
|
15
|
+
}
|
|
16
|
+
export async function getBoundingBox(locator) {
|
|
17
|
+
try {
|
|
18
|
+
const box = await locator.boundingBox({ timeout: 3000 });
|
|
19
|
+
if (!box)
|
|
20
|
+
return undefined;
|
|
21
|
+
return { x: box.x, y: box.y, width: box.width, height: box.height };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=resolve-locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-locator.js","sourceRoot":"","sources":["../../../src/browser/resolve-locator.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,cAAc,CAAC,IAAU,EAAE,MAAqB;IAC9D,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAW,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAW,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|