@tontoko/fast-playwright-mcp 0.0.4
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 +202 -0
- package/README.md +1047 -0
- package/cli.js +18 -0
- package/config.d.ts +124 -0
- package/index.d.ts +25 -0
- package/index.js +18 -0
- package/lib/actions.d.js +0 -0
- package/lib/batch/batch-executor.js +137 -0
- package/lib/browser-context-factory.js +252 -0
- package/lib/browser-server-backend.js +139 -0
- package/lib/config/constants.js +80 -0
- package/lib/config.js +405 -0
- package/lib/context.js +274 -0
- package/lib/diagnostics/common/diagnostic-base.js +63 -0
- package/lib/diagnostics/common/error-enrichment-utils.js +212 -0
- package/lib/diagnostics/common/index.js +56 -0
- package/lib/diagnostics/common/initialization-manager.js +210 -0
- package/lib/diagnostics/common/performance-tracker.js +132 -0
- package/lib/diagnostics/diagnostic-error.js +140 -0
- package/lib/diagnostics/diagnostic-level.js +123 -0
- package/lib/diagnostics/diagnostic-thresholds.js +347 -0
- package/lib/diagnostics/element-discovery.js +441 -0
- package/lib/diagnostics/enhanced-error-handler.js +376 -0
- package/lib/diagnostics/error-enrichment.js +157 -0
- package/lib/diagnostics/frame-reference-manager.js +179 -0
- package/lib/diagnostics/page-analyzer.js +639 -0
- package/lib/diagnostics/parallel-page-analyzer.js +129 -0
- package/lib/diagnostics/resource-manager.js +134 -0
- package/lib/diagnostics/smart-config.js +482 -0
- package/lib/diagnostics/smart-handle.js +118 -0
- package/lib/diagnostics/unified-system.js +717 -0
- package/lib/extension/cdp-relay.js +486 -0
- package/lib/extension/extension-context-factory.js +74 -0
- package/lib/extension/main.js +41 -0
- package/lib/file-utils.js +42 -0
- package/lib/generate-keys.js +75 -0
- package/lib/http-server.js +50 -0
- package/lib/in-process-client.js +64 -0
- package/lib/index.js +48 -0
- package/lib/javascript.js +90 -0
- package/lib/log.js +33 -0
- package/lib/loop/loop-claude.js +247 -0
- package/lib/loop/loop-open-ai.js +222 -0
- package/lib/loop/loop.js +174 -0
- package/lib/loop/main.js +46 -0
- package/lib/loopTools/context.js +76 -0
- package/lib/loopTools/main.js +65 -0
- package/lib/loopTools/perform.js +40 -0
- package/lib/loopTools/snapshot.js +37 -0
- package/lib/loopTools/tool.js +26 -0
- package/lib/manual-promise.js +125 -0
- package/lib/mcp/in-process-transport.js +91 -0
- package/lib/mcp/proxy-backend.js +127 -0
- package/lib/mcp/server.js +123 -0
- package/lib/mcp/transport.js +159 -0
- package/lib/package.js +28 -0
- package/lib/program.js +82 -0
- package/lib/response.js +493 -0
- package/lib/schemas/expectation.js +152 -0
- package/lib/session-log.js +210 -0
- package/lib/tab.js +417 -0
- package/lib/tools/base-tool-handler.js +141 -0
- package/lib/tools/batch-execute.js +150 -0
- package/lib/tools/common.js +65 -0
- package/lib/tools/console.js +60 -0
- package/lib/tools/diagnose/diagnose-analysis-runner.js +101 -0
- package/lib/tools/diagnose/diagnose-config-handler.js +130 -0
- package/lib/tools/diagnose/diagnose-report-builder.js +394 -0
- package/lib/tools/diagnose.js +147 -0
- package/lib/tools/dialogs.js +57 -0
- package/lib/tools/evaluate.js +67 -0
- package/lib/tools/files.js +53 -0
- package/lib/tools/find-elements.js +307 -0
- package/lib/tools/install.js +60 -0
- package/lib/tools/keyboard.js +93 -0
- package/lib/tools/mouse.js +110 -0
- package/lib/tools/navigate.js +82 -0
- package/lib/tools/network.js +50 -0
- package/lib/tools/pdf.js +46 -0
- package/lib/tools/screenshot.js +113 -0
- package/lib/tools/snapshot.js +158 -0
- package/lib/tools/tabs.js +97 -0
- package/lib/tools/tool.js +47 -0
- package/lib/tools/utils.js +131 -0
- package/lib/tools/wait.js +64 -0
- package/lib/tools.js +65 -0
- package/lib/types/batch.js +47 -0
- package/lib/types/diff.js +0 -0
- package/lib/types/performance.js +0 -0
- package/lib/types/threshold-base.js +0 -0
- package/lib/utils/array-utils.js +44 -0
- package/lib/utils/code-deduplication-utils.js +141 -0
- package/lib/utils/common-formatters.js +252 -0
- package/lib/utils/console-filter.js +64 -0
- package/lib/utils/diagnostic-report-utils.js +178 -0
- package/lib/utils/diff-formatter.js +126 -0
- package/lib/utils/disposable-manager.js +135 -0
- package/lib/utils/error-handler-middleware.js +77 -0
- package/lib/utils/image-processor.js +137 -0
- package/lib/utils/index.js +92 -0
- package/lib/utils/report-builder.js +189 -0
- package/lib/utils/request-logger.js +82 -0
- package/lib/utils/response-diff-detector.js +150 -0
- package/lib/utils/section-builder.js +62 -0
- package/lib/utils/tool-patterns.js +153 -0
- package/lib/utils.js +46 -0
- package/package.json +77 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/parallel-page-analyzer.ts
|
|
21
|
+
import { createDisposableManager } from "../utils/disposable-manager.js";
|
|
22
|
+
import { PageAnalyzer } from "./page-analyzer.js";
|
|
23
|
+
|
|
24
|
+
class ParallelPageAnalyzer {
|
|
25
|
+
pageAnalyzer;
|
|
26
|
+
disposableManager = createDisposableManager("ParallelPageAnalyzer");
|
|
27
|
+
constructor(page) {
|
|
28
|
+
this.pageAnalyzer = this.disposableManager.register(new PageAnalyzer(page));
|
|
29
|
+
}
|
|
30
|
+
async runParallelAnalysis() {
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
const errors = [];
|
|
33
|
+
let structureAnalysis;
|
|
34
|
+
let performanceMetrics;
|
|
35
|
+
try {
|
|
36
|
+
const analysisPromises = [
|
|
37
|
+
this.executeAnalysis("structure-analysis", async () => {
|
|
38
|
+
return await this.pageAnalyzer.analyzePageStructure();
|
|
39
|
+
}),
|
|
40
|
+
this.executeAnalysis("performance-metrics", async () => {
|
|
41
|
+
return await this.pageAnalyzer.analyzePerformanceMetrics();
|
|
42
|
+
})
|
|
43
|
+
];
|
|
44
|
+
const results = await Promise.allSettled(analysisPromises);
|
|
45
|
+
const processedResults = this.processAnalysisResults(results, errors);
|
|
46
|
+
structureAnalysis = processedResults.structureAnalysis;
|
|
47
|
+
performanceMetrics = processedResults.performanceMetrics;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const errorMsg = error instanceof Error ? error.message : "Parallel execution failed";
|
|
50
|
+
errors.push({
|
|
51
|
+
step: "parallel-execution",
|
|
52
|
+
error: errorMsg
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const executionTime = Date.now() - startTime;
|
|
56
|
+
const convertedStructureAnalysis = structureAnalysis ? {
|
|
57
|
+
iframes: {
|
|
58
|
+
detected: structureAnalysis.iframes.detected,
|
|
59
|
+
count: structureAnalysis.iframes.count,
|
|
60
|
+
accessible: structureAnalysis.iframes.accessible.map((iframe) => ({
|
|
61
|
+
id: iframe.src || "unknown",
|
|
62
|
+
url: iframe.src || "",
|
|
63
|
+
title: iframe.src || "iframe",
|
|
64
|
+
contentAccessible: iframe.accessible,
|
|
65
|
+
crossOrigin: false
|
|
66
|
+
})),
|
|
67
|
+
inaccessible: structureAnalysis.iframes.inaccessible.map((iframe, index) => ({
|
|
68
|
+
id: iframe.reason || `inaccessible-${index}`,
|
|
69
|
+
reason: iframe.reason || "Unknown reason",
|
|
70
|
+
url: iframe.src,
|
|
71
|
+
title: iframe.src || "inaccessible iframe"
|
|
72
|
+
}))
|
|
73
|
+
},
|
|
74
|
+
modalStates: structureAnalysis.modalStates,
|
|
75
|
+
elements: structureAnalysis.elements
|
|
76
|
+
} : {
|
|
77
|
+
iframes: {
|
|
78
|
+
detected: false,
|
|
79
|
+
count: 0,
|
|
80
|
+
accessible: [],
|
|
81
|
+
inaccessible: []
|
|
82
|
+
},
|
|
83
|
+
modalStates: {
|
|
84
|
+
hasDialog: false,
|
|
85
|
+
hasFileChooser: false,
|
|
86
|
+
blockedBy: []
|
|
87
|
+
},
|
|
88
|
+
elements: { totalVisible: 0, totalInteractable: 0, missingAria: 0 }
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
structureAnalysis: convertedStructureAnalysis,
|
|
92
|
+
performanceMetrics: performanceMetrics ?? {},
|
|
93
|
+
resourceUsage: null,
|
|
94
|
+
executionTime,
|
|
95
|
+
errors
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async executeAnalysis(_stepName, analysisFunction) {
|
|
99
|
+
return await analysisFunction();
|
|
100
|
+
}
|
|
101
|
+
processAnalysisResults(results, errors) {
|
|
102
|
+
let structureAnalysis;
|
|
103
|
+
let performanceMetrics;
|
|
104
|
+
for (let index = 0;index < results.length; index++) {
|
|
105
|
+
const result = results[index];
|
|
106
|
+
const stepName = index === 0 ? "structure-analysis" : "performance-metrics";
|
|
107
|
+
if (result.status === "fulfilled") {
|
|
108
|
+
if (stepName === "structure-analysis") {
|
|
109
|
+
structureAnalysis = result.value;
|
|
110
|
+
} else {
|
|
111
|
+
performanceMetrics = result.value;
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
const errorMsg = result.reason?.message ?? "Unknown error";
|
|
115
|
+
errors.push({
|
|
116
|
+
step: stepName,
|
|
117
|
+
error: errorMsg
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { structureAnalysis, performanceMetrics };
|
|
122
|
+
}
|
|
123
|
+
async dispose() {
|
|
124
|
+
await this.disposableManager.dispose();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
ParallelPageAnalyzer
|
|
129
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/diagnostics/resource-manager.ts
|
|
21
|
+
import debug from "debug";
|
|
22
|
+
var resourceDebug = debug("pw:mcp:resource");
|
|
23
|
+
|
|
24
|
+
class ResourceManager {
|
|
25
|
+
resources = new Map;
|
|
26
|
+
nextId = 0;
|
|
27
|
+
disposeTimeout = 30000;
|
|
28
|
+
cleanupInterval = null;
|
|
29
|
+
constructor() {
|
|
30
|
+
this.startCleanupTimer();
|
|
31
|
+
}
|
|
32
|
+
trackResource(resource, disposeMethod) {
|
|
33
|
+
const id = `resource_${this.nextId}`;
|
|
34
|
+
this.nextId++;
|
|
35
|
+
this.resources.set(id, {
|
|
36
|
+
resource,
|
|
37
|
+
disposeMethod,
|
|
38
|
+
timestamp: Date.now()
|
|
39
|
+
});
|
|
40
|
+
return id;
|
|
41
|
+
}
|
|
42
|
+
untrackResource(id) {
|
|
43
|
+
this.resources.delete(id);
|
|
44
|
+
}
|
|
45
|
+
async disposeAll() {
|
|
46
|
+
const disposePromises = [];
|
|
47
|
+
for (const [id, { resource, disposeMethod }] of Array.from(this.resources.entries())) {
|
|
48
|
+
try {
|
|
49
|
+
if (resource && typeof resource[disposeMethod] === "function") {
|
|
50
|
+
const disposeFn = resource[disposeMethod];
|
|
51
|
+
disposePromises.push(disposeFn());
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
resourceDebug(`Failed to dispose resource ${id}:`, error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await Promise.allSettled(disposePromises);
|
|
58
|
+
this.resources.clear();
|
|
59
|
+
}
|
|
60
|
+
getActiveCount() {
|
|
61
|
+
return this.resources.size;
|
|
62
|
+
}
|
|
63
|
+
setDisposeTimeout(timeout) {
|
|
64
|
+
this.disposeTimeout = timeout;
|
|
65
|
+
}
|
|
66
|
+
getDisposeTimeout() {
|
|
67
|
+
return this.disposeTimeout;
|
|
68
|
+
}
|
|
69
|
+
createSmartHandle(resource, disposeMethod) {
|
|
70
|
+
const id = this.trackResource(resource, disposeMethod);
|
|
71
|
+
return { handle: resource, id };
|
|
72
|
+
}
|
|
73
|
+
getResourceStats() {
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
let expiredCount = 0;
|
|
76
|
+
for (const [, { timestamp }] of Array.from(this.resources.entries())) {
|
|
77
|
+
if (now - timestamp > this.disposeTimeout) {
|
|
78
|
+
expiredCount++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
totalTracked: this.resources.size,
|
|
83
|
+
activeCount: this.resources.size - expiredCount,
|
|
84
|
+
expiredCount,
|
|
85
|
+
memoryUsage: process.memoryUsage().heapUsed
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
startCleanupTimer() {
|
|
89
|
+
this.cleanupInterval = setInterval(() => {
|
|
90
|
+
this.cleanupExpiredResources().catch(() => {});
|
|
91
|
+
}, this.disposeTimeout / 2);
|
|
92
|
+
}
|
|
93
|
+
async cleanupExpiredResources() {
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const expiredIds = [];
|
|
96
|
+
for (const [id, { timestamp }] of Array.from(this.resources.entries())) {
|
|
97
|
+
if (now - timestamp > this.disposeTimeout) {
|
|
98
|
+
expiredIds.push(id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const disposeSequentially = async (index) => {
|
|
102
|
+
if (index >= expiredIds.length) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const id = expiredIds[index];
|
|
106
|
+
const entry = this.resources.get(id);
|
|
107
|
+
if (entry) {
|
|
108
|
+
try {
|
|
109
|
+
if (entry.resource && typeof entry.resource[entry.disposeMethod] === "function") {
|
|
110
|
+
const disposeFn = entry.resource[entry.disposeMethod];
|
|
111
|
+
await disposeFn();
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
resourceDebug(`Failed to dispose expired resource ${id}:`, error);
|
|
115
|
+
}
|
|
116
|
+
this.untrackResource(id);
|
|
117
|
+
}
|
|
118
|
+
await disposeSequentially(index + 1);
|
|
119
|
+
};
|
|
120
|
+
await disposeSequentially(0);
|
|
121
|
+
}
|
|
122
|
+
async dispose() {
|
|
123
|
+
if (this.cleanupInterval) {
|
|
124
|
+
clearInterval(this.cleanupInterval);
|
|
125
|
+
this.cleanupInterval = null;
|
|
126
|
+
}
|
|
127
|
+
await this.disposeAll();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
var globalResourceManager = new ResourceManager;
|
|
131
|
+
export {
|
|
132
|
+
globalResourceManager,
|
|
133
|
+
ResourceManager
|
|
134
|
+
};
|