chrometools-mcp 1.8.2 → 2.2.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/CHANGELOG.md +757 -494
- package/README.md +219 -41
- package/browser/browser-manager.js +206 -0
- package/browser/page-manager.js +298 -0
- package/index.js +525 -1892
- package/package.json +55 -55
- package/recorder/page-object-generator.js +720 -0
- package/recorder/recorder-script.js +118 -12
- package/recorder/scenario-executor.js +970 -946
- package/recorder/scenario-storage.js +253 -29
- package/server/tool-definitions.js +620 -0
- package/server/tool-schemas.js +295 -0
- package/utils/code-generators/code-generator-base.js +61 -0
- package/utils/code-generators/file-appender.js +202 -0
- package/utils/code-generators/playwright-python.js +84 -0
- package/utils/code-generators/playwright-typescript.js +95 -0
- package/utils/code-generators/selenium-java.js +123 -0
- package/utils/code-generators/selenium-python.js +82 -0
- package/utils/css-utils.js +151 -0
- package/utils/image-processing.js +236 -0
- package/utils/platform-utils.js +62 -0
- package/utils/url-to-project.js +141 -0
- package/index.js.backup +0 -3674
- package/utils/project-detector.js +0 -87
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* utils/platform-utils.js
|
|
3
|
+
*
|
|
4
|
+
* Platform detection and platform-specific utilities
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Detect WSL environment
|
|
11
|
+
* @returns {boolean} - True if running in WSL
|
|
12
|
+
*/
|
|
13
|
+
export const isWSL = (() => {
|
|
14
|
+
try {
|
|
15
|
+
const proc_version = readFileSync('/proc/version', 'utf8').toLowerCase();
|
|
16
|
+
return proc_version.includes('microsoft') || proc_version.includes('wsl');
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Detect Windows environment (including WSL)
|
|
24
|
+
* @returns {boolean} - True if running on Windows or WSL
|
|
25
|
+
*/
|
|
26
|
+
export const isWindows = process.platform === 'win32' || isWSL;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get Chrome executable path based on platform
|
|
30
|
+
* @returns {string} - Path to Chrome executable
|
|
31
|
+
*/
|
|
32
|
+
export function getChromePath() {
|
|
33
|
+
if (process.platform === 'win32') {
|
|
34
|
+
// Native Windows
|
|
35
|
+
return 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
|
|
36
|
+
} else if (isWSL) {
|
|
37
|
+
// WSL - use Windows Chrome
|
|
38
|
+
return '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe';
|
|
39
|
+
} else {
|
|
40
|
+
// Linux
|
|
41
|
+
return '/usr/bin/google-chrome';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get temp directory based on platform
|
|
47
|
+
* @returns {string} - Path to temp directory
|
|
48
|
+
*/
|
|
49
|
+
export function getTempDir() {
|
|
50
|
+
if (process.platform === 'win32') {
|
|
51
|
+
return process.env.TEMP || 'C:\\Windows\\Temp';
|
|
52
|
+
} else if (isWSL) {
|
|
53
|
+
return '/mnt/c/Windows/Temp';
|
|
54
|
+
} else {
|
|
55
|
+
return process.env.TMPDIR || '/tmp';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Chrome remote debugging port
|
|
61
|
+
*/
|
|
62
|
+
export const CHROME_DEBUG_PORT = 9222;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* utils/url-to-project.js
|
|
3
|
+
*
|
|
4
|
+
* Utilities for extracting project ID from website URLs.
|
|
5
|
+
* Used by scenario recorder to organize scenarios by domain.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extract project ID from URL
|
|
10
|
+
*
|
|
11
|
+
* Strategy (v3.0):
|
|
12
|
+
* - Always use main domain only (strip all subdomains)
|
|
13
|
+
* - Include ports for ALL domains (localhost and others)
|
|
14
|
+
* - file:// URLs → "local"
|
|
15
|
+
* - Invalid URLs → "unknown"
|
|
16
|
+
*
|
|
17
|
+
* Examples:
|
|
18
|
+
* - https://www.google.com → "google"
|
|
19
|
+
* - https://dev.example.com:8080 → "example-8080"
|
|
20
|
+
* - https://mail.google.com → "google"
|
|
21
|
+
* - http://localhost:3000 → "localhost-3000"
|
|
22
|
+
* - https://api.stripe.com:443 → "stripe-443"
|
|
23
|
+
* - file:///C:/test.html → "local"
|
|
24
|
+
*
|
|
25
|
+
* @param {string} url - Full URL
|
|
26
|
+
* @returns {string} - Project ID (e.g., "google", "localhost-3000", "example-8080")
|
|
27
|
+
*/
|
|
28
|
+
export function urlToProjectId(url) {
|
|
29
|
+
try {
|
|
30
|
+
// Handle file:// protocol
|
|
31
|
+
if (url.startsWith('file://')) {
|
|
32
|
+
return 'local';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const urlObj = new URL(url);
|
|
36
|
+
let hostname = urlObj.hostname.toLowerCase();
|
|
37
|
+
const port = urlObj.port;
|
|
38
|
+
|
|
39
|
+
// Remove www prefix
|
|
40
|
+
hostname = hostname.replace(/^www\./, '');
|
|
41
|
+
|
|
42
|
+
// Split hostname into parts
|
|
43
|
+
const parts = hostname.split('.');
|
|
44
|
+
|
|
45
|
+
// Single-level hostnames (e.g., "localhost", "example")
|
|
46
|
+
if (parts.length === 1) {
|
|
47
|
+
const projectId = sanitizeProjectId(parts[0]);
|
|
48
|
+
return port ? `${projectId}-${port}` : projectId;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Multi-level hostnames: extract main domain (second-to-last part before TLD)
|
|
52
|
+
// Examples:
|
|
53
|
+
// - google.com → parts=['google', 'com'] → mainDomain='google'
|
|
54
|
+
// - dev.example.com → parts=['dev', 'example', 'com'] → mainDomain='example'
|
|
55
|
+
// - mail.google.co.uk → parts=['mail', 'google', 'co', 'uk'] → mainDomain='co' (not ideal, but simple)
|
|
56
|
+
const mainDomain = parts[parts.length - 2];
|
|
57
|
+
const projectId = sanitizeProjectId(mainDomain);
|
|
58
|
+
|
|
59
|
+
// Add port if present (for ALL domains, not just localhost)
|
|
60
|
+
return port ? `${projectId}-${port}` : projectId;
|
|
61
|
+
|
|
62
|
+
} catch (error) {
|
|
63
|
+
// Invalid URL, return safe fallback
|
|
64
|
+
console.error('[url-to-project] Invalid URL:', url, error);
|
|
65
|
+
return 'unknown';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Sanitize project ID
|
|
71
|
+
* - Lowercase everything
|
|
72
|
+
* - Replace non-alphanumeric characters with hyphens
|
|
73
|
+
* - Collapse multiple hyphens into one
|
|
74
|
+
* - Remove leading/trailing hyphens
|
|
75
|
+
*
|
|
76
|
+
* @param {string} id - Raw project ID
|
|
77
|
+
* @returns {string} - Sanitized ID
|
|
78
|
+
*/
|
|
79
|
+
function sanitizeProjectId(id) {
|
|
80
|
+
return id
|
|
81
|
+
.toLowerCase()
|
|
82
|
+
.replace(/[^a-z0-9-]/g, '-') // Replace non-alphanumeric with hyphens
|
|
83
|
+
.replace(/-+/g, '-') // Collapse multiple hyphens
|
|
84
|
+
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get browser-compatible version of urlToProjectId for injection
|
|
89
|
+
* Returns the function as a string to be injected into browser context
|
|
90
|
+
*
|
|
91
|
+
* @returns {string} - Function code as string
|
|
92
|
+
*/
|
|
93
|
+
export function getUrlToProjectIdForBrowser() {
|
|
94
|
+
return `
|
|
95
|
+
/**
|
|
96
|
+
* Extract project ID from URL (browser version)
|
|
97
|
+
* @param {string} url - Full URL
|
|
98
|
+
* @returns {string} - Project ID
|
|
99
|
+
*/
|
|
100
|
+
function urlToProjectId(url) {
|
|
101
|
+
try {
|
|
102
|
+
if (url.startsWith('file://')) {
|
|
103
|
+
return 'local';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const urlObj = new URL(url);
|
|
107
|
+
let hostname = urlObj.hostname.toLowerCase();
|
|
108
|
+
const port = urlObj.port;
|
|
109
|
+
|
|
110
|
+
hostname = hostname.replace(/^www\\./, '');
|
|
111
|
+
const parts = hostname.split('.');
|
|
112
|
+
|
|
113
|
+
if (parts.length === 1) {
|
|
114
|
+
const projectId = sanitizeProjectId(parts[0]);
|
|
115
|
+
return port ? \`\${projectId}-\${port}\` : projectId;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const mainDomain = parts[parts.length - 2];
|
|
119
|
+
const projectId = sanitizeProjectId(mainDomain);
|
|
120
|
+
return port ? \`\${projectId}-\${port}\` : projectId;
|
|
121
|
+
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('[url-to-project] Invalid URL:', url, error);
|
|
124
|
+
return 'unknown';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sanitize project ID (browser version)
|
|
130
|
+
* @param {string} id - Raw project ID
|
|
131
|
+
* @returns {string} - Sanitized ID
|
|
132
|
+
*/
|
|
133
|
+
function sanitizeProjectId(id) {
|
|
134
|
+
return id
|
|
135
|
+
.toLowerCase()
|
|
136
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
137
|
+
.replace(/-+/g, '-')
|
|
138
|
+
.replace(/^-|-$/g, '');
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
}
|