sentience-ts 0.10.3
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 +193 -0
- package/dist/actions.d.ts +9 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +113 -0
- package/dist/actions.js.map +1 -0
- package/dist/browser.d.ts +24 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +236 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +158 -0
- package/dist/cli.js.map +1 -0
- package/dist/expect.d.ts +16 -0
- package/dist/expect.d.ts.map +1 -0
- package/dist/expect.js +66 -0
- package/dist/expect.js.map +1 -0
- package/dist/generator.d.ts +16 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +205 -0
- package/dist/generator.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector.d.ts +13 -0
- package/dist/inspector.d.ts.map +1 -0
- package/dist/inspector.js +147 -0
- package/dist/inspector.js.map +1 -0
- package/dist/query.d.ts +8 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +337 -0
- package/dist/query.js.map +1 -0
- package/dist/read.d.ts +40 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +86 -0
- package/dist/read.js.map +1 -0
- package/dist/recorder.d.ts +44 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +256 -0
- package/dist/recorder.js.map +1 -0
- package/dist/screenshot.d.ts +17 -0
- package/dist/screenshot.d.ts.map +1 -0
- package/dist/screenshot.js +37 -0
- package/dist/screenshot.js.map +1 -0
- package/dist/snapshot.d.ts +20 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +101 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/wait.d.ts +7 -0
- package/dist/wait.d.ts.map +1 -0
- package/dist/wait.js +37 -0
- package/dist/wait.js.map +1 -0
- package/package.json +58 -0
- package/spec/README.md +72 -0
- package/spec/SNAPSHOT_V1.md +208 -0
- package/spec/sdk-types.md +259 -0
- package/spec/snapshot.schema.json +148 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recorder - captures user actions into a trace
|
|
3
|
+
*/
|
|
4
|
+
import { SentienceBrowser } from './browser';
|
|
5
|
+
import { Snapshot } from './types';
|
|
6
|
+
export interface TraceStep {
|
|
7
|
+
ts: number;
|
|
8
|
+
type: 'navigation' | 'click' | 'type' | 'press' | 'wait' | 'assert';
|
|
9
|
+
selector?: string;
|
|
10
|
+
element_id?: number;
|
|
11
|
+
text?: string;
|
|
12
|
+
key?: string;
|
|
13
|
+
url?: string;
|
|
14
|
+
snapshot?: Snapshot;
|
|
15
|
+
}
|
|
16
|
+
export interface Trace {
|
|
17
|
+
version: string;
|
|
18
|
+
created_at: string;
|
|
19
|
+
start_url: string;
|
|
20
|
+
steps: TraceStep[];
|
|
21
|
+
}
|
|
22
|
+
export declare class Recorder {
|
|
23
|
+
private browser;
|
|
24
|
+
private captureSnapshots;
|
|
25
|
+
private trace;
|
|
26
|
+
private active;
|
|
27
|
+
private startTime;
|
|
28
|
+
private maskPatterns;
|
|
29
|
+
constructor(browser: SentienceBrowser, captureSnapshots?: boolean);
|
|
30
|
+
start(): void;
|
|
31
|
+
stop(): void;
|
|
32
|
+
addMaskPattern(pattern: string): void;
|
|
33
|
+
private shouldMask;
|
|
34
|
+
recordNavigation(url: string): void;
|
|
35
|
+
recordClick(elementId: number, selector?: string): Promise<void>;
|
|
36
|
+
recordType(elementId: number, text: string, selector?: string): Promise<void>;
|
|
37
|
+
recordPress(key: string): void;
|
|
38
|
+
getTrace(): Trace;
|
|
39
|
+
save(filepath: string): Promise<void>;
|
|
40
|
+
static load(filepath: string): Promise<Trace>;
|
|
41
|
+
private inferSelector;
|
|
42
|
+
}
|
|
43
|
+
export declare function record(browser: SentienceBrowser, captureSnapshots?: boolean): Recorder;
|
|
44
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAW,MAAM,SAAS,CAAC;AAI5C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,qBAAa,QAAQ;IAOjB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,gBAAgB;IAP1B,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,YAAY,CAAgB;gBAG1B,OAAO,EAAE,gBAAgB,EACzB,gBAAgB,GAAE,OAAe;IAG3C,KAAK,IAAI,IAAI;IAcb,IAAI,IAAI,IAAI;IAIZ,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC,OAAO,CAAC,UAAU;IAKlB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAW7B,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwChE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnF,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAW9B,QAAQ,IAAI,KAAK;IAOX,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAS9B,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;YAMrC,aAAa;CAwF5B;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,GAAE,OAAe,GAAG,QAAQ,CAE7F"}
|
package/dist/recorder.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Recorder - captures user actions into a trace
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Recorder = void 0;
|
|
40
|
+
exports.record = record;
|
|
41
|
+
const snapshot_1 = require("./snapshot");
|
|
42
|
+
const query_1 = require("./query");
|
|
43
|
+
class Recorder {
|
|
44
|
+
constructor(browser, captureSnapshots = false) {
|
|
45
|
+
this.browser = browser;
|
|
46
|
+
this.captureSnapshots = captureSnapshots;
|
|
47
|
+
this.trace = null;
|
|
48
|
+
this.active = false;
|
|
49
|
+
this.startTime = new Date();
|
|
50
|
+
this.maskPatterns = [];
|
|
51
|
+
}
|
|
52
|
+
start() {
|
|
53
|
+
const page = this.browser.getPage();
|
|
54
|
+
this.active = true;
|
|
55
|
+
const startUrl = page.url();
|
|
56
|
+
this.startTime = new Date();
|
|
57
|
+
this.trace = {
|
|
58
|
+
version: '1.0.0',
|
|
59
|
+
created_at: new Date().toISOString(),
|
|
60
|
+
start_url: startUrl,
|
|
61
|
+
steps: [],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
stop() {
|
|
65
|
+
this.active = false;
|
|
66
|
+
}
|
|
67
|
+
addMaskPattern(pattern) {
|
|
68
|
+
this.maskPatterns.push(pattern.toLowerCase());
|
|
69
|
+
}
|
|
70
|
+
shouldMask(text) {
|
|
71
|
+
const textLower = text.toLowerCase();
|
|
72
|
+
return this.maskPatterns.some((pattern) => textLower.includes(pattern));
|
|
73
|
+
}
|
|
74
|
+
recordNavigation(url) {
|
|
75
|
+
if (!this.active || !this.trace)
|
|
76
|
+
return;
|
|
77
|
+
const ts = Date.now() - this.startTime.getTime();
|
|
78
|
+
this.trace.steps.push({
|
|
79
|
+
ts,
|
|
80
|
+
type: 'navigation',
|
|
81
|
+
url,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async recordClick(elementId, selector) {
|
|
85
|
+
if (!this.active || !this.trace)
|
|
86
|
+
return;
|
|
87
|
+
// If no selector provided, try to infer one
|
|
88
|
+
if (!selector) {
|
|
89
|
+
selector = await this.inferSelector(elementId);
|
|
90
|
+
}
|
|
91
|
+
const ts = Date.now() - this.startTime.getTime();
|
|
92
|
+
// Optionally capture snapshot
|
|
93
|
+
if (this.captureSnapshots) {
|
|
94
|
+
try {
|
|
95
|
+
const snap = await (0, snapshot_1.snapshot)(this.browser);
|
|
96
|
+
this.trace.steps.push({
|
|
97
|
+
ts,
|
|
98
|
+
type: 'click',
|
|
99
|
+
element_id: elementId,
|
|
100
|
+
selector,
|
|
101
|
+
snapshot: snap,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
// If snapshot fails, just record without it
|
|
106
|
+
this.trace.steps.push({
|
|
107
|
+
ts,
|
|
108
|
+
type: 'click',
|
|
109
|
+
element_id: elementId,
|
|
110
|
+
selector,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.trace.steps.push({
|
|
116
|
+
ts,
|
|
117
|
+
type: 'click',
|
|
118
|
+
element_id: elementId,
|
|
119
|
+
selector,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async recordType(elementId, text, selector) {
|
|
124
|
+
if (!this.active || !this.trace)
|
|
125
|
+
return;
|
|
126
|
+
// If no selector provided, try to infer one
|
|
127
|
+
if (!selector) {
|
|
128
|
+
selector = await this.inferSelector(elementId);
|
|
129
|
+
}
|
|
130
|
+
const ts = Date.now() - this.startTime.getTime();
|
|
131
|
+
const mask = this.shouldMask(text);
|
|
132
|
+
const maskedText = mask ? '***' : text;
|
|
133
|
+
this.trace.steps.push({
|
|
134
|
+
ts,
|
|
135
|
+
type: 'type',
|
|
136
|
+
element_id: elementId,
|
|
137
|
+
text: maskedText,
|
|
138
|
+
selector,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
recordPress(key) {
|
|
142
|
+
if (!this.active || !this.trace)
|
|
143
|
+
return;
|
|
144
|
+
const ts = Date.now() - this.startTime.getTime();
|
|
145
|
+
this.trace.steps.push({
|
|
146
|
+
ts,
|
|
147
|
+
type: 'press',
|
|
148
|
+
key,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
getTrace() {
|
|
152
|
+
if (!this.trace) {
|
|
153
|
+
throw new Error('No trace available. Start recording first.');
|
|
154
|
+
}
|
|
155
|
+
return this.trace;
|
|
156
|
+
}
|
|
157
|
+
async save(filepath) {
|
|
158
|
+
if (!this.trace) {
|
|
159
|
+
throw new Error('No trace to save. Start recording first.');
|
|
160
|
+
}
|
|
161
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
162
|
+
fs.writeFileSync(filepath, JSON.stringify(this.trace, null, 2), 'utf-8');
|
|
163
|
+
}
|
|
164
|
+
static async load(filepath) {
|
|
165
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
166
|
+
const data = fs.readFileSync(filepath, 'utf-8');
|
|
167
|
+
return JSON.parse(data);
|
|
168
|
+
}
|
|
169
|
+
async inferSelector(elementId) {
|
|
170
|
+
try {
|
|
171
|
+
// Take a snapshot to get element info
|
|
172
|
+
const snap = await (0, snapshot_1.snapshot)(this.browser);
|
|
173
|
+
// Find the element in the snapshot
|
|
174
|
+
let element;
|
|
175
|
+
for (const el of snap.elements) {
|
|
176
|
+
if (el.id === elementId) {
|
|
177
|
+
element = el;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!element) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
// Build candidate selector
|
|
185
|
+
const parts = [];
|
|
186
|
+
// Add role
|
|
187
|
+
if (element.role && element.role !== 'generic') {
|
|
188
|
+
parts.push(`role=${element.role}`);
|
|
189
|
+
}
|
|
190
|
+
// Add text if available
|
|
191
|
+
if (element.text) {
|
|
192
|
+
const textPart = element.text.replace(/"/g, '\\"').substring(0, 50);
|
|
193
|
+
parts.push(`text~"${textPart}"`);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Try to get name/aria-label/placeholder from DOM
|
|
197
|
+
try {
|
|
198
|
+
const el = await this.browser.getPage().evaluate((id) => {
|
|
199
|
+
const registry = window.sentience_registry;
|
|
200
|
+
if (!registry || !registry[id])
|
|
201
|
+
return null;
|
|
202
|
+
const elem = registry[id];
|
|
203
|
+
return {
|
|
204
|
+
name: elem.name || null,
|
|
205
|
+
ariaLabel: elem.getAttribute('aria-label') || null,
|
|
206
|
+
placeholder: elem.placeholder || null,
|
|
207
|
+
};
|
|
208
|
+
}, elementId);
|
|
209
|
+
if (el) {
|
|
210
|
+
if (el.name) {
|
|
211
|
+
parts.push(`name="${el.name}"`);
|
|
212
|
+
}
|
|
213
|
+
else if (el.ariaLabel) {
|
|
214
|
+
parts.push(`text~"${el.ariaLabel}"`);
|
|
215
|
+
}
|
|
216
|
+
else if (el.placeholder) {
|
|
217
|
+
parts.push(`text~"${el.placeholder}"`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
// Ignore errors
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Add clickable if relevant
|
|
226
|
+
if (element.visual_cues.is_clickable) {
|
|
227
|
+
parts.push('clickable=true');
|
|
228
|
+
}
|
|
229
|
+
if (parts.length === 0) {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
const selector = parts.join(' ');
|
|
233
|
+
// Validate selector - should match exactly 1 element
|
|
234
|
+
const matches = (0, query_1.query)(snap, selector);
|
|
235
|
+
if (matches.length === 1) {
|
|
236
|
+
return selector;
|
|
237
|
+
}
|
|
238
|
+
else if (matches.length > 1) {
|
|
239
|
+
// Multiple matches - return selector anyway (could add more constraints later)
|
|
240
|
+
return selector;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// Selector doesn't match - return undefined (will use element_id)
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
exports.Recorder = Recorder;
|
|
253
|
+
function record(browser, captureSnapshots = false) {
|
|
254
|
+
return new Recorder(browser, captureSnapshots);
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot functionality - standalone screenshot capture
|
|
3
|
+
*/
|
|
4
|
+
import { SentienceBrowser } from './browser';
|
|
5
|
+
export interface ScreenshotOptions {
|
|
6
|
+
format?: 'png' | 'jpeg';
|
|
7
|
+
quality?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Capture screenshot of current page
|
|
11
|
+
*
|
|
12
|
+
* @param browser - SentienceBrowser instance
|
|
13
|
+
* @param options - Screenshot options
|
|
14
|
+
* @returns Base64-encoded screenshot data URL (e.g., "data:image/png;base64,...")
|
|
15
|
+
*/
|
|
16
|
+
export declare function screenshot(browser: SentienceBrowser, options?: ScreenshotOptions): Promise<string>;
|
|
17
|
+
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CA2BjB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Screenshot functionality - standalone screenshot capture
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.screenshot = screenshot;
|
|
7
|
+
/**
|
|
8
|
+
* Capture screenshot of current page
|
|
9
|
+
*
|
|
10
|
+
* @param browser - SentienceBrowser instance
|
|
11
|
+
* @param options - Screenshot options
|
|
12
|
+
* @returns Base64-encoded screenshot data URL (e.g., "data:image/png;base64,...")
|
|
13
|
+
*/
|
|
14
|
+
async function screenshot(browser, options = {}) {
|
|
15
|
+
const page = browser.getPage();
|
|
16
|
+
const format = options.format || 'png';
|
|
17
|
+
const quality = options.quality;
|
|
18
|
+
if (format === 'jpeg' && quality !== undefined) {
|
|
19
|
+
if (quality < 1 || quality > 100) {
|
|
20
|
+
throw new Error('Quality must be between 1 and 100 for JPEG format');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Use Playwright's screenshot with base64 encoding
|
|
24
|
+
const screenshotOptions = {
|
|
25
|
+
type: format,
|
|
26
|
+
encoding: 'base64',
|
|
27
|
+
};
|
|
28
|
+
if (format === 'jpeg' && quality !== undefined) {
|
|
29
|
+
screenshotOptions.quality = quality;
|
|
30
|
+
}
|
|
31
|
+
// Capture screenshot
|
|
32
|
+
const base64Data = await page.screenshot(screenshotOptions);
|
|
33
|
+
// Return as data URL
|
|
34
|
+
const mimeType = format === 'png' ? 'image/png' : 'image/jpeg';
|
|
35
|
+
return `data:${mimeType};base64,${base64Data}`;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../src/screenshot.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAgBH,gCA8BC;AArCD;;;;;;GAMG;AACI,KAAK,UAAU,UAAU,CAC9B,OAAyB,EACzB,UAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/C,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,GAAG,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,iBAAiB,GAAQ;QAC7B,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/C,iBAAiB,CAAC,OAAO,GAAG,OAAO,CAAC;IACtC,CAAC;IAED,qBAAqB;IACrB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAE5D,qBAAqB;IACrB,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAC/D,OAAO,QAAQ,QAAQ,WAAW,UAAU,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot functionality - calls window.sentience.snapshot() or server-side API
|
|
3
|
+
*/
|
|
4
|
+
import { SentienceBrowser } from './browser';
|
|
5
|
+
import { Snapshot } from './types';
|
|
6
|
+
export interface SnapshotOptions {
|
|
7
|
+
screenshot?: boolean | {
|
|
8
|
+
format: 'png' | 'jpeg';
|
|
9
|
+
quality?: number;
|
|
10
|
+
};
|
|
11
|
+
limit?: number;
|
|
12
|
+
filter?: {
|
|
13
|
+
min_area?: number;
|
|
14
|
+
allowed_roles?: string[];
|
|
15
|
+
min_z_index?: number;
|
|
16
|
+
};
|
|
17
|
+
use_api?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function snapshot(browser: SentienceBrowser, options?: SnapshotOptions): Promise<Snapshot>;
|
|
20
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,QAAQ,CAAC,CAiBnB"}
|
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Snapshot functionality - calls window.sentience.snapshot() or server-side API
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.snapshot = snapshot;
|
|
7
|
+
async function snapshot(browser, options = {}) {
|
|
8
|
+
// Get API configuration
|
|
9
|
+
const apiKey = browser.getApiKey();
|
|
10
|
+
const apiUrl = browser.getApiUrl();
|
|
11
|
+
// Determine if we should use server-side API
|
|
12
|
+
const shouldUseApi = options.use_api !== undefined
|
|
13
|
+
? options.use_api
|
|
14
|
+
: (apiKey !== undefined);
|
|
15
|
+
if (shouldUseApi && apiKey) {
|
|
16
|
+
// Use server-side API (Pro/Enterprise tier)
|
|
17
|
+
return snapshotViaApi(browser, options, apiKey, apiUrl);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
// Use local extension (Free tier)
|
|
21
|
+
return snapshotViaExtension(browser, options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function snapshotViaExtension(browser, options) {
|
|
25
|
+
const page = browser.getPage();
|
|
26
|
+
// Build options object
|
|
27
|
+
const opts = {};
|
|
28
|
+
if (options.screenshot !== undefined) {
|
|
29
|
+
opts.screenshot = options.screenshot;
|
|
30
|
+
}
|
|
31
|
+
if (options.limit !== undefined) {
|
|
32
|
+
opts.limit = options.limit;
|
|
33
|
+
}
|
|
34
|
+
if (options.filter !== undefined) {
|
|
35
|
+
opts.filter = options.filter;
|
|
36
|
+
}
|
|
37
|
+
// Call extension API
|
|
38
|
+
const result = await page.evaluate((opts) => {
|
|
39
|
+
return window.sentience.snapshot(opts);
|
|
40
|
+
}, opts);
|
|
41
|
+
// Basic validation
|
|
42
|
+
if (result.status !== 'success' && result.status !== 'error') {
|
|
43
|
+
throw new Error(`Invalid snapshot status: ${result.status}`);
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
async function snapshotViaApi(browser, options, apiKey, apiUrl) {
|
|
48
|
+
const page = browser.getPage();
|
|
49
|
+
// Step 1: Get raw data from local extension (always happens locally)
|
|
50
|
+
const rawOpts = {};
|
|
51
|
+
if (options.screenshot !== undefined) {
|
|
52
|
+
rawOpts.screenshot = options.screenshot;
|
|
53
|
+
}
|
|
54
|
+
const rawResult = await page.evaluate((opts) => {
|
|
55
|
+
return window.sentience.snapshot(opts);
|
|
56
|
+
}, rawOpts);
|
|
57
|
+
// Step 2: Send to server for smart ranking/filtering
|
|
58
|
+
// Use raw_elements (raw data) instead of elements (processed data)
|
|
59
|
+
// Server validates API key and applies proprietary ranking logic
|
|
60
|
+
const payload = {
|
|
61
|
+
raw_elements: rawResult.raw_elements || [], // Raw data needed for server processing
|
|
62
|
+
url: rawResult.url || '',
|
|
63
|
+
viewport: rawResult.viewport,
|
|
64
|
+
options: {
|
|
65
|
+
limit: options.limit,
|
|
66
|
+
filter: options.filter,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const headers = {
|
|
70
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(`${apiUrl}/v1/snapshot`, {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers,
|
|
77
|
+
body: JSON.stringify(payload),
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
const errorText = await response.text();
|
|
81
|
+
throw new Error(`API request failed: ${response.status} ${errorText}`);
|
|
82
|
+
}
|
|
83
|
+
const apiResult = await response.json();
|
|
84
|
+
// Merge API result with local data (screenshot, etc.)
|
|
85
|
+
const snapshotData = {
|
|
86
|
+
status: apiResult.status || 'success',
|
|
87
|
+
timestamp: apiResult.timestamp,
|
|
88
|
+
url: apiResult.url || rawResult.url || '',
|
|
89
|
+
viewport: apiResult.viewport || rawResult.viewport,
|
|
90
|
+
elements: apiResult.elements || [],
|
|
91
|
+
screenshot: rawResult.screenshot, // Keep local screenshot
|
|
92
|
+
screenshot_format: rawResult.screenshot_format,
|
|
93
|
+
error: apiResult.error,
|
|
94
|
+
};
|
|
95
|
+
return snapshotData;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
throw new Error(`API request failed: ${e.message}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions - matches spec/sdk-types.md
|
|
3
|
+
*/
|
|
4
|
+
export interface BBox {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
export interface Viewport {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
}
|
|
14
|
+
export interface VisualCues {
|
|
15
|
+
is_primary: boolean;
|
|
16
|
+
background_color_name: string | null;
|
|
17
|
+
is_clickable: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface Element {
|
|
20
|
+
id: number;
|
|
21
|
+
role: string;
|
|
22
|
+
text: string | null;
|
|
23
|
+
importance: number;
|
|
24
|
+
bbox: BBox;
|
|
25
|
+
visual_cues: VisualCues;
|
|
26
|
+
in_viewport: boolean;
|
|
27
|
+
is_occluded: boolean;
|
|
28
|
+
z_index: number;
|
|
29
|
+
}
|
|
30
|
+
export interface Snapshot {
|
|
31
|
+
status: "success" | "error";
|
|
32
|
+
timestamp?: string;
|
|
33
|
+
url: string;
|
|
34
|
+
viewport?: Viewport;
|
|
35
|
+
elements: Element[];
|
|
36
|
+
screenshot?: string;
|
|
37
|
+
screenshot_format?: "png" | "jpeg";
|
|
38
|
+
error?: string;
|
|
39
|
+
requires_license?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface ActionResult {
|
|
42
|
+
success: boolean;
|
|
43
|
+
duration_ms: number;
|
|
44
|
+
outcome?: "navigated" | "dom_updated" | "no_change" | "error";
|
|
45
|
+
url_changed?: boolean;
|
|
46
|
+
snapshot_after?: Snapshot;
|
|
47
|
+
error?: {
|
|
48
|
+
code: string;
|
|
49
|
+
reason: string;
|
|
50
|
+
recovery_hint?: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export interface WaitResult {
|
|
54
|
+
found: boolean;
|
|
55
|
+
element?: Element;
|
|
56
|
+
duration_ms: number;
|
|
57
|
+
timeout: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface QuerySelectorObject {
|
|
60
|
+
role?: string;
|
|
61
|
+
text?: string;
|
|
62
|
+
name?: string;
|
|
63
|
+
clickable?: boolean;
|
|
64
|
+
isPrimary?: boolean;
|
|
65
|
+
importance?: number | {
|
|
66
|
+
min?: number;
|
|
67
|
+
max?: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export type QuerySelector = string | QuerySelectorObject;
|
|
71
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,mBAAmB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
package/dist/wait.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait functionality
|
|
3
|
+
*/
|
|
4
|
+
import { SentienceBrowser } from './browser';
|
|
5
|
+
import { WaitResult, QuerySelector } from './types';
|
|
6
|
+
export declare function waitFor(browser: SentienceBrowser, selector: QuerySelector, timeout?: number, interval?: number): Promise<WaitResult>;
|
|
7
|
+
//# sourceMappingURL=wait.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAW,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7D,wBAAsB,OAAO,CAC3B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,MAAc,EACvB,QAAQ,GAAE,MAAY,GACrB,OAAO,CAAC,UAAU,CAAC,CAgCrB"}
|
package/dist/wait.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Wait functionality
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.waitFor = waitFor;
|
|
7
|
+
const snapshot_1 = require("./snapshot");
|
|
8
|
+
const query_1 = require("./query");
|
|
9
|
+
async function waitFor(browser, selector, timeout = 10000, interval = 250) {
|
|
10
|
+
const startTime = Date.now();
|
|
11
|
+
while (Date.now() - startTime < timeout) {
|
|
12
|
+
// Take snapshot
|
|
13
|
+
const snap = await (0, snapshot_1.snapshot)(browser);
|
|
14
|
+
// Try to find element
|
|
15
|
+
const element = (0, query_1.find)(snap, selector);
|
|
16
|
+
if (element) {
|
|
17
|
+
const durationMs = Date.now() - startTime;
|
|
18
|
+
return {
|
|
19
|
+
found: true,
|
|
20
|
+
element,
|
|
21
|
+
duration_ms: durationMs,
|
|
22
|
+
timeout: false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// Wait before next poll
|
|
26
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
27
|
+
}
|
|
28
|
+
// Timeout
|
|
29
|
+
const durationMs = Date.now() - startTime;
|
|
30
|
+
return {
|
|
31
|
+
found: false,
|
|
32
|
+
element: undefined,
|
|
33
|
+
duration_ms: durationMs,
|
|
34
|
+
timeout: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=wait.js.map
|
package/dist/wait.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAOH,0BAqCC;AAxCD,yCAAsC;AACtC,mCAA+B;AAExB,KAAK,UAAU,OAAO,CAC3B,OAAyB,EACzB,QAAuB,EACvB,UAAkB,KAAK,EACvB,WAAmB,GAAG;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC;QACxC,gBAAgB;QAChB,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EAAC,OAAO,CAAC,CAAC;QAErC,sBAAsB;QACtB,MAAM,OAAO,GAAG,IAAA,YAAI,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAErC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,OAAO;gBACL,KAAK,EAAE,IAAI;gBACX,OAAO;gBACP,WAAW,EAAE,UAAU;gBACvB,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,UAAU;IACV,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAC1C,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|