chrometools-mcp 3.3.6 → 3.3.9
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/CHANGELOG.md +87 -0
- package/README.md +129 -24
- package/SPEC-pom-integration.md +227 -0
- package/SPEC-swagger-api-tools.md +3101 -0
- package/browser/page-manager.js +83 -0
- package/index.js +623 -201
- package/package.json +2 -1
- package/pom/apom-tree-converter.js +287 -51
- package/recorder/page-object-generator.js +45 -1
- package/server/tool-definitions.js +57 -6
- package/server/tool-schemas.js +31 -0
- package/test-swagger-phase1.mjs +959 -0
- package/utils/api-generators/api-models-python.js +448 -0
- package/utils/api-generators/api-models-typescript.js +375 -0
- package/utils/code-generators/code-generator-base.js +111 -6
- package/utils/code-generators/playwright-python.js +74 -0
- package/utils/code-generators/playwright-typescript.js +69 -0
- package/utils/code-generators/pom-integrator.js +373 -0
- package/utils/code-generators/selenium-java.js +72 -0
- package/utils/code-generators/selenium-python.js +75 -0
- package/utils/hints-generator.js +114 -19
- package/utils/openapi/helpers.js +25 -0
- package/utils/openapi/parser.js +448 -0
- package/utils/openapi/ref-resolver.js +149 -0
- package/utils/openapi/type-mapper.js +174 -0
- package/nul +0 -0
package/browser/page-manager.js
CHANGED
|
@@ -7,6 +7,59 @@
|
|
|
7
7
|
import { getBrowser } from './browser-manager.js';
|
|
8
8
|
// Note: injectRecorder removed - now using Chrome Extension for recording
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Click listener tracking script - injected via evaluateOnNewDocument
|
|
12
|
+
* Monkey-patches addEventListener to track which elements have click listeners
|
|
13
|
+
* This enables detection of click handlers added by frameworks like Angular
|
|
14
|
+
*/
|
|
15
|
+
const CLICK_LISTENER_TRACKER_SCRIPT = `
|
|
16
|
+
(function() {
|
|
17
|
+
// Only inject once
|
|
18
|
+
if (window.__clickListenerTracker) return;
|
|
19
|
+
window.__clickListenerTracker = true;
|
|
20
|
+
|
|
21
|
+
// WeakMap to track elements with click listeners (prevents memory leaks)
|
|
22
|
+
const clickListeners = new WeakMap();
|
|
23
|
+
|
|
24
|
+
// Store original methods
|
|
25
|
+
const originalAddEventListener = EventTarget.prototype.addEventListener;
|
|
26
|
+
const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
|
|
27
|
+
|
|
28
|
+
// Patch addEventListener
|
|
29
|
+
EventTarget.prototype.addEventListener = function(type, listener, options) {
|
|
30
|
+
if (type === 'click' && this instanceof Element) {
|
|
31
|
+
// Track this element has click listener
|
|
32
|
+
const count = clickListeners.get(this) || 0;
|
|
33
|
+
clickListeners.set(this, count + 1);
|
|
34
|
+
}
|
|
35
|
+
return originalAddEventListener.call(this, type, listener, options);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Patch removeEventListener for accuracy
|
|
39
|
+
EventTarget.prototype.removeEventListener = function(type, listener, options) {
|
|
40
|
+
if (type === 'click' && this instanceof Element) {
|
|
41
|
+
const count = clickListeners.get(this) || 0;
|
|
42
|
+
if (count > 0) {
|
|
43
|
+
clickListeners.set(this, count - 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return originalRemoveEventListener.call(this, type, listener, options);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Global function to check if element has click listener
|
|
50
|
+
window.__hasClickListener = function(element) {
|
|
51
|
+
if (!element) return false;
|
|
52
|
+
const count = clickListeners.get(element);
|
|
53
|
+
return count && count > 0;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Also expose for debugging
|
|
57
|
+
window.__getClickListenerCount = function(element) {
|
|
58
|
+
return clickListeners.get(element) || 0;
|
|
59
|
+
};
|
|
60
|
+
})();
|
|
61
|
+
`;
|
|
62
|
+
|
|
10
63
|
/**
|
|
11
64
|
* Debug log helper (only logs to stderr when DEBUG=1)
|
|
12
65
|
* @param {...any} args - Arguments to log
|
|
@@ -159,6 +212,20 @@ export async function setupNetworkMonitoring(page) {
|
|
|
159
212
|
|
|
160
213
|
// Note: setupRecorderAutoReinjection removed - Chrome Extension handles recording now
|
|
161
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Inject click listener tracker into page
|
|
217
|
+
* Must be called BEFORE page.goto() to catch all listeners
|
|
218
|
+
* @param {Page} page - Puppeteer page instance
|
|
219
|
+
*/
|
|
220
|
+
async function injectClickListenerTracker(page) {
|
|
221
|
+
try {
|
|
222
|
+
await page.evaluateOnNewDocument(CLICK_LISTENER_TRACKER_SCRIPT);
|
|
223
|
+
debugLog('Click listener tracker injected');
|
|
224
|
+
} catch (error) {
|
|
225
|
+
debugLog('Failed to inject click listener tracker:', error.message);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
162
229
|
/**
|
|
163
230
|
* Get or create page for URL
|
|
164
231
|
* @param {string} url - URL to navigate to
|
|
@@ -180,6 +247,9 @@ export async function getOrCreatePage(url) {
|
|
|
180
247
|
// Create new page
|
|
181
248
|
const page = await browser.newPage();
|
|
182
249
|
|
|
250
|
+
// Inject click listener tracker BEFORE navigation
|
|
251
|
+
await injectClickListenerTracker(page);
|
|
252
|
+
|
|
183
253
|
// Set up console log capture
|
|
184
254
|
const client = await page.target().createCDPSession();
|
|
185
255
|
await client.send('Runtime.enable');
|
|
@@ -277,6 +347,19 @@ export function setLastPage(page) {
|
|
|
277
347
|
* @returns {Promise<void>}
|
|
278
348
|
*/
|
|
279
349
|
export async function setupNewPage(page, source = 'manual') {
|
|
350
|
+
// Inject click listener tracker
|
|
351
|
+
// For new tabs, we need both:
|
|
352
|
+
// 1. evaluateOnNewDocument for future navigations
|
|
353
|
+
// 2. evaluate for already-loaded content (won't catch existing listeners, but will catch new ones)
|
|
354
|
+
try {
|
|
355
|
+
await page.evaluateOnNewDocument(CLICK_LISTENER_TRACKER_SCRIPT);
|
|
356
|
+
// Also inject immediately for current page (in case content already loaded)
|
|
357
|
+
await page.evaluate(CLICK_LISTENER_TRACKER_SCRIPT);
|
|
358
|
+
debugLog(`Click listener tracker injected for ${source} page`);
|
|
359
|
+
} catch (error) {
|
|
360
|
+
debugLog('Failed to inject click listener tracker:', error.message);
|
|
361
|
+
}
|
|
362
|
+
|
|
280
363
|
// Set up console log capture
|
|
281
364
|
try {
|
|
282
365
|
const client = await page.target().createCDPSession();
|