@anweat/dsh-browser 0.1.17 → 0.2.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/README.md +266 -88
- package/assets/skills/dsh-browser/SKILL.md +120 -0
- package/assets/skills/dsh-browser/references/develop.md +48 -0
- package/assets/skills/dsh-browser/references/observe.md +91 -0
- package/assets/skills/dsh-browser/references/opencli.md +25 -0
- package/assets/skills/dsh-browser/references/recipes.md +149 -0
- package/assets/skills/dsh-browser/references/userscripts.md +44 -0
- package/cordis.patch.yml +11 -3
- package/lib/actions/act.d.ts +3 -0
- package/lib/actions/act.js +147 -0
- package/lib/actions/act.js.map +1 -0
- package/lib/actions/automation.d.ts +3 -0
- package/lib/actions/automation.js +356 -0
- package/lib/actions/automation.js.map +1 -0
- package/lib/actions/crawl.d.ts +3 -0
- package/lib/actions/crawl.js +28 -0
- package/lib/actions/crawl.js.map +1 -0
- package/lib/actions/errors.d.ts +53 -0
- package/lib/actions/errors.js +178 -0
- package/lib/actions/errors.js.map +1 -0
- package/lib/actions/index-view.d.ts +42 -0
- package/lib/actions/index-view.js +268 -0
- package/lib/actions/index-view.js.map +1 -0
- package/lib/actions/inspect.d.ts +3 -0
- package/lib/actions/inspect.js +35 -0
- package/lib/actions/inspect.js.map +1 -0
- package/lib/actions/observe.d.ts +3 -0
- package/lib/actions/observe.js +121 -0
- package/lib/actions/observe.js.map +1 -0
- package/lib/actions/opencli.d.ts +3 -0
- package/lib/actions/opencli.js +51 -0
- package/lib/actions/opencli.js.map +1 -0
- package/lib/actions/registry.d.ts +35 -0
- package/lib/actions/registry.js +89 -0
- package/lib/actions/registry.js.map +1 -0
- package/lib/actions/run.d.ts +34 -0
- package/lib/actions/run.js +226 -0
- package/lib/actions/run.js.map +1 -0
- package/lib/actions/runtime.d.ts +3 -0
- package/lib/actions/runtime.js +33 -0
- package/lib/actions/runtime.js.map +1 -0
- package/lib/actions/schema.d.ts +31 -0
- package/lib/actions/schema.js +309 -0
- package/lib/actions/schema.js.map +1 -0
- package/lib/actions/script.d.ts +3 -0
- package/lib/actions/script.js +97 -0
- package/lib/actions/script.js.map +1 -0
- package/lib/actions/shared.d.ts +31 -0
- package/lib/actions/shared.js +45 -0
- package/lib/actions/shared.js.map +1 -0
- package/lib/actions/surface.d.ts +22 -0
- package/lib/actions/surface.js +18 -0
- package/lib/actions/surface.js.map +1 -0
- package/lib/actions/target.d.ts +3 -0
- package/lib/actions/target.js +66 -0
- package/lib/actions/target.js.map +1 -0
- package/lib/actions/types.d.ts +181 -0
- package/lib/actions/types.js +48 -0
- package/lib/actions/types.js.map +1 -0
- package/lib/activation-rules.d.ts +29 -0
- package/lib/activation-rules.js +33 -0
- package/lib/activation-rules.js.map +1 -0
- package/lib/approval-policy.d.ts +40 -2
- package/lib/approval-policy.js +184 -97
- package/lib/approval-policy.js.map +1 -1
- package/lib/automation-assets-rpc.d.ts +8 -2
- package/lib/automation-assets-rpc.js +68 -10
- package/lib/automation-assets-rpc.js.map +1 -1
- package/lib/automation-assets.d.ts +152 -4
- package/lib/automation-assets.js +255 -15
- package/lib/automation-assets.js.map +1 -1
- package/lib/automation-convert.d.ts +23 -0
- package/lib/automation-convert.js +110 -0
- package/lib/automation-convert.js.map +1 -0
- package/lib/automation-development.d.ts +26 -0
- package/lib/automation-development.js +47 -0
- package/lib/automation-development.js.map +1 -1
- package/lib/automation-execution.d.ts +57 -1
- package/lib/automation-execution.js +167 -11
- package/lib/automation-execution.js.map +1 -1
- package/lib/automation-journal.d.ts +92 -0
- package/lib/automation-journal.js +449 -0
- package/lib/automation-journal.js.map +1 -0
- package/lib/automation-v2.d.ts +138 -0
- package/lib/automation-v2.js +631 -0
- package/lib/automation-v2.js.map +1 -0
- package/lib/automation.d.ts +82 -5
- package/lib/automation.js +239 -82
- package/lib/automation.js.map +1 -1
- package/lib/browser-service.d.ts +309 -32
- package/lib/browser-service.js +636 -182
- package/lib/browser-service.js.map +1 -1
- package/lib/client/SettingsCard.js +95 -57
- package/lib/client/SettingsCard.js.map +1 -1
- package/lib/client/asset-editor.d.ts +55 -0
- package/lib/client/asset-editor.js +101 -0
- package/lib/client/asset-editor.js.map +1 -0
- package/lib/client/automation-assets-client.d.ts +99 -2
- package/lib/client/automation-assets-client.js +243 -10
- package/lib/client/automation-assets-client.js.map +1 -1
- package/lib/client/form.d.ts +48 -4
- package/lib/client/form.js +142 -29
- package/lib/client/form.js.map +1 -1
- package/lib/client/index.d.ts +25 -2
- package/lib/client/index.js +5 -1
- package/lib/client/index.js.map +1 -1
- package/lib/client/locales.d.ts +85 -6
- package/lib/client/locales.js +64 -12
- package/lib/client/locales.js.map +1 -1
- package/lib/client/prompts-form.d.ts +67 -0
- package/lib/client/prompts-form.js +140 -0
- package/lib/client/prompts-form.js.map +1 -0
- package/lib/client/prompts-status-client.d.ts +34 -0
- package/lib/client/prompts-status-client.js +53 -0
- package/lib/client/prompts-status-client.js.map +1 -0
- package/lib/client/settings-namespace.d.ts +1 -1
- package/lib/client/settings-namespace.js +1 -1
- package/lib/client/settings-namespace.js.map +1 -1
- package/lib/client.js +1915 -330
- package/lib/client.js.map +1 -1
- package/lib/config.d.ts +50 -1
- package/lib/config.js +31 -1
- package/lib/config.js.map +1 -1
- package/lib/dialogs.d.ts +37 -0
- package/lib/dialogs.js +73 -0
- package/lib/dialogs.js.map +1 -0
- package/lib/freedom.d.ts +23 -7
- package/lib/freedom.js +48 -59
- package/lib/freedom.js.map +1 -1
- package/lib/index.d.ts +5 -13
- package/lib/index.js +51 -30
- package/lib/index.js.map +1 -1
- package/lib/journal.d.ts +109 -0
- package/lib/journal.js +238 -0
- package/lib/journal.js.map +1 -0
- package/lib/locator.d.ts +82 -0
- package/lib/locator.js +190 -0
- package/lib/locator.js.map +1 -0
- package/lib/observe-script.d.ts +27 -0
- package/lib/observe-script.js +565 -0
- package/lib/observe-script.js.map +1 -0
- package/lib/observe.d.ts +179 -0
- package/lib/observe.js +368 -0
- package/lib/observe.js.map +1 -0
- package/lib/policy-keys.d.ts +30 -0
- package/lib/policy-keys.js +34 -0
- package/lib/policy-keys.js.map +1 -0
- package/lib/prompt-limits.d.ts +30 -0
- package/lib/prompt-limits.js +31 -0
- package/lib/prompt-limits.js.map +1 -0
- package/lib/prompts.d.ts +131 -0
- package/lib/prompts.js +295 -0
- package/lib/prompts.js.map +1 -0
- package/lib/skill.d.ts +100 -0
- package/lib/skill.js +181 -0
- package/lib/skill.js.map +1 -0
- package/lib/tool-defs.d.ts +72 -0
- package/lib/tool-defs.js +67 -0
- package/lib/tool-defs.js.map +1 -0
- package/lib/tools.d.ts +19 -4
- package/lib/tools.js +124 -922
- package/lib/tools.js.map +1 -1
- package/package.json +15 -11
- package/scripts/check-host-rpc.mjs +11 -4
- package/scripts/dump-prompts.mjs +29 -0
- package/scripts/measure-tool-surface.mjs +190 -0
- package/lib/settings-scope.d.ts +0 -56
- package/lib/settings-scope.js +0 -51
- package/lib/settings-scope.js.map +0 -1
package/lib/journal.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exploration journal: a bounded, in-memory record of what one session did through `browser_call`.
|
|
3
|
+
*
|
|
4
|
+
* It is evidence for turning an exploration into a draft (`automation.develop` draft_from_journal), not a
|
|
5
|
+
* log of the page. Entries hold the action, the page generation before and after, the locator, scrubbed
|
|
6
|
+
* parameters, and the outcome. Typed text never appears in an entry: fill/type text is a reference
|
|
7
|
+
* `{ref:'v<seq>', length, sensitive?}`. The text itself is kept in memory only when it is short (at most
|
|
8
|
+
* {@link RAW_TEXT_MAX} characters) and does not look secret (see {@link looksSecret}), and only so a draft
|
|
9
|
+
* can use it as a literal or an example; it is released together with its entry, and nothing is written to disk.
|
|
10
|
+
* @module dsh-browser/journal
|
|
11
|
+
*/
|
|
12
|
+
/** Default number of entries a session keeps; the oldest are dropped first. */
|
|
13
|
+
export const JOURNAL_LIMIT = 200;
|
|
14
|
+
/** Typed text longer than this is never retained, only its length. */
|
|
15
|
+
export const RAW_TEXT_MAX = 200;
|
|
16
|
+
// --- what counts as secret -----------------------------------------------------
|
|
17
|
+
/** Field names that suggest a secret; the same list `observe.read` uses for controls. */
|
|
18
|
+
export const SENSITIVE_NAME = /(^|[^a-z])(pass(word|wd|phrase|code)?|pwd|secret|token|api[-_ ]?key|credential|bearer|jwt|otp|csrf|xsrf|session[-_ ]?(id|key)?|ssn|cvv|cvc|private[-_ ]?key|authori[sz]ation|auth[-_ ]?(token|key|code)|one[-_ ]?time[-_ ]?code|card[-_ ]?(number|num|no)|cc[-_ ]?(number|num|csc|exp)|iban|account[-_ ]?(number|num))([^a-z]|$)/i;
|
|
19
|
+
function camel(value) { return value.replace(/([a-z])([A-Z])/g, '$1 $2'); }
|
|
20
|
+
export function cardLike(value) {
|
|
21
|
+
const digits = value.replace(/[ -]/g, '');
|
|
22
|
+
if (!/^\d{13,19}$/.test(digits))
|
|
23
|
+
return false;
|
|
24
|
+
let sum = 0;
|
|
25
|
+
for (let i = 0; i < digits.length; i++) {
|
|
26
|
+
let digit = Number(digits[digits.length - 1 - i]);
|
|
27
|
+
if (i % 2 === 1) {
|
|
28
|
+
digit *= 2;
|
|
29
|
+
if (digit > 9)
|
|
30
|
+
digit -= 9;
|
|
31
|
+
}
|
|
32
|
+
sum += digit;
|
|
33
|
+
}
|
|
34
|
+
return sum % 10 === 0;
|
|
35
|
+
}
|
|
36
|
+
export function tokenLike(value) {
|
|
37
|
+
if (cardLike(value))
|
|
38
|
+
return true;
|
|
39
|
+
if (value.length < 20 || /\s/.test(value))
|
|
40
|
+
return false;
|
|
41
|
+
if (/^eyJ[\w-]+\.[\w-]+\.[\w-]*$/.test(value))
|
|
42
|
+
return true;
|
|
43
|
+
return /^[A-Za-z0-9_\-+/=.~]+$/.test(value) && /\d/.test(value) && /[A-Za-z]/.test(value);
|
|
44
|
+
}
|
|
45
|
+
/** A value that looks like a token, a JWT or a card number. */
|
|
46
|
+
export function looksSecret(value) {
|
|
47
|
+
return tokenLike(value);
|
|
48
|
+
}
|
|
49
|
+
/** A locator that names a password-like field (its label, name, css...). */
|
|
50
|
+
export function locatorSuggestsSecret(locator) {
|
|
51
|
+
if (!locator)
|
|
52
|
+
return false;
|
|
53
|
+
const parts = [locator.name, locator.label, locator.text, locator.testId, locator.selector, locator.css].filter((part) => typeof part === 'string');
|
|
54
|
+
return parts.some(part => SENSITIVE_NAME.test(camel(part)));
|
|
55
|
+
}
|
|
56
|
+
/** `https://u:p@host/path?token=x` -> secret query values and userinfo removed. Returns the cleaned URL and whether anything was removed. */
|
|
57
|
+
export function redactUrl(value) {
|
|
58
|
+
try {
|
|
59
|
+
const parsed = new URL(value);
|
|
60
|
+
let redacted = false;
|
|
61
|
+
if (parsed.username || parsed.password) {
|
|
62
|
+
parsed.username = '';
|
|
63
|
+
parsed.password = '';
|
|
64
|
+
redacted = true;
|
|
65
|
+
}
|
|
66
|
+
for (const key of [...parsed.searchParams.keys()]) {
|
|
67
|
+
const raw = parsed.searchParams.get(key) ?? '';
|
|
68
|
+
if (SENSITIVE_NAME.test(camel(key)) || /token|key|auth|session|cookie|password|secret/i.test(key) || tokenLike(raw)) {
|
|
69
|
+
parsed.searchParams.set(key, '[redacted]');
|
|
70
|
+
redacted = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { url: parsed.toString().slice(0, 2_000), redacted };
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return { url: value.slice(0, 200), redacted: false };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// --- scrubbing a call's arguments ---------------------------------------------
|
|
80
|
+
/** Arguments that steer a call but carry no value worth keeping. */
|
|
81
|
+
const SKIP = new Set(['locator', 'selector', 'expectGeneration']);
|
|
82
|
+
/** Text typed into a control: always a reference. */
|
|
83
|
+
const TYPED = new Set(['act.fill', 'act.type']);
|
|
84
|
+
function clip(value, max = 200) { return value.length > max ? value.slice(0, max) + '…' : value; }
|
|
85
|
+
function normalizeLocator(args) {
|
|
86
|
+
const given = args.locator;
|
|
87
|
+
if (typeof args.selector === 'string' && given === undefined)
|
|
88
|
+
return { css: clip(args.selector, 500) };
|
|
89
|
+
if (!given || typeof given !== 'object' || Array.isArray(given))
|
|
90
|
+
return undefined;
|
|
91
|
+
const copy = {};
|
|
92
|
+
for (const [key, value] of Object.entries(given)) {
|
|
93
|
+
if (typeof value === 'string')
|
|
94
|
+
copy[key === 'selector' ? 'css' : key] = clip(value, 500);
|
|
95
|
+
else
|
|
96
|
+
copy[key] = value;
|
|
97
|
+
}
|
|
98
|
+
return copy;
|
|
99
|
+
}
|
|
100
|
+
/** A short plain value kept as is; anything long or secret-looking becomes a reference. */
|
|
101
|
+
function scrubValue(value, seq, index = 0) {
|
|
102
|
+
if (typeof value !== 'string')
|
|
103
|
+
return value;
|
|
104
|
+
if (value.length > RAW_TEXT_MAX || looksSecret(value))
|
|
105
|
+
return { ref: `v${seq}${index ? '.' + index : ''}`, length: value.length, ...looksSecret(value) ? { sensitive: true } : {} };
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Scrub the arguments of one call. `sensitiveControl` is true when the page itself says the target is a
|
|
110
|
+
* password-like control (type=password, autocomplete one-time-code, ...).
|
|
111
|
+
*/
|
|
112
|
+
export function scrubCall(action, args, seq, sensitiveControl = false) {
|
|
113
|
+
const locator = normalizeLocator(args);
|
|
114
|
+
const params = {};
|
|
115
|
+
let raw;
|
|
116
|
+
for (const [key, value] of Object.entries(args)) {
|
|
117
|
+
if (SKIP.has(key) || value === undefined)
|
|
118
|
+
continue;
|
|
119
|
+
if (typeof value === 'string') {
|
|
120
|
+
if (TYPED.has(action) && key === 'text') {
|
|
121
|
+
const sensitive = sensitiveControl || locatorSuggestsSecret(locator) || looksSecret(value);
|
|
122
|
+
params[key] = { ref: `v${seq}`, length: value.length, ...sensitive ? { sensitive: true } : {} };
|
|
123
|
+
if (!sensitive && value.length <= RAW_TEXT_MAX)
|
|
124
|
+
raw = value;
|
|
125
|
+
}
|
|
126
|
+
else if (key === 'url')
|
|
127
|
+
params[key] = redactUrl(value).url;
|
|
128
|
+
else if (['expression', 'source', 'code', 'script'].includes(key))
|
|
129
|
+
params[key] = { ref: `v${seq}`, length: value.length };
|
|
130
|
+
else
|
|
131
|
+
params[key] = scrubValue(value, seq);
|
|
132
|
+
}
|
|
133
|
+
else if (Array.isArray(value)) {
|
|
134
|
+
if (key === 'files')
|
|
135
|
+
params.files = { count: value.length, names: value.slice(0, 5).map(file => clip(String(file).split(/[\\/]/).pop() ?? '', 80)) };
|
|
136
|
+
else if (['steps', 'recipe'].includes(key))
|
|
137
|
+
params[key] = { count: value.length };
|
|
138
|
+
else
|
|
139
|
+
params[key] = value.slice(0, 20).map((entry, index) => scrubValue(entry, seq, index + 1));
|
|
140
|
+
}
|
|
141
|
+
else if (value && typeof value === 'object') {
|
|
142
|
+
// inputs and the like: only the names, never the values.
|
|
143
|
+
params[key] = { keys: Object.keys(value).slice(0, 10) };
|
|
144
|
+
}
|
|
145
|
+
else
|
|
146
|
+
params[key] = value;
|
|
147
|
+
}
|
|
148
|
+
return { params, ...locator ? { locator } : {}, ...raw !== undefined ? { raw } : {} };
|
|
149
|
+
}
|
|
150
|
+
// --- which calls are journaled -------------------------------------------------
|
|
151
|
+
const JOURNALED_GROUPS = new Set(['target', 'observe', 'act', 'script']);
|
|
152
|
+
const JOURNALED_EXTRA = new Set(['automation.run_recipe', 'automation.run']);
|
|
153
|
+
/** Calls that only read the page: observation points, never steps. */
|
|
154
|
+
const OBSERVATIONS = new Set(['observe.read', 'observe.screenshot']);
|
|
155
|
+
/** Whether a call goes into the journal. Lists, inspection, searches and drafting are not exploration. */
|
|
156
|
+
export function isJournaled(action) {
|
|
157
|
+
if (action === 'target.list')
|
|
158
|
+
return false;
|
|
159
|
+
return JOURNALED_GROUPS.has(action.split('.')[0]) || JOURNALED_EXTRA.has(action);
|
|
160
|
+
}
|
|
161
|
+
export function isObservation(action) {
|
|
162
|
+
return OBSERVATIONS.has(action);
|
|
163
|
+
}
|
|
164
|
+
/** What a finished call changed, from what it is and how it ended. */
|
|
165
|
+
export function effectsOf(mutating, outcome) {
|
|
166
|
+
if (!mutating)
|
|
167
|
+
return 'none';
|
|
168
|
+
if (outcome.ok)
|
|
169
|
+
return 'observed';
|
|
170
|
+
if (outcome.executionStatus === 'outcome_unknown')
|
|
171
|
+
return 'unknown';
|
|
172
|
+
const never = ['LOCATOR_NOT_FOUND', 'LOCATOR_AMBIGUOUS', 'NOT_ACTIONABLE', 'TARGET_STALE', 'INVALID_ARGS', 'TARGET_CLOSED', 'POLICY_DENIED', 'INVALID_RECIPE'];
|
|
173
|
+
return outcome.errorCode && never.includes(outcome.errorCode) ? 'none' : 'unknown';
|
|
174
|
+
}
|
|
175
|
+
// --- the journal itself --------------------------------------------------------
|
|
176
|
+
export class SessionJournal {
|
|
177
|
+
limit;
|
|
178
|
+
nextSeq = 1;
|
|
179
|
+
items = [];
|
|
180
|
+
raws = new Map();
|
|
181
|
+
/** How many entries fell off the front because of the limit. */
|
|
182
|
+
dropped = 0;
|
|
183
|
+
constructor(limit = JOURNAL_LIMIT) {
|
|
184
|
+
this.limit = limit;
|
|
185
|
+
}
|
|
186
|
+
/** Reserve the sequence number of a call that is about to run. */
|
|
187
|
+
allocate() {
|
|
188
|
+
return this.nextSeq++;
|
|
189
|
+
}
|
|
190
|
+
add(entry, raw) {
|
|
191
|
+
this.items.push(entry);
|
|
192
|
+
if (this.items.length > 1 && this.items[this.items.length - 2].seq > entry.seq)
|
|
193
|
+
this.items.sort((a, b) => a.seq - b.seq);
|
|
194
|
+
if (raw !== undefined)
|
|
195
|
+
this.raws.set(entry.seq, raw);
|
|
196
|
+
while (this.items.length > this.limit) {
|
|
197
|
+
const gone = this.items.shift();
|
|
198
|
+
this.raws.delete(gone.seq);
|
|
199
|
+
this.dropped += 1;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
entries() {
|
|
203
|
+
return this.items;
|
|
204
|
+
}
|
|
205
|
+
/** The retained typed text of an entry, if it was short and not secret. Internal: never part of an entry. */
|
|
206
|
+
rawText(seq) {
|
|
207
|
+
return this.raws.get(seq);
|
|
208
|
+
}
|
|
209
|
+
get firstSeq() { return this.items[0]?.seq; }
|
|
210
|
+
get lastSeq() { return this.items[this.items.length - 1]?.seq; }
|
|
211
|
+
get size() { return this.items.length; }
|
|
212
|
+
clear() {
|
|
213
|
+
this.items = [];
|
|
214
|
+
this.raws.clear();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** The one-line summary of a finished call, with no secret query values. */
|
|
218
|
+
export function summarize(action, envelope) {
|
|
219
|
+
if (!envelope.ok)
|
|
220
|
+
return clip(`${envelope.error?.code ?? 'FAILED'}: ${String(envelope.error?.message ?? '').split('\n')[0]}`, 140);
|
|
221
|
+
const result = envelope.result ?? {};
|
|
222
|
+
const parts = [];
|
|
223
|
+
if (typeof result.title === 'string' && result.title)
|
|
224
|
+
parts.push(clip(result.title, 60));
|
|
225
|
+
if (typeof result.url === 'string' && result.url) {
|
|
226
|
+
try {
|
|
227
|
+
const parsed = new URL(redactUrl(result.url).url);
|
|
228
|
+
parts.push(parsed.pathname + parsed.search);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
parts.push(clip(result.url, 80));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (typeof result.text === 'string' && isObservation(action))
|
|
235
|
+
parts.push(`${result.text.length} chars`);
|
|
236
|
+
return clip(parts.join(' | ') || 'ok', 140);
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"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"}
|
package/lib/locator.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One locator contract for atomic actions and v2 recipe steps.
|
|
3
|
+
*
|
|
4
|
+
* A locator is strict by default: it must match exactly one element. When it
|
|
5
|
+
* matches several, the step is not performed and the caller gets
|
|
6
|
+
* {@link LocatorAmbiguousError} with a short summary of the first candidates, so
|
|
7
|
+
* the model can tell which element it meant instead of acting on whichever one
|
|
8
|
+
* happened to come first. Choosing one anyway takes an explicit `index` with an
|
|
9
|
+
* `indexReason`; `explicitFirst` is the marker a v1 migration leaves behind for
|
|
10
|
+
* "this used to be `.first()`".
|
|
11
|
+
* @module dsh-browser/locator
|
|
12
|
+
*/
|
|
13
|
+
export interface BrowserFrameSpec {
|
|
14
|
+
selector?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface BrowserLocatorSpec {
|
|
19
|
+
/** CSS selector. `css` is accepted as an alias (the v2 recipe spelling). */
|
|
20
|
+
selector?: string;
|
|
21
|
+
css?: string;
|
|
22
|
+
role?: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
text?: string;
|
|
25
|
+
label?: string;
|
|
26
|
+
testId?: string;
|
|
27
|
+
exact?: boolean;
|
|
28
|
+
/** Atomic-action iframe: exactly one of selector, name, url. */
|
|
29
|
+
frame?: BrowserFrameSpec;
|
|
30
|
+
/** Nested iframes, outermost first, each a CSS selector for an iframe element. */
|
|
31
|
+
framePath?: string[];
|
|
32
|
+
/** Pick the n-th match (0-based). Requires `indexReason`. */
|
|
33
|
+
index?: number;
|
|
34
|
+
indexReason?: string;
|
|
35
|
+
/** Take the first match without an ambiguity error. Set by the v1 converter; meant to be resolved later. */
|
|
36
|
+
explicitFirst?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export type BrowserTarget = string | BrowserLocatorSpec;
|
|
39
|
+
/** What one of several matches looks like, enough to choose between them. */
|
|
40
|
+
export interface LocatorCandidate {
|
|
41
|
+
index: number;
|
|
42
|
+
role: string;
|
|
43
|
+
name: string;
|
|
44
|
+
text: string;
|
|
45
|
+
visible: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface LocatorAmbiguity {
|
|
48
|
+
total: number;
|
|
49
|
+
items: LocatorCandidate[];
|
|
50
|
+
}
|
|
51
|
+
/** Raised instead of acting when a strict locator matches more than one element. */
|
|
52
|
+
export declare class LocatorAmbiguousError extends Error {
|
|
53
|
+
readonly ambiguity: LocatorAmbiguity;
|
|
54
|
+
constructor(message: string, ambiguity: LocatorAmbiguity);
|
|
55
|
+
}
|
|
56
|
+
/** Where a page stands now: what a stale caller needs to re-bind to it. */
|
|
57
|
+
export interface PageGeneration {
|
|
58
|
+
targetId: string;
|
|
59
|
+
generation: number;
|
|
60
|
+
}
|
|
61
|
+
/** Raised, before anything is done, when `expectGeneration` is not the page's current generation. */
|
|
62
|
+
export declare class TargetStaleError extends Error {
|
|
63
|
+
readonly current: PageGeneration;
|
|
64
|
+
constructor(message: string, current: PageGeneration);
|
|
65
|
+
}
|
|
66
|
+
export declare const MAX_CANDIDATES = 5;
|
|
67
|
+
/** Check a locator's shape. Throws a message the model can act on; used before resolving and when a recipe is saved. */
|
|
68
|
+
export declare function validateLocatorSpec(spec: unknown, label?: string): BrowserLocatorSpec;
|
|
69
|
+
/**
|
|
70
|
+
* Build the Playwright locator for a target. No `.first()` unless the spec asks
|
|
71
|
+
* for it, so Playwright's own strict-mode check stays in force.
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveLocator(page: any, target: BrowserTarget): any;
|
|
74
|
+
/** The first candidates of a locator, best effort: a failure here must not hide the ambiguity itself. */
|
|
75
|
+
export declare function describeCandidates(locator: any): Promise<LocatorAmbiguity>;
|
|
76
|
+
export declare function formatCandidates(ambiguity: LocatorAmbiguity): string;
|
|
77
|
+
/**
|
|
78
|
+
* Run an action on a strict locator. If the locator turns out to match several
|
|
79
|
+
* elements, nothing was acted on (Playwright checks before it acts) and the
|
|
80
|
+
* error is upgraded with the candidate summary.
|
|
81
|
+
*/
|
|
82
|
+
export declare function withStrictLocator<T>(locator: any, run: (locator: any) => Promise<T>): Promise<T>;
|
package/lib/locator.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One locator contract for atomic actions and v2 recipe steps.
|
|
3
|
+
*
|
|
4
|
+
* A locator is strict by default: it must match exactly one element. When it
|
|
5
|
+
* matches several, the step is not performed and the caller gets
|
|
6
|
+
* {@link LocatorAmbiguousError} with a short summary of the first candidates, so
|
|
7
|
+
* the model can tell which element it meant instead of acting on whichever one
|
|
8
|
+
* happened to come first. Choosing one anyway takes an explicit `index` with an
|
|
9
|
+
* `indexReason`; `explicitFirst` is the marker a v1 migration leaves behind for
|
|
10
|
+
* "this used to be `.first()`".
|
|
11
|
+
* @module dsh-browser/locator
|
|
12
|
+
*/
|
|
13
|
+
/** Raised instead of acting when a strict locator matches more than one element. */
|
|
14
|
+
export class LocatorAmbiguousError extends Error {
|
|
15
|
+
ambiguity;
|
|
16
|
+
constructor(message, ambiguity) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.ambiguity = ambiguity;
|
|
19
|
+
this.name = 'LocatorAmbiguousError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Raised, before anything is done, when `expectGeneration` is not the page's current generation. */
|
|
23
|
+
export class TargetStaleError extends Error {
|
|
24
|
+
current;
|
|
25
|
+
constructor(message, current) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.current = current;
|
|
28
|
+
this.name = 'TargetStaleError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const MODES = ['selector', 'css', 'role', 'text', 'label', 'testId'];
|
|
32
|
+
const KNOWN_KEYS = new Set([...MODES, 'name', 'exact', 'frame', 'framePath', 'index', 'indexReason', 'explicitFirst']);
|
|
33
|
+
const MAX_FRAME_PATH = 5;
|
|
34
|
+
export const MAX_CANDIDATES = 5;
|
|
35
|
+
function bounded(value, label, max) {
|
|
36
|
+
if (typeof value !== 'string' || value.length < 1 || value.length > max)
|
|
37
|
+
throw new Error(`${label} must contain 1 to ${max} characters`);
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
/** Check a locator's shape. Throws a message the model can act on; used before resolving and when a recipe is saved. */
|
|
41
|
+
export function validateLocatorSpec(spec, label = 'browser target') {
|
|
42
|
+
if (!spec || typeof spec !== 'object' || Array.isArray(spec))
|
|
43
|
+
throw new Error(`${label} must be a selector string or locator object`);
|
|
44
|
+
const value = spec;
|
|
45
|
+
for (const key of Object.keys(value))
|
|
46
|
+
if (!KNOWN_KEYS.has(key))
|
|
47
|
+
throw new Error(`${label} has an unsupported field "${key}"; use ${[...KNOWN_KEYS].join(', ')}`);
|
|
48
|
+
const modes = MODES.filter(mode => value[mode] !== undefined);
|
|
49
|
+
if (modes.length !== 1)
|
|
50
|
+
throw new Error(`${label} requires exactly one of selector (css), role, text, label, or testId`);
|
|
51
|
+
if (value.name !== undefined && value.role === undefined)
|
|
52
|
+
throw new Error(`${label} name is only valid with role`);
|
|
53
|
+
if (value.exact !== undefined && typeof value.exact !== 'boolean')
|
|
54
|
+
throw new Error(`${label} exact must be a boolean`);
|
|
55
|
+
if (value.index !== undefined) {
|
|
56
|
+
if (!Number.isInteger(value.index) || value.index < 0 || value.index > 1000)
|
|
57
|
+
throw new Error(`${label} index must be an integer from 0 to 1000`);
|
|
58
|
+
if (typeof value.indexReason !== 'string' || !value.indexReason.trim())
|
|
59
|
+
throw new Error(`${label} index requires indexReason: say why this match and not the others`);
|
|
60
|
+
}
|
|
61
|
+
if (value.indexReason !== undefined && value.index === undefined)
|
|
62
|
+
throw new Error(`${label} indexReason is only valid with index`);
|
|
63
|
+
if (value.index !== undefined && value.explicitFirst)
|
|
64
|
+
throw new Error(`${label} cannot combine index and explicitFirst`);
|
|
65
|
+
if (value.explicitFirst !== undefined && typeof value.explicitFirst !== 'boolean')
|
|
66
|
+
throw new Error(`${label} explicitFirst must be a boolean`);
|
|
67
|
+
if (value.frame !== undefined && value.framePath !== undefined)
|
|
68
|
+
throw new Error(`${label} cannot combine frame and framePath`);
|
|
69
|
+
if (value.framePath !== undefined) {
|
|
70
|
+
if (!Array.isArray(value.framePath) || value.framePath.length < 1 || value.framePath.length > MAX_FRAME_PATH)
|
|
71
|
+
throw new Error(`${label} framePath must list 1 to ${MAX_FRAME_PATH} iframe selectors`);
|
|
72
|
+
value.framePath.forEach(entry => bounded(entry, `${label} framePath entry`, 500));
|
|
73
|
+
}
|
|
74
|
+
if (value.frame !== undefined) {
|
|
75
|
+
const frameModes = [value.frame.selector, value.frame.name, value.frame.url].filter(entry => entry !== undefined);
|
|
76
|
+
if (frameModes.length !== 1)
|
|
77
|
+
throw new Error('browser frame requires exactly one of selector, name, or url');
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build the Playwright locator for a target. No `.first()` unless the spec asks
|
|
83
|
+
* for it, so Playwright's own strict-mode check stays in force.
|
|
84
|
+
*/
|
|
85
|
+
export function resolveLocator(page, target) {
|
|
86
|
+
if (!target || (typeof target !== 'string' && typeof target !== 'object'))
|
|
87
|
+
throw new Error('browser target must be a selector string or locator object');
|
|
88
|
+
const spec = validateLocatorSpec(typeof target === 'string' ? { selector: target } : target);
|
|
89
|
+
let root = page;
|
|
90
|
+
if (spec.frame) {
|
|
91
|
+
if (spec.frame.selector)
|
|
92
|
+
root = page.frameLocator(bounded(spec.frame.selector, 'frame selector', 500));
|
|
93
|
+
else {
|
|
94
|
+
const frame = page.frame(spec.frame.name
|
|
95
|
+
? { name: bounded(spec.frame.name, 'frame name', 500) }
|
|
96
|
+
: { url: bounded(spec.frame.url, 'frame url', 2_000) });
|
|
97
|
+
if (!frame)
|
|
98
|
+
throw new Error('browser target frame was not found');
|
|
99
|
+
root = frame;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const entry of spec.framePath ?? [])
|
|
103
|
+
root = root.frameLocator(entry);
|
|
104
|
+
const css = spec.selector ?? spec.css;
|
|
105
|
+
let locator;
|
|
106
|
+
if (css !== undefined)
|
|
107
|
+
locator = root.locator(bounded(css, 'selector', 500));
|
|
108
|
+
else if (spec.role !== undefined) {
|
|
109
|
+
locator = root.getByRole(bounded(spec.role, 'role', 100), {
|
|
110
|
+
...spec.name !== undefined ? { name: bounded(spec.name, 'role name', 2_000) } : {},
|
|
111
|
+
exact: spec.exact ?? false,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else if (spec.text !== undefined)
|
|
115
|
+
locator = root.getByText(bounded(spec.text, 'text locator', 2_000), { exact: spec.exact ?? false });
|
|
116
|
+
else if (spec.label !== undefined)
|
|
117
|
+
locator = root.getByLabel(bounded(spec.label, 'label locator', 2_000), { exact: spec.exact ?? false });
|
|
118
|
+
else
|
|
119
|
+
locator = root.getByTestId(bounded(spec.testId, 'testId', 500));
|
|
120
|
+
if (spec.index !== undefined)
|
|
121
|
+
return locator.nth(spec.index);
|
|
122
|
+
if (spec.explicitFirst)
|
|
123
|
+
return locator.first();
|
|
124
|
+
return locator;
|
|
125
|
+
}
|
|
126
|
+
/** Summarize the matches of an ambiguous locator, in the page. A raw string: it must not carry transpiler helpers. */
|
|
127
|
+
const SUMMARIZE = `(els) => {
|
|
128
|
+
const implicit = { a: 'link', button: 'button', select: 'combobox', textarea: 'textbox', img: 'img', ul: 'list', ol: 'list', li: 'listitem', nav: 'navigation', main: 'main', table: 'table', form: 'form', h1: 'heading', h2: 'heading', h3: 'heading', h4: 'heading', h5: 'heading', h6: 'heading', summary: 'button', dialog: 'dialog' }
|
|
129
|
+
const inputRole = { checkbox: 'checkbox', radio: 'radio', button: 'button', submit: 'button', reset: 'button', image: 'button', range: 'slider', search: 'searchbox', number: 'spinbutton' }
|
|
130
|
+
const named = ['button', 'link', 'heading', 'menuitem', 'tab', 'option', 'checkbox', 'radio', 'listitem']
|
|
131
|
+
return els.slice(0, ${MAX_CANDIDATES}).map((el, index) => {
|
|
132
|
+
const tag = el.tagName.toLowerCase()
|
|
133
|
+
let role = el.getAttribute('role') || ''
|
|
134
|
+
if (!role) role = tag === 'input' ? (inputRole[(el.getAttribute('type') || 'text').toLowerCase()] || 'textbox') : (implicit[tag] || '')
|
|
135
|
+
const text = String(el.innerText || el.textContent || el.value || '').trim().replace(/\\s+/g, ' ')
|
|
136
|
+
let name = el.getAttribute('aria-label') || ''
|
|
137
|
+
if (!name && el.labels && el.labels.length) name = el.labels[0].innerText || ''
|
|
138
|
+
if (!name) name = el.getAttribute('title') || el.getAttribute('placeholder') || el.getAttribute('alt') || ''
|
|
139
|
+
if (!name && named.includes(role)) name = text
|
|
140
|
+
const rect = el.getBoundingClientRect()
|
|
141
|
+
const style = getComputedStyle(el)
|
|
142
|
+
const visible = rect.width > 0 && rect.height > 0 && style.visibility !== 'hidden' && style.display !== 'none'
|
|
143
|
+
return { index, role: role || tag, name: String(name).trim().slice(0, 80), text: text.slice(0, 80), visible }
|
|
144
|
+
})
|
|
145
|
+
}`;
|
|
146
|
+
/** The first candidates of a locator, best effort: a failure here must not hide the ambiguity itself. */
|
|
147
|
+
export async function describeCandidates(locator) {
|
|
148
|
+
let total = 0;
|
|
149
|
+
let items = [];
|
|
150
|
+
try {
|
|
151
|
+
total = Number(await locator.count()) || 0;
|
|
152
|
+
}
|
|
153
|
+
catch { /* keep 0 */ }
|
|
154
|
+
try {
|
|
155
|
+
// Playwright treats a plain string as an expression, not a function; a Function built from the string serializes as one.
|
|
156
|
+
const rows = await locator.evaluateAll(new Function('els', `return (${SUMMARIZE})(els)`));
|
|
157
|
+
if (Array.isArray(rows))
|
|
158
|
+
items = rows.slice(0, MAX_CANDIDATES).map((row, index) => ({
|
|
159
|
+
index: typeof row?.index === 'number' ? row.index : index,
|
|
160
|
+
role: String(row?.role ?? ''), name: String(row?.name ?? ''), text: String(row?.text ?? ''), visible: row?.visible !== false,
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
catch { /* the summary is optional */ }
|
|
164
|
+
return { total: Math.max(total, items.length), items };
|
|
165
|
+
}
|
|
166
|
+
export function formatCandidates(ambiguity) {
|
|
167
|
+
const rows = ambiguity.items.map(item => `#${item.index} ${item.role}${item.name ? ' ' + JSON.stringify(item.name) : ''}${item.text && item.text !== item.name ? ' text ' + JSON.stringify(item.text) : ''} ${item.visible ? 'visible' : 'hidden'}`);
|
|
168
|
+
return rows.join('; ') + (ambiguity.total > ambiguity.items.length ? `; …${ambiguity.total - ambiguity.items.length} more` : '');
|
|
169
|
+
}
|
|
170
|
+
function isStrictViolation(error) {
|
|
171
|
+
return !(error instanceof LocatorAmbiguousError) && /strict mode violation/i.test(error instanceof Error ? error.message : String(error));
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Run an action on a strict locator. If the locator turns out to match several
|
|
175
|
+
* elements, nothing was acted on (Playwright checks before it acts) and the
|
|
176
|
+
* error is upgraded with the candidate summary.
|
|
177
|
+
*/
|
|
178
|
+
export async function withStrictLocator(locator, run) {
|
|
179
|
+
try {
|
|
180
|
+
return await run(locator);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (!isStrictViolation(error))
|
|
184
|
+
throw error;
|
|
185
|
+
const ambiguity = await describeCandidates(locator);
|
|
186
|
+
const first = (error instanceof Error ? error.message : String(error)).split('\n')[0];
|
|
187
|
+
throw new LocatorAmbiguousError(`Locator matched ${ambiguity.total || 'more than one'} elements, so nothing was done. Candidates: ${formatCandidates(ambiguity) || '(unavailable)'}. Make the locator unique (role+name, exact, label, testId, frame), or pass index with indexReason. [${first}]`, ambiguity);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.js","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The in-page half of observe.read: one function, shipped to the page as source text.
|
|
3
|
+
*
|
|
4
|
+
* It is a raw string on purpose: it runs inside the page, so it must not carry transpiler helpers, and
|
|
5
|
+
* it must not use template literals (the string is written with String.raw). It reads the DOM and
|
|
6
|
+
* returns plain data; it never changes the page. The only thing it leaves behind is a WeakMap stored
|
|
7
|
+
* under a registered symbol on each scanned window, which maps each listed element to its number, so
|
|
8
|
+
* that the Node side can later prove that a candidate locator points at that very element.
|
|
9
|
+
*
|
|
10
|
+
* Coverage: the document, open shadow roots (recursively), and same-origin iframes (recursively, up to
|
|
11
|
+
* the frame-path limit). A cross-origin or sandboxed iframe is listed as a frame with its limitation,
|
|
12
|
+
* never entered. Closed shadow roots cannot be seen from page script and are not covered.
|
|
13
|
+
* @module dsh-browser/observe-script
|
|
14
|
+
*/
|
|
15
|
+
/** Symbol (registered with Symbol.for) under which each scanned window keeps its element-number map. */
|
|
16
|
+
export declare const OBSERVE_SYMBOL = "dsh.observe";
|
|
17
|
+
/** Maximum iframe nesting the scan enters; matches the locator framePath limit. */
|
|
18
|
+
export declare const OBSERVE_MAX_FRAME_DEPTH = 5;
|
|
19
|
+
/** Maximum number of iframes entered in one observation. */
|
|
20
|
+
export declare const OBSERVE_MAX_FRAMES = 20;
|
|
21
|
+
/** Reads, in the element's own window, the numbers of the elements a locator matched. */
|
|
22
|
+
export declare const IDENTITY_SOURCE: string;
|
|
23
|
+
/**
|
|
24
|
+
* `(root, opts) => result`. `root` is a Document or the Element an observation is scoped to.
|
|
25
|
+
* opts: { controls, links, tables, maxItems, includeValues, region?, maxFrameDepth, maxFrames }.
|
|
26
|
+
*/
|
|
27
|
+
export declare const OBSERVE_SOURCE: string;
|