Skip to content

Commit a421585

Browse files
committed
Added getDomSnapshot feature
1 parent 9f01e22 commit a421585

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

agent-server/nodejs/src/api-server.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ class APIServer {
155155
result = await this.executeJavaScript(JSON.parse(body));
156156
break;
157157

158+
case '/page/dom-snapshot':
159+
if (method !== 'POST') {
160+
this.sendError(res, 405, 'Method not allowed');
161+
return;
162+
}
163+
result = await this.getDOMSnapshot(JSON.parse(body));
164+
break;
165+
158166
default:
159167
this.sendError(res, 404, 'Not found');
160168
return;
@@ -324,6 +332,49 @@ class APIServer {
324332
return response;
325333
}
326334

335+
async getDOMSnapshot(payload) {
336+
const {
337+
clientId,
338+
tabId,
339+
computedStyles = [],
340+
includeDOMRects = true,
341+
includePaintOrder = false
342+
} = payload;
343+
344+
if (!clientId) {
345+
throw new Error('Client ID is required');
346+
}
347+
348+
if (!tabId) {
349+
throw new Error('Tab ID is required');
350+
}
351+
352+
const baseClientId = clientId.split(':')[0];
353+
354+
logger.info('Capturing DOM snapshot', {
355+
baseClientId,
356+
tabId,
357+
computedStyleCount: computedStyles.length,
358+
includeDOMRects,
359+
includePaintOrder
360+
});
361+
362+
// Call the captureDOMSnapshot method from BrowserAgentServer
363+
const result = await this.browserAgentServer.captureDOMSnapshot(tabId, {
364+
computedStyles,
365+
includeDOMRects,
366+
includePaintOrder
367+
});
368+
369+
return {
370+
clientId: baseClientId,
371+
tabId: result.tabId,
372+
snapshot: result.snapshot, // Contains { documents, strings }
373+
format: 'dom-snapshot',
374+
timestamp: Date.now()
375+
};
376+
}
377+
327378
async getScreenshot(payload) {
328379
const { clientId, tabId, fullPage = false } = payload;
329380

agent-server/nodejs/src/lib/BrowserAgentServer.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,69 @@ export class BrowserAgentServer extends EventEmitter {
13061306
}
13071307
}
13081308

1309+
/**
1310+
* Capture DOM snapshot using CDP DOMSnapshot.captureSnapshot
1311+
* @param {string} tabId - Tab ID (target ID)
1312+
* @param {Object} options - Snapshot options
1313+
* @param {string[]} options.computedStyles - Array of computed style properties to capture (default: [])
1314+
* @param {boolean} options.includeDOMRects - Whether to include bounding boxes (default: true)
1315+
* @param {boolean} options.includePaintOrder - Whether to include paint order (default: false)
1316+
* @returns {Promise<Object>} Result with DOM snapshot data
1317+
*/
1318+
async captureDOMSnapshot(tabId, options = {}) {
1319+
const {
1320+
computedStyles = [],
1321+
includeDOMRects = true,
1322+
includePaintOrder = false
1323+
} = options;
1324+
1325+
try {
1326+
logger.info('Capturing DOM snapshot via CDP', {
1327+
tabId,
1328+
computedStyleCount: computedStyles.length,
1329+
includeDOMRects,
1330+
includePaintOrder
1331+
});
1332+
1333+
// Use DOMSnapshot.captureSnapshot CDP command
1334+
const result = await this.sendCDPCommandToTarget(tabId, 'DOMSnapshot.captureSnapshot', {
1335+
computedStyles,
1336+
includeDOMRects,
1337+
includePaintOrder
1338+
});
1339+
1340+
// Validate response structure
1341+
if (!result.documents || !result.strings) {
1342+
throw new Error('Invalid DOMSnapshot response: missing documents or strings array');
1343+
}
1344+
1345+
logger.info('DOM snapshot captured successfully', {
1346+
tabId,
1347+
documentCount: result.documents.length,
1348+
stringCount: result.strings.length,
1349+
totalNodes: result.documents.reduce((sum, doc) => sum + (doc.nodes?.nodeType?.length || 0), 0)
1350+
});
1351+
1352+
return {
1353+
tabId,
1354+
snapshot: result // Contains documents[] and strings[]
1355+
};
1356+
} catch (error) {
1357+
logger.error('Failed to capture DOM snapshot via CDP', {
1358+
tabId,
1359+
error: error.message,
1360+
stack: error.stack
1361+
});
1362+
1363+
// Check if DOMSnapshot domain is available
1364+
if (error.message && error.message.includes('was not found')) {
1365+
throw new Error('DOMSnapshot domain not available. Requires Chrome 74+ with CDP enabled.');
1366+
}
1367+
1368+
throw error;
1369+
}
1370+
}
1371+
13091372
/**
13101373
* Capture page screenshot using CDP
13111374
* @param {string} tabId - Tab ID (target ID)

0 commit comments

Comments
 (0)