@anweat/dsh-browser 0.1.4 → 0.1.6
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/README.md +229 -92
- package/cordis.patch.yml +15 -15
- package/lib/approval-policy.d.ts +11 -0
- package/lib/approval-policy.js +33 -0
- package/lib/approval-policy.js.map +1 -0
- package/lib/auth-profiles.d.ts +20 -0
- package/lib/auth-profiles.js +28 -0
- package/lib/auth-profiles.js.map +1 -0
- package/lib/automation.d.ts +67 -0
- package/lib/automation.js +181 -0
- package/lib/automation.js.map +1 -0
- package/lib/browser-service.d.ts +63 -0
- package/lib/browser-service.js +222 -62
- package/lib/browser-service.js.map +1 -1
- package/lib/config.d.ts +11 -0
- package/lib/config.js +23 -0
- package/lib/config.js.map +1 -1
- package/lib/deps.js +3 -7
- package/lib/deps.js.map +1 -1
- package/lib/index.d.ts +6 -1
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -1
- package/lib/rule-packs.d.ts +32 -0
- package/lib/rule-packs.js +77 -0
- package/lib/rule-packs.js.map +1 -0
- package/lib/scripts.d.ts +35 -0
- package/lib/scripts.js +181 -0
- package/lib/scripts.js.map +1 -0
- package/lib/tools.js +262 -1
- package/lib/tools.js.map +1 -1
- package/package.json +78 -74
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded, auditable Playwright recipes for model-generated browser flows.
|
|
3
|
+
* Recipes deliberately expose named operations instead of arbitrary JavaScript.
|
|
4
|
+
* @module dsh-browser/automation
|
|
5
|
+
*/
|
|
6
|
+
const READ_ONLY_ACTIONS = new Set(['wait', 'extract', 'assert', 'screenshot']);
|
|
7
|
+
function finite(value, fallback, min, max, label) {
|
|
8
|
+
const resolved = value ?? fallback;
|
|
9
|
+
if (!Number.isFinite(resolved) || resolved < min || resolved > max)
|
|
10
|
+
throw new Error(label + ' must be between ' + min + ' and ' + max);
|
|
11
|
+
return resolved;
|
|
12
|
+
}
|
|
13
|
+
function selector(value) {
|
|
14
|
+
if (!value || value.length > 500)
|
|
15
|
+
throw new Error('selector must contain 1 to 500 characters');
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function shortText(value, label, max = 20_000) {
|
|
19
|
+
if (value === undefined || value.length === 0 || value.length > max)
|
|
20
|
+
throw new Error(label + ' must contain 1 to ' + max + ' characters');
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
export function validateRecipe(steps) {
|
|
24
|
+
if (steps.length < 1 || steps.length > 25)
|
|
25
|
+
throw new Error('recipe must contain between 1 and 25 steps');
|
|
26
|
+
for (const step of steps) {
|
|
27
|
+
switch (step.type) {
|
|
28
|
+
case 'wait': {
|
|
29
|
+
finite(step.timeoutMs, 15_000, 0, 30_000, 'wait timeoutMs');
|
|
30
|
+
if (step.condition === 'selector')
|
|
31
|
+
selector(step.value);
|
|
32
|
+
else if (step.condition === 'text')
|
|
33
|
+
shortText(step.value, 'wait text', 2_000);
|
|
34
|
+
else if (step.condition === 'time')
|
|
35
|
+
finite(step.waitMs ?? Number(step.value ?? 0), 0, 0, 10_000, 'wait waitMs');
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'click':
|
|
39
|
+
selector(step.selector);
|
|
40
|
+
finite(step.timeoutMs, 15_000, 1, 30_000, 'click timeoutMs');
|
|
41
|
+
break;
|
|
42
|
+
case 'fill':
|
|
43
|
+
case 'type':
|
|
44
|
+
selector(step.selector);
|
|
45
|
+
shortText(step.value, step.type + ' value');
|
|
46
|
+
finite(step.timeoutMs, 15_000, 1, 30_000, step.type + ' timeoutMs');
|
|
47
|
+
break;
|
|
48
|
+
case 'press':
|
|
49
|
+
shortText(step.key, 'key', 100);
|
|
50
|
+
if (step.selector !== undefined)
|
|
51
|
+
selector(step.selector);
|
|
52
|
+
break;
|
|
53
|
+
case 'select':
|
|
54
|
+
selector(step.selector);
|
|
55
|
+
shortText(step.value, 'select value', 2_000);
|
|
56
|
+
break;
|
|
57
|
+
case 'check':
|
|
58
|
+
case 'hover':
|
|
59
|
+
selector(step.selector);
|
|
60
|
+
break;
|
|
61
|
+
case 'scroll':
|
|
62
|
+
finite(step.deltaY, 2_000, -20_000, 20_000, 'scroll deltaY');
|
|
63
|
+
finite(step.waitMs, 400, 0, 5_000, 'scroll waitMs');
|
|
64
|
+
break;
|
|
65
|
+
case 'extract':
|
|
66
|
+
if (step.selector !== undefined)
|
|
67
|
+
selector(step.selector);
|
|
68
|
+
finite(step.limit, 100, 1, 500, 'extract limit');
|
|
69
|
+
if (step.mode === 'attribute')
|
|
70
|
+
shortText(step.attribute, 'attribute', 100);
|
|
71
|
+
break;
|
|
72
|
+
case 'assert':
|
|
73
|
+
if (step.selector === undefined && step.text === undefined)
|
|
74
|
+
throw new Error('assert requires selector or text');
|
|
75
|
+
if (step.selector !== undefined)
|
|
76
|
+
selector(step.selector);
|
|
77
|
+
if (step.text !== undefined)
|
|
78
|
+
shortText(step.text, 'assert text', 2_000);
|
|
79
|
+
finite(step.timeoutMs, 15_000, 1, 30_000, 'assert timeoutMs');
|
|
80
|
+
break;
|
|
81
|
+
case 'screenshot':
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
throw new Error('unsupported recipe step');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function recipeNeedsApproval(steps) {
|
|
89
|
+
return steps.some(step => !READ_ONLY_ACTIONS.has(step.type));
|
|
90
|
+
}
|
|
91
|
+
function cap(value, max = 50_000) {
|
|
92
|
+
return value.length <= max ? value : value.slice(0, max) + '\n…(truncated)';
|
|
93
|
+
}
|
|
94
|
+
export async function runRecipe(page, steps, captureScreenshot, signal) {
|
|
95
|
+
validateRecipe(steps);
|
|
96
|
+
const results = [];
|
|
97
|
+
for (let index = 0; index < steps.length; index += 1) {
|
|
98
|
+
signal?.throwIfAborted();
|
|
99
|
+
const step = steps[index];
|
|
100
|
+
let value;
|
|
101
|
+
switch (step.type) {
|
|
102
|
+
case 'wait': {
|
|
103
|
+
const timeout = finite(step.timeoutMs, 15_000, 0, 30_000, 'wait timeoutMs');
|
|
104
|
+
if (step.condition === 'selector')
|
|
105
|
+
await page.locator(selector(step.value)).first().waitFor({ state: 'visible', timeout });
|
|
106
|
+
else if (step.condition === 'text')
|
|
107
|
+
await page.getByText(shortText(step.value, 'wait text', 2_000), { exact: false }).first().waitFor({ state: 'visible', timeout });
|
|
108
|
+
else if (step.condition === 'load')
|
|
109
|
+
await page.waitForLoadState('networkidle', { timeout });
|
|
110
|
+
else
|
|
111
|
+
await page.waitForTimeout(finite(step.waitMs ?? Number(step.value ?? 0), 0, 0, 10_000, 'wait waitMs'));
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'click':
|
|
115
|
+
await page.locator(selector(step.selector)).first().click({ timeout: step.timeoutMs ?? 15_000 });
|
|
116
|
+
break;
|
|
117
|
+
case 'fill':
|
|
118
|
+
await page.locator(selector(step.selector)).first().fill(step.value, { timeout: step.timeoutMs ?? 15_000 });
|
|
119
|
+
break;
|
|
120
|
+
case 'type':
|
|
121
|
+
await page.locator(selector(step.selector)).first().pressSequentially(step.value, { timeout: step.timeoutMs ?? 15_000 });
|
|
122
|
+
break;
|
|
123
|
+
case 'press':
|
|
124
|
+
if (step.selector)
|
|
125
|
+
await page.locator(selector(step.selector)).first().press(step.key);
|
|
126
|
+
else
|
|
127
|
+
await page.keyboard.press(step.key);
|
|
128
|
+
break;
|
|
129
|
+
case 'select':
|
|
130
|
+
await page.locator(selector(step.selector)).first().selectOption(step.value);
|
|
131
|
+
break;
|
|
132
|
+
case 'check': {
|
|
133
|
+
const target = page.locator(selector(step.selector)).first();
|
|
134
|
+
if (step.checked === false)
|
|
135
|
+
await target.uncheck();
|
|
136
|
+
else
|
|
137
|
+
await target.check();
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case 'hover':
|
|
141
|
+
await page.locator(selector(step.selector)).first().hover();
|
|
142
|
+
break;
|
|
143
|
+
case 'scroll':
|
|
144
|
+
await page.mouse.wheel(0, step.deltaY ?? 2_000);
|
|
145
|
+
await page.waitForTimeout(step.waitMs ?? 400);
|
|
146
|
+
break;
|
|
147
|
+
case 'extract': {
|
|
148
|
+
const target = page.locator(step.selector ?? 'body').first();
|
|
149
|
+
const mode = step.mode ?? 'text';
|
|
150
|
+
if (mode === 'text')
|
|
151
|
+
value = cap(await target.innerText());
|
|
152
|
+
else if (mode === 'html')
|
|
153
|
+
value = cap(await target.innerHTML());
|
|
154
|
+
else if (mode === 'attribute')
|
|
155
|
+
value = String(await target.getAttribute(shortText(step.attribute, 'attribute', 100)) ?? '');
|
|
156
|
+
else {
|
|
157
|
+
const rows = await target.locator('a[href]').evaluateAll((anchors, limit) => anchors.slice(0, limit).map(anchor => ({
|
|
158
|
+
text: String(anchor.textContent ?? '').trim(),
|
|
159
|
+
url: String(anchor.href ?? ''),
|
|
160
|
+
})), step.limit ?? 100);
|
|
161
|
+
value = cap(JSON.stringify(rows));
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case 'assert': {
|
|
166
|
+
const timeout = step.timeoutMs ?? 15_000;
|
|
167
|
+
if (step.selector)
|
|
168
|
+
await page.locator(selector(step.selector)).first().waitFor({ state: 'visible', timeout });
|
|
169
|
+
if (step.text)
|
|
170
|
+
await page.getByText(step.text, { exact: false }).first().waitFor({ state: 'visible', timeout });
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case 'screenshot':
|
|
174
|
+
value = await captureScreenshot();
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
results.push({ step: index + 1, action: step.type, ok: true, ...value !== undefined ? { value } : {} });
|
|
178
|
+
}
|
|
179
|
+
return results;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=automation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation.js","sourceRoot":"","sources":["../src/automation.ts"],"names":[],"mappings":"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"}
|
package/lib/browser-service.d.ts
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { type CliResult } from './deps.ts';
|
|
22
22
|
import type { ResolvedConfig } from './config.ts';
|
|
23
|
+
import { type BrowserRecipeStep, type RecipeStepResult } from './automation.ts';
|
|
24
|
+
import { type UserscriptValidation } from './scripts.ts';
|
|
23
25
|
export interface RenderRule {
|
|
24
26
|
hostname: string;
|
|
25
27
|
contentSelectors: string[];
|
|
@@ -56,27 +58,46 @@ export interface InteractiveState {
|
|
|
56
58
|
text: string;
|
|
57
59
|
screenshotPath?: string;
|
|
58
60
|
}
|
|
61
|
+
export interface RecipeRunResult extends InteractiveState {
|
|
62
|
+
steps: RecipeStepResult[];
|
|
63
|
+
}
|
|
64
|
+
export interface ScriptRunResult {
|
|
65
|
+
url: string;
|
|
66
|
+
name: string;
|
|
67
|
+
sha256: string;
|
|
68
|
+
capabilities: string[];
|
|
69
|
+
resultJson: string;
|
|
70
|
+
truncated: boolean;
|
|
71
|
+
}
|
|
59
72
|
export declare class BrowserService {
|
|
60
73
|
private readonly config;
|
|
61
74
|
private browser;
|
|
62
75
|
private launching?;
|
|
63
76
|
private activeContext;
|
|
64
77
|
private activePage;
|
|
78
|
+
private activeProfile?;
|
|
79
|
+
private activeRulePack?;
|
|
80
|
+
private readonly authProfiles;
|
|
65
81
|
constructor(config: ResolvedConfig);
|
|
66
82
|
available(): boolean;
|
|
67
83
|
private ensure;
|
|
68
84
|
/** Run `playwright install chromium` from the bundled playwright CLI. */
|
|
69
85
|
installChromium(): Promise<CliResult>;
|
|
70
86
|
private transientContext;
|
|
87
|
+
private persistAndClose;
|
|
71
88
|
render(url: string, rules: readonly RenderRule[], opts?: {
|
|
72
89
|
signal?: AbortSignal;
|
|
73
90
|
maxChars?: number;
|
|
74
91
|
waitMs?: number;
|
|
92
|
+
authProfile?: string;
|
|
93
|
+
rulePack?: string;
|
|
75
94
|
}): Promise<RenderResult>;
|
|
76
95
|
snapshot(url: string, rules: readonly RenderRule[], opts: {
|
|
77
96
|
signal?: AbortSignal;
|
|
78
97
|
outDir: string;
|
|
79
98
|
maxChars?: number;
|
|
99
|
+
authProfile?: string;
|
|
100
|
+
rulePack?: string;
|
|
80
101
|
}): Promise<SnapshotResult>;
|
|
81
102
|
searchResults(url: string, spec: PlatformSpec, opts?: {
|
|
82
103
|
signal?: AbortSignal;
|
|
@@ -88,17 +109,42 @@ export declare class BrowserService {
|
|
|
88
109
|
domain: string;
|
|
89
110
|
path: string;
|
|
90
111
|
}[];
|
|
112
|
+
authProfile?: string;
|
|
113
|
+
rulePack?: string;
|
|
91
114
|
}): Promise<SearchItem[]>;
|
|
92
115
|
opencliAvailable(): boolean;
|
|
93
116
|
opencli(args: string[], opts?: {
|
|
94
117
|
timeoutMs?: number;
|
|
95
118
|
signal?: AbortSignal;
|
|
96
119
|
}): Promise<CliResult>;
|
|
120
|
+
opencliDoctor(signal?: AbortSignal): Promise<CliResult>;
|
|
121
|
+
scriptCatalog(): {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
description: string;
|
|
125
|
+
sha256: string;
|
|
126
|
+
}[];
|
|
127
|
+
validateUserscript(source: string, targetUrl?: string): UserscriptValidation;
|
|
128
|
+
private runScript;
|
|
129
|
+
runBuiltinScript(url: string, id: string, opts?: {
|
|
130
|
+
signal?: AbortSignal;
|
|
131
|
+
timeoutMs?: number;
|
|
132
|
+
authProfile?: string;
|
|
133
|
+
rulePack?: string;
|
|
134
|
+
}): Promise<ScriptRunResult>;
|
|
135
|
+
runUserscript(url: string, source: string, opts?: {
|
|
136
|
+
signal?: AbortSignal;
|
|
137
|
+
timeoutMs?: number;
|
|
138
|
+
authProfile?: string;
|
|
139
|
+
rulePack?: string;
|
|
140
|
+
}): Promise<ScriptRunResult>;
|
|
97
141
|
private ensureActivePage;
|
|
98
142
|
private captureScreenshot;
|
|
99
143
|
private readState;
|
|
100
144
|
open(url: string, opts?: {
|
|
101
145
|
waitMs?: number;
|
|
146
|
+
authProfile?: string;
|
|
147
|
+
rulePack?: string;
|
|
102
148
|
}): Promise<InteractiveState>;
|
|
103
149
|
click(selector: string, opts?: {
|
|
104
150
|
timeoutMs?: number;
|
|
@@ -114,6 +160,13 @@ export declare class BrowserService {
|
|
|
114
160
|
screenshot(): Promise<{
|
|
115
161
|
path: string;
|
|
116
162
|
}>;
|
|
163
|
+
recipe(steps: readonly BrowserRecipeStep[], opts?: {
|
|
164
|
+
url?: string;
|
|
165
|
+
waitMs?: number;
|
|
166
|
+
authProfile?: string;
|
|
167
|
+
rulePack?: string;
|
|
168
|
+
signal?: AbortSignal;
|
|
169
|
+
}): Promise<RecipeRunResult>;
|
|
117
170
|
closePage(): Promise<void>;
|
|
118
171
|
status(): Promise<{
|
|
119
172
|
enabled: boolean;
|
|
@@ -121,7 +174,17 @@ export declare class BrowserService {
|
|
|
121
174
|
headless: boolean;
|
|
122
175
|
opencliEnabled: boolean;
|
|
123
176
|
chromiumInstalled: boolean;
|
|
177
|
+
authProfiles: {
|
|
178
|
+
id: string;
|
|
179
|
+
allowedDomains: string[];
|
|
180
|
+
persistState: boolean;
|
|
181
|
+
}[];
|
|
182
|
+
rulePacks: string[];
|
|
183
|
+
builtinScripts: string[];
|
|
184
|
+
externalUserscriptsRequireApproval: true;
|
|
185
|
+
mutatingRecipesRequireApproval: true;
|
|
124
186
|
activeUrl?: string;
|
|
187
|
+
activeAuthProfile?: string;
|
|
125
188
|
}>;
|
|
126
189
|
close(): Promise<void>;
|
|
127
190
|
}
|