digital-workers 2.1.1 → 2.3.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/CHANGELOG.md +23 -0
- package/README.md +136 -180
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +34 -21
- package/dist/actions.js.map +1 -1
- package/dist/agent-comms.d.ts +438 -0
- package/dist/agent-comms.d.ts.map +1 -0
- package/dist/agent-comms.js +677 -0
- package/dist/agent-comms.js.map +1 -0
- package/dist/approve.d.ts +40 -8
- package/dist/approve.d.ts.map +1 -1
- package/dist/approve.js +86 -20
- package/dist/approve.js.map +1 -1
- package/dist/ask.d.ts +38 -7
- package/dist/ask.d.ts.map +1 -1
- package/dist/ask.js +85 -25
- package/dist/ask.js.map +1 -1
- package/dist/browse.d.ts +223 -0
- package/dist/browse.d.ts.map +1 -0
- package/dist/browse.js +392 -0
- package/dist/browse.js.map +1 -0
- package/dist/capability-tiers.d.ts +230 -0
- package/dist/capability-tiers.d.ts.map +1 -0
- package/dist/capability-tiers.js +388 -0
- package/dist/capability-tiers.js.map +1 -0
- package/dist/cascade-context.d.ts +523 -0
- package/dist/cascade-context.d.ts.map +1 -0
- package/dist/cascade-context.js +494 -0
- package/dist/cascade-context.js.map +1 -0
- package/dist/client.d.ts +162 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +64 -0
- package/dist/client.js.map +1 -0
- package/dist/decide.d.ts +42 -6
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +54 -11
- package/dist/decide.js.map +1 -1
- package/dist/do.d.ts +36 -7
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +82 -39
- package/dist/do.js.map +1 -1
- package/dist/error-escalation.d.ts +416 -0
- package/dist/error-escalation.d.ts.map +1 -0
- package/dist/error-escalation.js +656 -0
- package/dist/error-escalation.js.map +1 -0
- package/dist/generate.d.ts +48 -7
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +49 -8
- package/dist/generate.js.map +1 -1
- package/dist/goals.d.ts +10 -9
- package/dist/goals.d.ts.map +1 -1
- package/dist/goals.js +30 -24
- package/dist/goals.js.map +1 -1
- package/dist/image.d.ts +189 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +528 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +59 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -2
- package/dist/index.js.map +1 -1
- package/dist/is.d.ts +45 -10
- package/dist/is.d.ts.map +1 -1
- package/dist/is.js +56 -21
- package/dist/is.js.map +1 -1
- package/dist/kpis.d.ts +24 -15
- package/dist/kpis.d.ts.map +1 -1
- package/dist/kpis.js +16 -14
- package/dist/kpis.js.map +1 -1
- package/dist/load-balancing.d.ts +395 -0
- package/dist/load-balancing.d.ts.map +1 -0
- package/dist/load-balancing.js +991 -0
- package/dist/load-balancing.js.map +1 -0
- package/dist/logger.d.ts +76 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +39 -0
- package/dist/logger.js.map +1 -0
- package/dist/notify.d.ts +38 -9
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +72 -17
- package/dist/notify.js.map +1 -1
- package/dist/role.d.ts +5 -4
- package/dist/role.d.ts.map +1 -1
- package/dist/role.js +13 -10
- package/dist/role.js.map +1 -1
- package/dist/runtime.d.ts +310 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +510 -0
- package/dist/runtime.js.map +1 -0
- package/dist/team.d.ts +11 -6
- package/dist/team.d.ts.map +1 -1
- package/dist/team.js +22 -15
- package/dist/team.js.map +1 -1
- package/dist/transports/email.d.ts +318 -0
- package/dist/transports/email.d.ts.map +1 -0
- package/dist/transports/email.js +779 -0
- package/dist/transports/email.js.map +1 -0
- package/dist/transports/slack.d.ts +515 -0
- package/dist/transports/slack.d.ts.map +1 -0
- package/dist/transports/slack.js +844 -0
- package/dist/transports/slack.js.map +1 -0
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +44 -25
- package/dist/transports.js.map +1 -1
- package/dist/types.d.ts +149 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/id.d.ts +19 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +21 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/video.d.ts +203 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +528 -0
- package/dist/video.js.map +1 -0
- package/dist/worker.d.ts +343 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +698 -0
- package/dist/worker.js.map +1 -0
- package/package.json +24 -5
- package/src/actions.ts +48 -38
- package/src/agent-comms.ts +1200 -0
- package/src/approve.ts +91 -20
- package/src/ask.ts +99 -25
- package/src/browse.ts +627 -0
- package/src/capability-tiers.ts +545 -0
- package/src/cascade-context.ts +648 -0
- package/src/client.ts +221 -0
- package/src/decide.ts +81 -35
- package/src/do.ts +98 -52
- package/src/error-escalation.ts +1123 -0
- package/src/generate.ts +52 -18
- package/src/goals.ts +36 -27
- package/src/image.ts +816 -0
- package/src/index.ts +410 -2
- package/src/is.ts +59 -25
- package/src/kpis.ts +41 -36
- package/src/load-balancing.ts +1467 -0
- package/src/logger.ts +93 -0
- package/src/notify.ts +78 -17
- package/src/role.ts +30 -20
- package/src/runtime.ts +796 -0
- package/src/team.ts +24 -19
- package/src/transports/email.ts +1160 -0
- package/src/transports/slack.ts +1320 -0
- package/src/transports.ts +58 -43
- package/src/types.ts +182 -46
- package/src/utils/id.ts +21 -0
- package/src/video.ts +906 -0
- package/src/worker.ts +1007 -0
- package/test/agent-comms.test.ts +1397 -0
- package/test/approve.test.ts +305 -0
- package/test/ask.test.ts +274 -0
- package/test/browse.test.ts +361 -0
- package/test/capability-tiers.test.ts +631 -0
- package/test/cascade-context.test.ts +692 -0
- package/test/decide.test.ts +252 -0
- package/test/do.test.ts +144 -0
- package/test/error-escalation.test.ts +1205 -0
- package/test/error-logging.test.ts +357 -0
- package/test/generate.test.ts +319 -0
- package/test/image.test.ts +398 -0
- package/test/is.test.ts +287 -0
- package/test/load-balancing-safety.test.ts +404 -0
- package/test/load-balancing-thread-safety.test.ts +464 -0
- package/test/load-balancing.test.ts +1145 -0
- package/test/notify.test.ts +434 -0
- package/test/primitives.test.ts +320 -0
- package/test/runtime-integration.test.ts +892 -0
- package/test/transports/crypto.test.ts +230 -0
- package/test/transports/email.test.ts +866 -0
- package/test/transports/id-generation.test.ts +91 -0
- package/test/transports/slack.test.ts +760 -0
- package/test/type-safety.test.ts +834 -0
- package/test/types.test.ts +95 -2
- package/test/video.test.ts +530 -0
- package/test/worker.test.ts +1433 -0
- package/tsconfig.json +4 -1
- package/vitest.config.ts +42 -0
- package/wrangler.jsonc +36 -0
- package/.turbo/turbo-build.log +0 -5
- package/src/actions.js +0 -436
- package/src/approve.js +0 -234
- package/src/ask.js +0 -226
- package/src/decide.js +0 -244
- package/src/do.js +0 -227
- package/src/generate.js +0 -298
- package/src/goals.js +0 -205
- package/src/index.js +0 -68
- package/src/is.js +0 -317
- package/src/kpis.js +0 -270
- package/src/notify.js +0 -219
- package/src/role.js +0 -110
- package/src/team.js +0 -130
- package/src/transports.js +0 -357
- package/src/types.js +0 -71
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for browse() - Browser automation primitive
|
|
3
|
+
*
|
|
4
|
+
* The browse() function routes browser automation tasks to appropriate Workers
|
|
5
|
+
* (AI Agents or Humans) based on capability matching. It uses AI to plan and
|
|
6
|
+
* execute browser actions with human fallback support.
|
|
7
|
+
*
|
|
8
|
+
* These tests verify the structure and exports of the browse module.
|
|
9
|
+
* Integration tests with real browser automation are skipped unless
|
|
10
|
+
* a browser automation environment is configured.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { describe, it, expect } from 'vitest'
|
|
14
|
+
import { browse } from '../src/index.js'
|
|
15
|
+
import type {
|
|
16
|
+
BrowseOptions,
|
|
17
|
+
BrowseResult,
|
|
18
|
+
BrowseAction,
|
|
19
|
+
Viewport,
|
|
20
|
+
ClickOptions,
|
|
21
|
+
TypeOptions,
|
|
22
|
+
ScrollOptions,
|
|
23
|
+
ScreenshotOptions,
|
|
24
|
+
ExtractOptions,
|
|
25
|
+
} from '../src/browse.js'
|
|
26
|
+
|
|
27
|
+
describe('browse() - Browser Automation Primitive', () => {
|
|
28
|
+
describe('Structure Tests', () => {
|
|
29
|
+
it('should be exported from index', () => {
|
|
30
|
+
expect(browse).toBeDefined()
|
|
31
|
+
expect(typeof browse).toBe('function')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('should have click method', () => {
|
|
35
|
+
expect(browse.click).toBeDefined()
|
|
36
|
+
expect(typeof browse.click).toBe('function')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('should have type method', () => {
|
|
40
|
+
expect(browse.type).toBeDefined()
|
|
41
|
+
expect(typeof browse.type).toBe('function')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should have scroll method', () => {
|
|
45
|
+
expect(browse.scroll).toBeDefined()
|
|
46
|
+
expect(typeof browse.scroll).toBe('function')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('should have screenshot method', () => {
|
|
50
|
+
expect(browse.screenshot).toBeDefined()
|
|
51
|
+
expect(typeof browse.screenshot).toBe('function')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should have extract method', () => {
|
|
55
|
+
expect(browse.extract).toBeDefined()
|
|
56
|
+
expect(typeof browse.extract).toBe('function')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should have waitFor method', () => {
|
|
60
|
+
expect(browse.waitFor).toBeDefined()
|
|
61
|
+
expect(typeof browse.waitFor).toBe('function')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should have fill method', () => {
|
|
65
|
+
expect(browse.fill).toBeDefined()
|
|
66
|
+
expect(typeof browse.fill).toBe('function')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('should have crawl method', () => {
|
|
70
|
+
expect(browse.crawl).toBeDefined()
|
|
71
|
+
expect(typeof browse.crawl).toBe('function')
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('Type Tests', () => {
|
|
76
|
+
it('should accept valid BrowseOptions', () => {
|
|
77
|
+
const options: BrowseOptions = {
|
|
78
|
+
url: 'https://example.com',
|
|
79
|
+
task: 'Extract page title',
|
|
80
|
+
timeout: 30000,
|
|
81
|
+
headless: true,
|
|
82
|
+
viewport: { width: 1280, height: 720 },
|
|
83
|
+
context: { key: 'value' },
|
|
84
|
+
waitFor: '.content',
|
|
85
|
+
humanFallback: false,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
expect(options.url).toBe('https://example.com')
|
|
89
|
+
expect(options.task).toBe('Extract page title')
|
|
90
|
+
expect(options.timeout).toBe(30000)
|
|
91
|
+
expect(options.headless).toBe(true)
|
|
92
|
+
expect(options.viewport?.width).toBe(1280)
|
|
93
|
+
expect(options.viewport?.height).toBe(720)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should accept valid BrowseResult', () => {
|
|
97
|
+
const result: BrowseResult = {
|
|
98
|
+
success: true,
|
|
99
|
+
data: { title: 'Example' },
|
|
100
|
+
screenshot: 'base64string',
|
|
101
|
+
actions: [
|
|
102
|
+
{ type: 'navigate', target: 'https://example.com', success: true },
|
|
103
|
+
{ type: 'click', target: '#button', success: true },
|
|
104
|
+
],
|
|
105
|
+
duration: 1500,
|
|
106
|
+
finalUrl: 'https://example.com/page',
|
|
107
|
+
title: 'Example Page',
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
expect(result.success).toBe(true)
|
|
111
|
+
expect(result.data).toEqual({ title: 'Example' })
|
|
112
|
+
expect(result.actions.length).toBe(2)
|
|
113
|
+
expect(result.duration).toBe(1500)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('should accept valid BrowseAction types', () => {
|
|
117
|
+
const actions: BrowseAction[] = [
|
|
118
|
+
{ type: 'navigate', target: 'https://example.com' },
|
|
119
|
+
{ type: 'click', target: '#submit' },
|
|
120
|
+
{ type: 'type', target: '#input', value: 'hello' },
|
|
121
|
+
{ type: 'scroll', value: '500' },
|
|
122
|
+
{ type: 'wait', value: '1000' },
|
|
123
|
+
{ type: 'screenshot' },
|
|
124
|
+
{ type: 'extract' },
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
expect(actions.length).toBe(7)
|
|
128
|
+
expect(actions[0].type).toBe('navigate')
|
|
129
|
+
expect(actions[2].value).toBe('hello')
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('should accept valid Viewport', () => {
|
|
133
|
+
const viewport: Viewport = {
|
|
134
|
+
width: 1920,
|
|
135
|
+
height: 1080,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
expect(viewport.width).toBe(1920)
|
|
139
|
+
expect(viewport.height).toBe(1080)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('should accept valid ClickOptions', () => {
|
|
143
|
+
const options: ClickOptions = {
|
|
144
|
+
waitForNavigation: true,
|
|
145
|
+
offset: { x: 10, y: 10 },
|
|
146
|
+
clickCount: 2,
|
|
147
|
+
button: 'left',
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
expect(options.waitForNavigation).toBe(true)
|
|
151
|
+
expect(options.clickCount).toBe(2)
|
|
152
|
+
expect(options.button).toBe('left')
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('should accept valid TypeOptions', () => {
|
|
156
|
+
const options: TypeOptions = {
|
|
157
|
+
clear: true,
|
|
158
|
+
delay: 50,
|
|
159
|
+
pressEnter: true,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
expect(options.clear).toBe(true)
|
|
163
|
+
expect(options.delay).toBe(50)
|
|
164
|
+
expect(options.pressEnter).toBe(true)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('should accept valid ScrollOptions', () => {
|
|
168
|
+
const options: ScrollOptions = {
|
|
169
|
+
direction: 'down',
|
|
170
|
+
amount: 500,
|
|
171
|
+
toElement: '#target',
|
|
172
|
+
smooth: true,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
expect(options.direction).toBe('down')
|
|
176
|
+
expect(options.amount).toBe(500)
|
|
177
|
+
expect(options.toElement).toBe('#target')
|
|
178
|
+
expect(options.smooth).toBe(true)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('should accept valid ScreenshotOptions', () => {
|
|
182
|
+
const options: ScreenshotOptions = {
|
|
183
|
+
fullPage: true,
|
|
184
|
+
selector: '#content',
|
|
185
|
+
format: 'png',
|
|
186
|
+
quality: 80,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
expect(options.fullPage).toBe(true)
|
|
190
|
+
expect(options.selector).toBe('#content')
|
|
191
|
+
expect(options.format).toBe('png')
|
|
192
|
+
expect(options.quality).toBe(80)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
it('should accept valid ExtractOptions', () => {
|
|
196
|
+
const options: ExtractOptions = {
|
|
197
|
+
schema: { title: 'Page title' },
|
|
198
|
+
selector: 'article',
|
|
199
|
+
multiple: true,
|
|
200
|
+
includeHtml: false,
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
expect(options.schema).toEqual({ title: 'Page title' })
|
|
204
|
+
expect(options.selector).toBe('article')
|
|
205
|
+
expect(options.multiple).toBe(true)
|
|
206
|
+
expect(options.includeHtml).toBe(false)
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
describe('Unit Tests (no browser)', () => {
|
|
211
|
+
it('should return function signature for browse', () => {
|
|
212
|
+
// browse(url, task, options?) => Promise<BrowseResult>
|
|
213
|
+
expect(browse.length).toBeGreaterThanOrEqual(2)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
it('should return function signature for browse.click', () => {
|
|
217
|
+
// browse.click(url, selector, options?) => Promise<BrowseResult>
|
|
218
|
+
expect(browse.click.length).toBeGreaterThanOrEqual(2)
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('should return function signature for browse.type', () => {
|
|
222
|
+
// browse.type(url, selector, text, options?) => Promise<BrowseResult>
|
|
223
|
+
expect(browse.type.length).toBeGreaterThanOrEqual(3)
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it('should return function signature for browse.scroll', () => {
|
|
227
|
+
// browse.scroll(url, direction, amount?, options?) => Promise<BrowseResult>
|
|
228
|
+
expect(browse.scroll.length).toBeGreaterThanOrEqual(2)
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('should return function signature for browse.screenshot', () => {
|
|
232
|
+
// browse.screenshot(url, options?) => Promise<BrowseResult>
|
|
233
|
+
expect(browse.screenshot.length).toBeGreaterThanOrEqual(1)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
it('should return function signature for browse.extract', () => {
|
|
237
|
+
// browse.extract(url, schema, options?) => Promise<BrowseResult>
|
|
238
|
+
expect(browse.extract.length).toBeGreaterThanOrEqual(2)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
it('should return function signature for browse.waitFor', () => {
|
|
242
|
+
// browse.waitFor(url, selector, timeout?) => Promise<BrowseResult>
|
|
243
|
+
expect(browse.waitFor.length).toBeGreaterThanOrEqual(2)
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
it('should return function signature for browse.fill', () => {
|
|
247
|
+
// browse.fill(url, formData, submitSelector?) => Promise<BrowseResult>
|
|
248
|
+
expect(browse.fill.length).toBeGreaterThanOrEqual(2)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it('should return function signature for browse.crawl', () => {
|
|
252
|
+
// browse.crawl(urls, taskPerPage) => Promise<BrowseResult[]>
|
|
253
|
+
expect(browse.crawl.length).toBeGreaterThanOrEqual(2)
|
|
254
|
+
})
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
// Skip integration tests if no AI gateway configured
|
|
258
|
+
const hasGateway = !!process.env.AI_GATEWAY_URL || !!process.env.ANTHROPIC_API_KEY
|
|
259
|
+
|
|
260
|
+
describe.skipIf(!hasGateway)('Integration Tests (with AI)', () => {
|
|
261
|
+
it('should execute a simple browse task', async () => {
|
|
262
|
+
const result = await browse('https://example.com', 'Get the page title', {
|
|
263
|
+
timeout: 30000,
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
expect(result).toBeDefined()
|
|
267
|
+
expect(typeof result.success).toBe('boolean')
|
|
268
|
+
expect(Array.isArray(result.actions)).toBe(true)
|
|
269
|
+
expect(result.actions.length).toBeGreaterThan(0)
|
|
270
|
+
expect(result.actions[0].type).toBe('navigate')
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it('should include duration in result', async () => {
|
|
274
|
+
const result = await browse('https://example.com', 'Check if page loaded', {
|
|
275
|
+
timeout: 30000,
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
expect(result.duration).toBeDefined()
|
|
279
|
+
expect(typeof result.duration).toBe('number')
|
|
280
|
+
expect(result.duration).toBeGreaterThan(0)
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('should handle timeout option', async () => {
|
|
284
|
+
const result = await browse('https://example.com', 'Perform complex task', {
|
|
285
|
+
timeout: 1, // Very short timeout
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
// Should fail or succeed quickly
|
|
289
|
+
expect(result).toBeDefined()
|
|
290
|
+
expect(typeof result.success).toBe('boolean')
|
|
291
|
+
if (!result.success) {
|
|
292
|
+
expect(result.error).toBeDefined()
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('should support human fallback option', async () => {
|
|
297
|
+
const result = await browse('https://example.com', 'Complete complex form', {
|
|
298
|
+
humanFallback: true,
|
|
299
|
+
timeout: 1, // Force failure
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
expect(result).toBeDefined()
|
|
303
|
+
// When AI fails with humanFallback, executedBy should indicate pending
|
|
304
|
+
if (!result.success && result.executedBy) {
|
|
305
|
+
expect(result.executedBy).toBe('pending-human-fallback')
|
|
306
|
+
}
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('should execute click helper', async () => {
|
|
310
|
+
const result = await browse.click('https://example.com', 'a')
|
|
311
|
+
|
|
312
|
+
expect(result).toBeDefined()
|
|
313
|
+
expect(typeof result.success).toBe('boolean')
|
|
314
|
+
expect(Array.isArray(result.actions)).toBe(true)
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
it('should execute type helper', async () => {
|
|
318
|
+
const result = await browse.type('https://example.com', 'input', 'test text')
|
|
319
|
+
|
|
320
|
+
expect(result).toBeDefined()
|
|
321
|
+
expect(typeof result.success).toBe('boolean')
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('should execute scroll helper', async () => {
|
|
325
|
+
const result = await browse.scroll('https://example.com', 'down', 100)
|
|
326
|
+
|
|
327
|
+
expect(result).toBeDefined()
|
|
328
|
+
expect(typeof result.success).toBe('boolean')
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
it('should execute screenshot helper', async () => {
|
|
332
|
+
const result = await browse.screenshot('https://example.com')
|
|
333
|
+
|
|
334
|
+
expect(result).toBeDefined()
|
|
335
|
+
expect(typeof result.success).toBe('boolean')
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
it('should execute extract helper', async () => {
|
|
339
|
+
const result = await browse.extract('https://example.com', {
|
|
340
|
+
title: 'Page title',
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
expect(result).toBeDefined()
|
|
344
|
+
expect(typeof result.success).toBe('boolean')
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
it('should execute crawl for multiple URLs', async () => {
|
|
348
|
+
const results = await browse.crawl(
|
|
349
|
+
['https://example.com', 'https://example.org'],
|
|
350
|
+
'Get page title'
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
expect(results).toBeDefined()
|
|
354
|
+
expect(Array.isArray(results)).toBe(true)
|
|
355
|
+
expect(results.length).toBe(2)
|
|
356
|
+
results.forEach((result) => {
|
|
357
|
+
expect(typeof result.success).toBe('boolean')
|
|
358
|
+
})
|
|
359
|
+
})
|
|
360
|
+
})
|
|
361
|
+
})
|