@testivai/witness-cdp 1.0.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/LICENSE +21 -0
- package/README.md +405 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +24 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/bin/testivai.d.ts +3 -0
- package/dist/bin/testivai.d.ts.map +1 -0
- package/dist/bin/testivai.js +48 -0
- package/dist/bin/testivai.js.map +1 -0
- package/dist/cdp/binding.d.ts +56 -0
- package/dist/cdp/binding.d.ts.map +1 -0
- package/dist/cdp/binding.js +364 -0
- package/dist/cdp/binding.js.map +1 -0
- package/dist/cdp/capture.d.ts +61 -0
- package/dist/cdp/capture.d.ts.map +1 -0
- package/dist/cdp/capture.js +422 -0
- package/dist/cdp/capture.js.map +1 -0
- package/dist/cdp/client.d.ts +63 -0
- package/dist/cdp/client.d.ts.map +1 -0
- package/dist/cdp/client.js +279 -0
- package/dist/cdp/client.js.map +1 -0
- package/dist/cdp/discovery.d.ts +33 -0
- package/dist/cdp/discovery.d.ts.map +1 -0
- package/dist/cdp/discovery.js +157 -0
- package/dist/cdp/discovery.js.map +1 -0
- package/dist/ci.d.ts +31 -0
- package/dist/ci.d.ts.map +1 -0
- package/dist/ci.js +118 -0
- package/dist/ci.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +122 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/capture.d.ts +3 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +143 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +255 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +438 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +329 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-naming.d.ts +31 -0
- package/dist/utils/file-naming.d.ts.map +1 -0
- package/dist/utils/file-naming.js +137 -0
- package/dist/utils/file-naming.js.map +1 -0
- package/dist/utils/framework-detect.d.ts +31 -0
- package/dist/utils/framework-detect.d.ts.map +1 -0
- package/dist/utils/framework-detect.js +379 -0
- package/dist/utils/framework-detect.js.map +1 -0
- package/dist/utils/logger.d.ts +29 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +114 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/process.d.ts +61 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +208 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/utils/template-generator.d.ts +36 -0
- package/dist/utils/template-generator.d.ts.map +1 -0
- package/dist/utils/template-generator.js +255 -0
- package/dist/utils/template-generator.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CdpBinding = void 0;
|
|
4
|
+
const capture_1 = require("./capture");
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
/**
|
|
7
|
+
* Client-side script injected into the browser
|
|
8
|
+
* This creates a simple function that triggers CDP capture
|
|
9
|
+
*/
|
|
10
|
+
const CLIENT_SCRIPT = `
|
|
11
|
+
(function() {
|
|
12
|
+
// Create the witness function
|
|
13
|
+
window.testivaiWitness = function(name) {
|
|
14
|
+
// Store the snapshot name for the CDP client to pick up
|
|
15
|
+
window.__testivaiSnapshotName = name;
|
|
16
|
+
// Signal that we want to capture
|
|
17
|
+
window.__testivaiCaptureRequested = Date.now();
|
|
18
|
+
// Return a promise that will be resolved by the ACK
|
|
19
|
+
return new Promise(function(resolve) {
|
|
20
|
+
window.__testivaiResolve = resolve;
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
`;
|
|
25
|
+
/**
|
|
26
|
+
* ACK script to resolve the Promise
|
|
27
|
+
*/
|
|
28
|
+
const ACK_SCRIPT = `
|
|
29
|
+
(function() {
|
|
30
|
+
if (window.__testivaiResolve) {
|
|
31
|
+
window.__testivaiResolve();
|
|
32
|
+
window.__testivaiResolve = null;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* CDP Binding management
|
|
38
|
+
*/
|
|
39
|
+
class CdpBinding {
|
|
40
|
+
constructor(client, options = {}) {
|
|
41
|
+
this.client = client;
|
|
42
|
+
this.snapshots = [];
|
|
43
|
+
this.isBindingRegistered = false;
|
|
44
|
+
// Create a logger with debug options
|
|
45
|
+
this.logger = (0, logger_1.createLogger)({ debug: options.debug || false });
|
|
46
|
+
this.capture = new capture_1.CdpCapture(client, { debug: options.debug });
|
|
47
|
+
this.setupEventListeners();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Set up the Runtime bindings
|
|
51
|
+
*/
|
|
52
|
+
async setupBindings() {
|
|
53
|
+
try {
|
|
54
|
+
// Enable Runtime domain
|
|
55
|
+
await this.client.enableDomain('Runtime');
|
|
56
|
+
await this.client.send('Runtime.enable');
|
|
57
|
+
// Inject the client-side script
|
|
58
|
+
await this.injectClientScript();
|
|
59
|
+
this.isBindingRegistered = true;
|
|
60
|
+
logger_1.logger.success('CDP bindings registered successfully');
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
logger_1.logger.error('Failed to setup CDP bindings:', error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Inject the client-side script into all pages
|
|
69
|
+
*/
|
|
70
|
+
async injectClientScript() {
|
|
71
|
+
try {
|
|
72
|
+
// Enable Page domain
|
|
73
|
+
await this.client.enableDomain('Page');
|
|
74
|
+
// Add script to evaluate on new documents
|
|
75
|
+
await this.client.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
76
|
+
source: CLIENT_SCRIPT,
|
|
77
|
+
});
|
|
78
|
+
// Try to evaluate on the current context
|
|
79
|
+
try {
|
|
80
|
+
await this.client.send('Runtime.evaluate', {
|
|
81
|
+
expression: CLIENT_SCRIPT,
|
|
82
|
+
});
|
|
83
|
+
logger_1.logger.debug('Client script evaluated in current context');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_1.logger.debug('Failed to evaluate script in current context (page may not be loaded yet):', error);
|
|
87
|
+
}
|
|
88
|
+
logger_1.logger.debug('Client script injected');
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger_1.logger.error('Failed to inject client script:', error);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Set up polling for capture requests
|
|
97
|
+
*/
|
|
98
|
+
setupEventListeners() {
|
|
99
|
+
let isConnected = true;
|
|
100
|
+
// Poll for capture requests
|
|
101
|
+
const pollInterval = setInterval(async () => {
|
|
102
|
+
if (!isConnected) {
|
|
103
|
+
clearInterval(pollInterval);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const result = await this.client.send('Runtime.evaluate', {
|
|
108
|
+
expression: 'window.__testivaiCaptureRequested',
|
|
109
|
+
});
|
|
110
|
+
if (result.result.value) {
|
|
111
|
+
// Get the snapshot name
|
|
112
|
+
const nameResult = await this.client.send('Runtime.evaluate', {
|
|
113
|
+
expression: 'window.__testivaiSnapshotName',
|
|
114
|
+
});
|
|
115
|
+
const snapshotName = nameResult.result.value || 'snapshot';
|
|
116
|
+
this.logger.debug('Capture requested for:', snapshotName);
|
|
117
|
+
// Clear the request flag
|
|
118
|
+
await this.client.send('Runtime.evaluate', {
|
|
119
|
+
expression: 'window.__testivaiCaptureRequested = null; window.__testivaiSnapshotName = null;',
|
|
120
|
+
});
|
|
121
|
+
// Handle the capture
|
|
122
|
+
await this.handleWitnessCall(snapshotName);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (error.message && error.message.includes('WebSocket is not open')) {
|
|
127
|
+
logger_1.logger.debug('WebSocket closed, stopping polling');
|
|
128
|
+
isConnected = false;
|
|
129
|
+
clearInterval(pollInterval);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
logger_1.logger.debug('Error polling for capture requests:', error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}, 100);
|
|
136
|
+
// Store interval for cleanup
|
|
137
|
+
this.pollInterval = pollInterval;
|
|
138
|
+
// Listen for disconnect event
|
|
139
|
+
this.client.on('disconnect', () => {
|
|
140
|
+
logger_1.logger.debug('CDP disconnected, stopping polling');
|
|
141
|
+
isConnected = false;
|
|
142
|
+
clearInterval(pollInterval);
|
|
143
|
+
});
|
|
144
|
+
// Listen for frame navigation to re-inject script
|
|
145
|
+
this.client.on('frameNavigated', async () => {
|
|
146
|
+
if (this.isBindingRegistered && isConnected) {
|
|
147
|
+
logger_1.logger.debug('Frame navigated, re-injecting client script');
|
|
148
|
+
await this.injectClientScript();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Handle a witness binding call
|
|
154
|
+
*/
|
|
155
|
+
async handleWitnessCall(snapshotName) {
|
|
156
|
+
try {
|
|
157
|
+
const name = snapshotName || 'snapshot';
|
|
158
|
+
this.logger.debug(`Capturing snapshot: ${name}`);
|
|
159
|
+
// Enable Page domain if not already enabled
|
|
160
|
+
await this.client.enableDomain('Page');
|
|
161
|
+
// Get current URL
|
|
162
|
+
const urlResult = await this.client.send('Runtime.evaluate', {
|
|
163
|
+
expression: 'window.location.href',
|
|
164
|
+
});
|
|
165
|
+
const currentUrl = urlResult.result.value || 'about:blank';
|
|
166
|
+
// Get viewport size
|
|
167
|
+
const viewportResult = await this.client.send('Runtime.evaluate', {
|
|
168
|
+
expression: '{width: window.innerWidth, height: window.innerHeight}',
|
|
169
|
+
});
|
|
170
|
+
const viewport = viewportResult.result.value || { width: 1920, height: 1080 };
|
|
171
|
+
// Capture page structure (HTML)
|
|
172
|
+
// @renamed: dom → structure (IP protection)
|
|
173
|
+
const structureResult = await this.client.send('Runtime.evaluate', {
|
|
174
|
+
expression: 'document.documentElement.outerHTML',
|
|
175
|
+
});
|
|
176
|
+
const structureHtml = structureResult.result.value || '';
|
|
177
|
+
// Capture computed styles
|
|
178
|
+
// @renamed: css → styles (IP protection)
|
|
179
|
+
const styles = await this.capture.captureComputedStyles().catch(err => {
|
|
180
|
+
logger_1.logger.warn('Failed to capture styles:', err);
|
|
181
|
+
return { computed_styles: {} };
|
|
182
|
+
});
|
|
183
|
+
// Capture performance metrics
|
|
184
|
+
const performanceMetrics = await this.capturePerformanceMetrics();
|
|
185
|
+
// Capture screenshot using Page.captureScreenshot
|
|
186
|
+
const screenshotResult = await this.client.send('Page.captureScreenshot', {
|
|
187
|
+
format: 'png',
|
|
188
|
+
captureBeyondViewport: true,
|
|
189
|
+
});
|
|
190
|
+
// Create snapshot object
|
|
191
|
+
// @renamed: dom → structure, css → styles (IP protection)
|
|
192
|
+
const snapshot = {
|
|
193
|
+
name,
|
|
194
|
+
screenshot: screenshotResult.data,
|
|
195
|
+
structure: structureHtml,
|
|
196
|
+
styles,
|
|
197
|
+
performanceMetrics,
|
|
198
|
+
timestamp: new Date().toISOString(),
|
|
199
|
+
url: currentUrl,
|
|
200
|
+
viewport,
|
|
201
|
+
};
|
|
202
|
+
// Add to snapshots array
|
|
203
|
+
this.snapshots.push(snapshot);
|
|
204
|
+
this.logger.debug(`Captured snapshot: ${name}`);
|
|
205
|
+
// Send ACK to resolve the Promise
|
|
206
|
+
await this.sendAck();
|
|
207
|
+
this.logger.debug(`Captured and ACK'd: ${name}`);
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.logger.error(`Failed to handle witness call for ${snapshotName}:`, error);
|
|
211
|
+
// Still send ACK to avoid hanging the test
|
|
212
|
+
await this.sendAck();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Capture performance metrics using CDP Performance API
|
|
217
|
+
*/
|
|
218
|
+
async capturePerformanceMetrics() {
|
|
219
|
+
try {
|
|
220
|
+
// Enable Performance domain
|
|
221
|
+
await this.client.send('Performance.enable');
|
|
222
|
+
// Get CDP performance metrics
|
|
223
|
+
const cdpMetrics = await this.client.send('Performance.getMetrics');
|
|
224
|
+
// Convert metrics array to object
|
|
225
|
+
const cdpMetricsObj = {};
|
|
226
|
+
cdpMetrics.metrics.forEach((metric) => {
|
|
227
|
+
cdpMetricsObj[metric.name] = metric.value;
|
|
228
|
+
});
|
|
229
|
+
// Get navigation timing and Web Vitals via Runtime.evaluate
|
|
230
|
+
const timingResult = await this.client.send('Runtime.evaluate', {
|
|
231
|
+
expression: `
|
|
232
|
+
(function() {
|
|
233
|
+
const timing = window.performance.timing;
|
|
234
|
+
const navigation = window.performance.navigation;
|
|
235
|
+
|
|
236
|
+
// Get paint entries
|
|
237
|
+
const paintEntries = window.performance.getEntriesByType('paint');
|
|
238
|
+
const fcp = paintEntries.find(e => e.name === 'first-contentful-paint')?.startTime;
|
|
239
|
+
|
|
240
|
+
// Get LCP
|
|
241
|
+
const lcpEntries = window.performance.getEntriesByType('largest-contentful-paint');
|
|
242
|
+
const lcp = lcpEntries[lcpEntries.length - 1]?.startTime;
|
|
243
|
+
|
|
244
|
+
// Get CLS
|
|
245
|
+
let cls = 0;
|
|
246
|
+
try {
|
|
247
|
+
const clsEntries = window.performance.getEntriesByType('layout-shift');
|
|
248
|
+
clsEntries.forEach((entry: any) => {
|
|
249
|
+
if (!entry.hadRecentInput) {
|
|
250
|
+
cls += entry.value;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
} catch (e) {
|
|
254
|
+
// CLS might not be available
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Get FID (requires PerformanceObserver)
|
|
258
|
+
let fid = null;
|
|
259
|
+
try {
|
|
260
|
+
const fidEntries = window.performance.getEntriesByType('first-input');
|
|
261
|
+
if (fidEntries.length > 0) {
|
|
262
|
+
fid = fidEntries[0].processingStart - fidEntries[0].startTime;
|
|
263
|
+
}
|
|
264
|
+
} catch (e) {
|
|
265
|
+
// FID might not be available
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return {
|
|
269
|
+
navigation: {
|
|
270
|
+
type: navigation.type,
|
|
271
|
+
redirectCount: navigation.redirectCount
|
|
272
|
+
},
|
|
273
|
+
timing: {
|
|
274
|
+
navigationStart: timing.navigationStart,
|
|
275
|
+
unloadEventStart: timing.unloadEventStart,
|
|
276
|
+
unloadEventEnd: timing.unloadEventEnd,
|
|
277
|
+
redirectStart: timing.redirectStart,
|
|
278
|
+
redirectEnd: timing.redirectEnd,
|
|
279
|
+
fetchStart: timing.fetchStart,
|
|
280
|
+
domainLookupStart: timing.domainLookupStart,
|
|
281
|
+
domainLookupEnd: timing.domainLookupEnd,
|
|
282
|
+
connectStart: timing.connectStart,
|
|
283
|
+
connectEnd: timing.connectEnd,
|
|
284
|
+
secureConnectionStart: timing.secureConnectionStart,
|
|
285
|
+
requestStart: timing.requestStart,
|
|
286
|
+
responseStart: timing.responseStart,
|
|
287
|
+
responseEnd: timing.responseEnd,
|
|
288
|
+
domLoading: timing.domLoading,
|
|
289
|
+
domInteractive: timing.domInteractive,
|
|
290
|
+
domContentLoadedEventStart: timing.domContentLoadedEventStart,
|
|
291
|
+
domContentLoadedEventEnd: timing.domContentLoadedEventEnd,
|
|
292
|
+
domComplete: timing.domComplete,
|
|
293
|
+
loadEventStart: timing.loadEventStart,
|
|
294
|
+
loadEventEnd: timing.loadEventEnd
|
|
295
|
+
},
|
|
296
|
+
webVitals: {
|
|
297
|
+
firstContentfulPaint: fcp,
|
|
298
|
+
largestContentfulPaint: lcp,
|
|
299
|
+
cumulativeLayoutShift: cls,
|
|
300
|
+
firstInputDelay: fid
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
})()
|
|
304
|
+
`
|
|
305
|
+
});
|
|
306
|
+
const timingData = timingResult.result.value;
|
|
307
|
+
// Disable Performance domain
|
|
308
|
+
await this.client.send('Performance.disable');
|
|
309
|
+
return {
|
|
310
|
+
cdp: cdpMetricsObj,
|
|
311
|
+
timing: timingData,
|
|
312
|
+
timestamp: Date.now()
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
logger_1.logger.warn('Failed to capture performance metrics:', error);
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Send ACK to resolve the Promise
|
|
322
|
+
*/
|
|
323
|
+
async sendAck() {
|
|
324
|
+
try {
|
|
325
|
+
await this.client.send('Runtime.evaluate', {
|
|
326
|
+
expression: ACK_SCRIPT,
|
|
327
|
+
});
|
|
328
|
+
logger_1.logger.debug('Sent ACK');
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
logger_1.logger.error('Failed to send ACK:', error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get all captured snapshots
|
|
336
|
+
*/
|
|
337
|
+
getSnapshots() {
|
|
338
|
+
return this.snapshots;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Clear all captured snapshots
|
|
342
|
+
*/
|
|
343
|
+
clearSnapshots() {
|
|
344
|
+
this.snapshots = [];
|
|
345
|
+
logger_1.logger.debug('Cleared snapshots');
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Check if bindings are registered
|
|
349
|
+
*/
|
|
350
|
+
isRegistered() {
|
|
351
|
+
return this.isBindingRegistered;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Clean up resources
|
|
355
|
+
*/
|
|
356
|
+
cleanup() {
|
|
357
|
+
if (this.pollInterval) {
|
|
358
|
+
clearInterval(this.pollInterval);
|
|
359
|
+
this.pollInterval = undefined;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
exports.CdpBinding = CdpBinding;
|
|
364
|
+
//# sourceMappingURL=binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/cdp/binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CdpClient } from './client';
|
|
2
|
+
import { SnapshotPayload } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* CDP Capture functionality
|
|
5
|
+
*/
|
|
6
|
+
export declare class CdpCapture {
|
|
7
|
+
private client;
|
|
8
|
+
private logger;
|
|
9
|
+
constructor(client: CdpClient, options?: {
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Capture a complete snapshot (screenshot + structure + styles + layout)
|
|
14
|
+
*/
|
|
15
|
+
captureSnapshot(snapshotName: string, testName?: string): Promise<SnapshotPayload>;
|
|
16
|
+
/**
|
|
17
|
+
* Capture screenshot as base64
|
|
18
|
+
*/
|
|
19
|
+
private captureScreenshot;
|
|
20
|
+
/**
|
|
21
|
+
* Capture page structure (HTML content)
|
|
22
|
+
* @renamed Was `captureDom` — renamed to conceal internal layer terminology (IP protection)
|
|
23
|
+
*/
|
|
24
|
+
private captureStructure;
|
|
25
|
+
/**
|
|
26
|
+
* Helper to build stable CSS selector path for a node
|
|
27
|
+
* Uses nth-of-type to ensure uniqueness for elements with same tag/class
|
|
28
|
+
*/
|
|
29
|
+
private buildSelectorPath;
|
|
30
|
+
/**
|
|
31
|
+
* Get the nth-of-type index for a node among its siblings
|
|
32
|
+
*/
|
|
33
|
+
private getSiblingIndex;
|
|
34
|
+
/**
|
|
35
|
+
* Capture computed CSS styles
|
|
36
|
+
*/
|
|
37
|
+
captureComputedStyles(): Promise<{
|
|
38
|
+
computed_styles: Record<string, Record<string, string>>;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Capture layout information
|
|
42
|
+
*/
|
|
43
|
+
private captureLayout;
|
|
44
|
+
/**
|
|
45
|
+
* Capture performance timings
|
|
46
|
+
*/
|
|
47
|
+
private capturePerformanceTimings;
|
|
48
|
+
/**
|
|
49
|
+
* Get current page URL
|
|
50
|
+
*/
|
|
51
|
+
private getCurrentUrl;
|
|
52
|
+
/**
|
|
53
|
+
* Get viewport dimensions
|
|
54
|
+
*/
|
|
55
|
+
private getViewport;
|
|
56
|
+
/**
|
|
57
|
+
* Capture Lighthouse audit (if available)
|
|
58
|
+
*/
|
|
59
|
+
captureLighthouse(): Promise<any | undefined>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/cdp/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,eAAe,EAAoC,MAAM,UAAU,CAAC;AAG7E;;GAEG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,MAAM,CAAM;gBAEA,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;IAKxE;;OAEG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAuDxF;;OAEG;YACW,iBAAiB;IAmB/B;;;OAGG;YACW,gBAAgB;IA2B9B;;;OAGG;YACW,iBAAiB;IA6E/B;;OAEG;YACW,eAAe;IAmB7B;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,CAAC;IAyFnG;;OAEG;YACW,aAAa;IAkC3B;;OAEG;YACW,yBAAyB;IAyDvC;;OAEG;YACW,aAAa;IAc3B;;OAEG;YACW,WAAW;IAqBzB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC;CAMpD"}
|