chrometools-mcp 1.9.1 → 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 +225 -0
- package/README.md +217 -41
- package/browser/browser-manager.js +206 -0
- package/browser/page-manager.js +298 -0
- package/index.js +525 -1901
- package/package.json +1 -1
- package/recorder/page-object-generator.js +720 -0
- package/recorder/recorder-script.js +63 -9
- package/recorder/scenario-executor.js +47 -27
- package/recorder/scenario-storage.js +251 -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/utils/project-detector.js +0 -87
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,231 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.2.0] - 2025-12-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Page Object Model (POM) Generator** - New `generatePageObject` MCP tool for automated Page Object creation
|
|
9
|
+
- Analyzes current page and extracts interactive elements (inputs, buttons, links, etc.)
|
|
10
|
+
- Smart selector generation: prioritizes id > name > data-testid > unique class > CSS path
|
|
11
|
+
- Auto-generates meaningful element names from labels, placeholders, text content
|
|
12
|
+
- Groups elements by semantic sections (header, nav, form, footer, etc.)
|
|
13
|
+
- Supports 4 frameworks: Playwright TypeScript/Python, Selenium Python/Java
|
|
14
|
+
- Generates helper methods automatically (fill/click methods for common actions)
|
|
15
|
+
- Example: `generatePageObject({ framework: 'playwright-typescript' })`
|
|
16
|
+
- Location: `recorder/page-object-generator.js`, `index.js:46,2098-2136`
|
|
17
|
+
|
|
18
|
+
- **Page Object Integration in exportScenarioAsCode** - Optional Page Object generation when exporting scenarios
|
|
19
|
+
- New parameter `generatePageObject` (default: false) to generate both test code and Page Object class
|
|
20
|
+
- New parameter `pageObjectClassName` for custom Page Object class names
|
|
21
|
+
- Opens scenario's entry URL and analyzes page structure automatically
|
|
22
|
+
- Returns JSON with both `testCode` and `pageObjectCode` when enabled
|
|
23
|
+
- Example: `exportScenarioAsCode({ scenarioName: "login", language: "playwright-typescript", generatePageObject: true })`
|
|
24
|
+
- Location: `index.js:2090-2186`, `server/tool-schemas.js:281-282`, `server/tool-definitions.js:565-572`
|
|
25
|
+
|
|
26
|
+
- **Append Mode for exportScenarioAsCode** - Ability to append generated tests to existing test files
|
|
27
|
+
- New parameter `appendToFile`: Path to existing test file to append to (enables append mode)
|
|
28
|
+
- New parameter `testName`: Override test name (default: from scenario name)
|
|
29
|
+
- New parameter `insertPosition`: Where to insert test - 'end' (default), 'before', or 'after' a reference test
|
|
30
|
+
- New parameter `referenceTestName`: Reference test name for 'before'/'after' insertion
|
|
31
|
+
- Supports all 4 frameworks: Playwright TypeScript/Python, Selenium Python/Java
|
|
32
|
+
- Automatic file validation (extension must match language)
|
|
33
|
+
- Automatic backup before file modification (.backup extension)
|
|
34
|
+
- Smart test name conversion (camelCase for Java, snake_case for Python, kebab-case for TypeScript)
|
|
35
|
+
- Framework-specific parsing: brace counting for TypeScript/Java, indentation-based for Python
|
|
36
|
+
- PEP 8 compliance: 2 blank lines between Python functions
|
|
37
|
+
- Example: `exportScenarioAsCode({ scenarioName: "new_test", language: "playwright-typescript", appendToFile: "./tests/suite.spec.ts" })`
|
|
38
|
+
- Location: `utils/code-generators/file-appender.js` (new 177 lines), `index.js:2044-2116`, `server/tool-schemas.js:283-286`, `utils/code-generators/*.js`
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- **Dependency Resolution with projectId** - Fixed collision errors when executing scenarios with dependencies
|
|
42
|
+
- Dependencies now correctly inherit parent scenario's projectId when not explicitly specified
|
|
43
|
+
- Explicit dependency projectId in metadata takes precedence over inherited value
|
|
44
|
+
- Fixes error: "Dependency 'test': Multiple scenarios named 'test' found"
|
|
45
|
+
- Location: `recorder/scenario-executor.js:63-119`
|
|
46
|
+
|
|
47
|
+
## [2.1.1] - 2025-12-21
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- **executeScenario Timeout Fix** - Prevents hanging when no browser tab is attached
|
|
51
|
+
- Auto-opens browser at scenario's entryUrl if no page is open
|
|
52
|
+
- Added timeout protection (1s) for page state checks to prevent hanging on `isClosed()`
|
|
53
|
+
- Added 30s timeout for browser opening operation
|
|
54
|
+
- Added 5min timeout for scenario execution with clear error messages
|
|
55
|
+
- Location: `browser/page-manager.js:255-290`, `index.js:1875-1955`
|
|
56
|
+
|
|
57
|
+
- **URL Validation Fix** - Fixed false negative in scenario exit URL validation
|
|
58
|
+
- Added 500ms wait before URL check to allow navigation/redirects to complete
|
|
59
|
+
- Changed from `page.url()` to `page.evaluate(() => window.location.href)` for more reliable current URL
|
|
60
|
+
- Fixes issue where correct URL was reported as wrong due to timing
|
|
61
|
+
- Location: `recorder/scenario-executor.js:186-191`
|
|
62
|
+
|
|
63
|
+
- **Global Timeout Protection** - All MCP tools now protected from hanging
|
|
64
|
+
- Added `executeToolWithTimeout()` wrapper for all tool calls
|
|
65
|
+
- Default timeout: 2 minutes for regular tools, 6 minutes for executeScenario
|
|
66
|
+
- Tools return clear error messages instead of hanging indefinitely
|
|
67
|
+
- Location: `index.js:183-217`
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- **Code Refactoring** - Reduced index.js from 3761 to 2093 lines (-44%)
|
|
71
|
+
- Extracted tool schemas to `server/tool-schemas.js` (34 schemas, 282 lines)
|
|
72
|
+
- Extracted tool definitions to `server/tool-definitions.js` (41 tools, 569 lines)
|
|
73
|
+
- Extracted browser management to `browser/browser-manager.js` (207 lines)
|
|
74
|
+
- Extracted page management to `browser/page-manager.js` (268 lines)
|
|
75
|
+
- Extracted image processing to `utils/image-processing.js` (254 lines)
|
|
76
|
+
- Extracted CSS utilities to `utils/css-utils.js` (163 lines)
|
|
77
|
+
- Extracted platform utilities to `utils/platform-utils.js` (63 lines)
|
|
78
|
+
- Better code organization and maintainability
|
|
79
|
+
|
|
80
|
+
## [2.1.0] - 2025-12-21
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
- **Name Collision Detection** - Smart handling of scenarios with same name across different projects
|
|
84
|
+
- `executeScenario` now detects when multiple scenarios share the same name
|
|
85
|
+
- Returns helpful error with list of available `projectId` values
|
|
86
|
+
- Optional `projectId` parameter to disambiguate: `executeScenario({ name: "login", projectId: "google" })`
|
|
87
|
+
- Location: `recorder/scenario-storage.js:111-163`, `recorder/scenario-executor.js:33,49-61,86-90`, `index.js:1677,3558-3571,3597-3600`
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
- **URL-Based Scenario Organization** - Scenarios now organized by website domain instead of file system project
|
|
91
|
+
- Project ID automatically extracted from URL where recording starts: `https://google.com` → `google`
|
|
92
|
+
- Main domain only (subdomains stripped): `mail.google.com` → `google`
|
|
93
|
+
- Ports included for ALL domains: `localhost:3000` → `localhost-3000`, `example.com:8080` → `example-8080`
|
|
94
|
+
- Protocol ignored: `http` and `https` both map to same projectId
|
|
95
|
+
- File URLs: `file:///` → `local`
|
|
96
|
+
- Location: `utils/url-to-project.js`, `recorder/recorder-script.js:30-78`
|
|
97
|
+
|
|
98
|
+
- **Global Scenario Access** - All tools now return scenarios from ALL websites
|
|
99
|
+
- `listScenarios()` returns ALL scenarios with `projectId`, `entryUrl`, `exitUrl` metadata
|
|
100
|
+
- `searchScenarios()` searches ALL scenarios across all websites
|
|
101
|
+
- Agent can filter results by `projectId`, `entryUrl`, or `exitUrl` as needed
|
|
102
|
+
- Removed `allProjects` parameter (no longer needed, always returns all)
|
|
103
|
+
- Location: `index.js:3586-3610`
|
|
104
|
+
|
|
105
|
+
- **Simplified API** - Recorder no longer depends on file system project detection
|
|
106
|
+
- `injectRecorder()` signature changed from `(page, projectDir, projectId, projectPath)` to `(page)`
|
|
107
|
+
- Project ID determined automatically from page URL in browser context
|
|
108
|
+
- Removed dependency on `utils/project-detector.js`
|
|
109
|
+
- Location: `recorder/recorder-script.js:1710-1763`, `index.js:3512-3533`
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
- **URL Normalization Utilities** - New module for extracting project ID from URLs
|
|
113
|
+
- `urlToProjectId(url)` - Extract and sanitize domain-based project ID
|
|
114
|
+
- `sanitizeProjectId(id)` - Clean project IDs (lowercase, alphanumeric, hyphens)
|
|
115
|
+
- Browser-compatible version injected into recorder widget
|
|
116
|
+
- Location: `utils/url-to-project.js`
|
|
117
|
+
|
|
118
|
+
### Migration
|
|
119
|
+
- **Automatic v2.1.0 Migration** - Old project-based scenarios removed on first run
|
|
120
|
+
- Deletes `~/.config/chrometools-mcp/projects/` directory from v2.0
|
|
121
|
+
- Deletes old global index
|
|
122
|
+
- Creates `.migration-v2.1.0-done` flag file
|
|
123
|
+
- One-time migration, starts fresh with URL-based organization
|
|
124
|
+
- Location: `index.js:780-811`
|
|
125
|
+
|
|
126
|
+
### Removed
|
|
127
|
+
- **Removed `utils/project-detector.js`** - No longer needed for URL-based organization
|
|
128
|
+
- **Removed helper functions** - `getProjectId()`, `getProjectDir()`, `getCurrentProjectDir()`
|
|
129
|
+
- **Removed old scenarios** - All v2.0 scenarios deleted during migration
|
|
130
|
+
|
|
131
|
+
### Documentation
|
|
132
|
+
- **Updated README.md** - Complete rewrite of Recorder Tools section
|
|
133
|
+
- Explained URL-based storage approach with examples
|
|
134
|
+
- Updated all tool descriptions and examples
|
|
135
|
+
- Documented domain extraction rules
|
|
136
|
+
- Added filtering examples for agents
|
|
137
|
+
- Location: `README.md:507-618`
|
|
138
|
+
|
|
139
|
+
## [2.0.2] - 2025-12-21
|
|
140
|
+
|
|
141
|
+
### Fixed
|
|
142
|
+
- **Project Detection for VS Code** - Improved project root detection for IDE environments
|
|
143
|
+
- Added support for `INIT_CWD` and `npm_config_local_prefix` environment variables
|
|
144
|
+
- Added `findProjectRootByMarkers()` to detect project by package.json, pom.xml, etc.
|
|
145
|
+
- Walks up parent directories to find Git root when cwd is IDE installation
|
|
146
|
+
- Now correctly detects `C:\prj\automation` instead of `Microsoft VS Code` when running in VS Code
|
|
147
|
+
- Location: `utils/project-detector.js:38-68`, `utils/project-detector.js:85-140`
|
|
148
|
+
|
|
149
|
+
### Added
|
|
150
|
+
- **Enhanced Project Detection Strategy** - Multiple fallback mechanisms for project root detection
|
|
151
|
+
- Priority: CLAUDE_PROJECT_DIR → PROJECT_DIR → INIT_CWD → npm prefix → Git root → markers → parent Git → cwd
|
|
152
|
+
- Supports 8+ project markers: package.json, pom.xml, build.gradle, Cargo.toml, go.mod, etc.
|
|
153
|
+
- Better logging with `console.error` for debugging project detection
|
|
154
|
+
|
|
155
|
+
### Documentation
|
|
156
|
+
- **VS Code Setup Guide** - Add instructions for setting PROJECT_DIR in MCP config for VS Code users
|
|
157
|
+
|
|
158
|
+
## [2.0.1] - 2025-12-21
|
|
159
|
+
|
|
160
|
+
### Fixed
|
|
161
|
+
- **Recorder Auto-Reinjection** - Fixed critical bug where recorder widget didn't reinject after page navigation
|
|
162
|
+
- Updated `setupRecorderAutoReinjection()` to use new v2.0 API signature
|
|
163
|
+
- Fixed both navigation (`framenavigated`) and reload (`load`) event handlers
|
|
164
|
+
- Recorder now correctly passes `projectDir`, `projectId`, and `projectPath` instead of deprecated `baseDir`
|
|
165
|
+
- Location: `index.js:483-486`, `index.js:499-502`
|
|
166
|
+
|
|
167
|
+
## [2.0.0] - 2025-12-21
|
|
168
|
+
|
|
169
|
+
### Breaking Changes
|
|
170
|
+
- **Project-Based Scenario Storage** - Complete restructuring of scenario storage system
|
|
171
|
+
- Scenarios now stored in `~/.config/chrometools-mcp/projects/{projectName}/scenarios/`
|
|
172
|
+
- Each project has its own isolated scenario storage
|
|
173
|
+
- Automatic project detection via `detectProjectRoot()` (CLAUDE_PROJECT_DIR → PROJECT_DIR → git root → cwd)
|
|
174
|
+
- Global index file at `~/.config/chrometools-mcp/index.json` for fast scenario discovery
|
|
175
|
+
- Scenarios include `projectId` and `projectPath` in metadata
|
|
176
|
+
- Old scenarios in `~/.config/chrometools-mcp/scenarios/` will no longer be accessible
|
|
177
|
+
- Location: `index.js:66-159`, `recorder/scenario-storage.js`
|
|
178
|
+
|
|
179
|
+
- **Removed `directory` parameter** - All scenario tools no longer accept explicit directory parameter
|
|
180
|
+
- Removed from: `enableRecorder`, `executeScenario`, `listScenarios`, `searchScenarios`, `getScenarioInfo`, `deleteScenario`, `exportScenarioAsCode`
|
|
181
|
+
- Project directory is now automatically determined
|
|
182
|
+
- Simplifies API and improves consistency
|
|
183
|
+
- Location: `index.js:1659-1750` (tool definitions)
|
|
184
|
+
|
|
185
|
+
### Added
|
|
186
|
+
- **Global Scenario Index** - Fast O(1) scenario lookups without filesystem scanning
|
|
187
|
+
- Location: `~/.config/chrometools-mcp/index.json`
|
|
188
|
+
- Contains all projects and their scenarios
|
|
189
|
+
- Enables quick discovery of scenarios across all projects
|
|
190
|
+
- AI-friendly: agents can read global index to understand all available scenarios
|
|
191
|
+
- Location: `index.js:103-159`, `recorder/scenario-storage.js:23-136`
|
|
192
|
+
|
|
193
|
+
- **Multi-Project Filtering** - New `allProjects` parameter for `listScenarios` and `searchScenarios`
|
|
194
|
+
- `allProjects: false` (default) - shows only current project's scenarios
|
|
195
|
+
- `allProjects: true` - shows scenarios from all projects
|
|
196
|
+
- Enables cross-project scenario discovery and reuse
|
|
197
|
+
- Location: `index.js:1685`, `index.js:1697`, `recorder/scenario-storage.js:385-453`
|
|
198
|
+
|
|
199
|
+
- **Cross-Project Dependency Support** - Scenarios can depend on scenarios from other projects
|
|
200
|
+
- Dependencies automatically resolved across projects via global index
|
|
201
|
+
- Enables scenario reuse between projects
|
|
202
|
+
- Location: `recorder/scenario-executor.js:27-121`
|
|
203
|
+
|
|
204
|
+
- **Storage Path in Tool Descriptions** - All scenario tools now document storage location
|
|
205
|
+
- Every tool description includes: "Scenarios are stored in ~/.config/chrometools-mcp/projects/{projectName}/scenarios/"
|
|
206
|
+
- Helps AI agents understand where to find scenarios
|
|
207
|
+
- Includes reference to global index location
|
|
208
|
+
- Location: `index.js:1660`, `index.js:1668`, `index.js:1681`, etc.
|
|
209
|
+
|
|
210
|
+
### Changed
|
|
211
|
+
- **Scenario Storage Functions** - Updated all storage functions for new architecture
|
|
212
|
+
- `saveScenario(scenario, projectId, projectPath)` - now requires project info instead of baseDir
|
|
213
|
+
- `loadScenario(name, includeSecrets, projectId)` - searches globally, optional project filter
|
|
214
|
+
- `listScenarios(projectId, allProjects)` - reads from global index
|
|
215
|
+
- `searchScenarios(query, projectId, allProjects)` - searches global index
|
|
216
|
+
- `deleteScenario(name, projectId)` - finds and deletes from correct project
|
|
217
|
+
- Location: `recorder/scenario-storage.js:191-500`
|
|
218
|
+
|
|
219
|
+
- **Recorder Injection** - Updated to pass project information
|
|
220
|
+
- `injectRecorder(page, projectDir, projectId, projectPath)` - now accepts project details
|
|
221
|
+
- Scenarios saved with project context automatically
|
|
222
|
+
- Location: `recorder/recorder-script.js:1659`
|
|
223
|
+
|
|
224
|
+
### Migration Guide
|
|
225
|
+
- **Old scenarios are inaccessible** - Scenarios in `~/.config/chrometools-mcp/scenarios/` will no longer be found
|
|
226
|
+
- To migrate: Manually move scenarios to new structure or re-record them
|
|
227
|
+
- New structure: `~/.config/chrometools-mcp/projects/{projectName}/scenarios/`
|
|
228
|
+
- **No code changes needed** - All changes are internal, MCP tool interface remains compatible (except removed `directory` parameter)
|
|
229
|
+
|
|
5
230
|
## [1.9.1] - 2025-12-19
|
|
6
231
|
|
|
7
232
|
### Fixed
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ MCP server for Chrome automation using Puppeteer with persistent browser session
|
|
|
14
14
|
- [Interaction Tools](#2-interaction-tools) - click, type, scrollTo
|
|
15
15
|
- [Inspection Tools](#3-inspection-tools) - getElement, getComputedCss, getBoxModel, screenshot
|
|
16
16
|
- [Advanced Tools](#4-advanced-tools) - executeScript, getConsoleLogs, listNetworkRequests, getNetworkRequest, filterNetworkRequests, hover, setStyles, setViewport, getViewport, navigateTo
|
|
17
|
-
- [Recorder Tools](#6-recorder-tools) ⭐ **NEW** - enableRecorder, executeScenario, listScenarios, searchScenarios, getScenarioInfo, deleteScenario, exportScenarioAsCode
|
|
17
|
+
- [Recorder Tools](#6-recorder-tools) ⭐ **NEW** - enableRecorder, executeScenario, listScenarios, searchScenarios, getScenarioInfo, deleteScenario, exportScenarioAsCode, generatePageObject
|
|
18
18
|
- [Typical Workflow Example](#typical-workflow-example)
|
|
19
19
|
- [Tool Usage Tips](#tool-usage-tips)
|
|
20
20
|
- [Configuration](#configuration)
|
|
@@ -506,56 +506,74 @@ Extract detailed design specifications from Figma including text content, colors
|
|
|
506
506
|
|
|
507
507
|
### 6. Recorder Tools ⭐ NEW
|
|
508
508
|
|
|
509
|
-
**
|
|
509
|
+
**URL-Based Storage (v2.1+)**: Scenarios are automatically organized by website domain in `~/.config/chrometools-mcp/projects/{domain}/scenarios/`.
|
|
510
510
|
|
|
511
|
-
**
|
|
511
|
+
**Automatic Domain Detection**: Project ID is extracted from the URL where recording starts:
|
|
512
|
+
- `https://www.google.com` → `google`
|
|
513
|
+
- `https://dev.example.com:8080` → `example-8080`
|
|
514
|
+
- `http://localhost:3000` → `localhost-3000`
|
|
515
|
+
- `file:///test.html` → `local`
|
|
512
516
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
517
|
+
**Domain Organization Rules**:
|
|
518
|
+
1. Main domain only (subdomains stripped): `mail.google.com` → `google`
|
|
519
|
+
2. Ports included for ALL domains: `example.com:8080` → `example-8080`
|
|
520
|
+
3. Protocol ignored: `http` and `https` both → same project
|
|
516
521
|
|
|
517
|
-
|
|
522
|
+
**Global Scenario Access**: All tools (`listScenarios`, `searchScenarios`) return scenarios from **all projects**. Agent can filter by:
|
|
523
|
+
- `projectId`: Domain-based identifier (e.g., "google", "localhost-3000")
|
|
524
|
+
- `entryUrl`: URL where recording started
|
|
525
|
+
- `exitUrl`: URL where recording ended
|
|
518
526
|
|
|
519
527
|
**Example**:
|
|
520
528
|
```javascript
|
|
521
|
-
//
|
|
522
|
-
enableRecorder() // Saves to ~/.config/chrometools-mcp
|
|
523
|
-
|
|
524
|
-
//
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
//
|
|
528
|
-
|
|
529
|
+
// Record scenario on google.com
|
|
530
|
+
enableRecorder() // Saves to ~/.config/chrometools-mcp/projects/google/scenarios/
|
|
531
|
+
|
|
532
|
+
// List ALL scenarios from all websites
|
|
533
|
+
listScenarios()
|
|
534
|
+
// Returns: [
|
|
535
|
+
// { name: "search", projectId: "google", entryUrl: "https://google.com" },
|
|
536
|
+
// { name: "login", projectId: "localhost-3000", entryUrl: "http://localhost:3000" }
|
|
537
|
+
// ]
|
|
538
|
+
|
|
539
|
+
// Agent filters by projectId or URL
|
|
540
|
+
scenarios.filter(s => s.projectId === "google")
|
|
541
|
+
scenarios.filter(s => s.entryUrl.includes("localhost"))
|
|
542
|
+
|
|
543
|
+
// Execute scenario (searches all projects automatically)
|
|
544
|
+
executeScenario({ name: "login" }) // Finds scenario in any project
|
|
529
545
|
```
|
|
530
546
|
|
|
531
547
|
---
|
|
532
548
|
|
|
533
549
|
#### enableRecorder
|
|
534
|
-
Inject visual recorder UI widget into the current page.
|
|
535
|
-
- **Parameters**:
|
|
536
|
-
- `directory` (optional): Directory to save scenarios (defaults to `~/.config/chrometools-mcp`)
|
|
550
|
+
Inject visual recorder UI widget into the current page. Scenarios are automatically saved to `~/.config/chrometools-mcp/projects/{domain}/scenarios/` based on the website URL.
|
|
551
|
+
- **Parameters**: None
|
|
537
552
|
- **Use case**: Start recording user interactions visually
|
|
538
|
-
- **Returns**: Success status
|
|
553
|
+
- **Returns**: Success status with storage location
|
|
539
554
|
- **Features**:
|
|
540
555
|
- Floating widget with compact mode (minimize to 50x50px)
|
|
541
556
|
- Visual recording indicator (red pulsing border)
|
|
542
557
|
- Start/Pause/Stop/Stop & Save/Clear controls
|
|
543
558
|
- Real-time action list display
|
|
544
559
|
- Metadata fields (name, description, tags)
|
|
560
|
+
- Automatic domain-based project detection from URL
|
|
545
561
|
|
|
546
562
|
#### executeScenario
|
|
547
|
-
Execute a previously recorded scenario by name.
|
|
563
|
+
Execute a previously recorded scenario by name. Searches all projects automatically via global index.
|
|
548
564
|
- **Parameters**:
|
|
549
565
|
- `name` (required): Scenario name
|
|
566
|
+
- `projectId` (optional): Project ID (domain) to disambiguate when multiple scenarios have the same name. Examples: `"google"`, `"localhost-3000"`
|
|
550
567
|
- `parameters` (optional): Runtime parameters (e.g., { email: "user@test.com" })
|
|
551
568
|
- `executeDependencies` (optional): Execute dependencies before running scenario (default: true)
|
|
552
|
-
|
|
553
|
-
- **Use case**: Run automated test scenarios
|
|
569
|
+
- **Use case**: Run automated test scenarios across projects
|
|
554
570
|
- **Returns**: Execution result with success/failure status
|
|
555
571
|
- **Features**:
|
|
556
572
|
- Automatic dependency resolution (enabled by default)
|
|
573
|
+
- Cross-project dependency support
|
|
557
574
|
- Secret parameter injection
|
|
558
575
|
- Fallback selector retry logic
|
|
576
|
+
- Name collision detection with helpful error messages
|
|
559
577
|
- **Example**:
|
|
560
578
|
```javascript
|
|
561
579
|
// Execute with dependencies (default)
|
|
@@ -563,56 +581,96 @@ Execute a previously recorded scenario by name.
|
|
|
563
581
|
|
|
564
582
|
// Execute without dependencies
|
|
565
583
|
executeScenario({ name: "create_post", executeDependencies: false })
|
|
584
|
+
|
|
585
|
+
// Disambiguate when multiple scenarios have same name
|
|
586
|
+
executeScenario({ name: "login", projectId: "google" })
|
|
587
|
+
executeScenario({ name: "login", projectId: "localhost-3000" })
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
- **Name Collision Handling**:
|
|
591
|
+
If multiple scenarios with the same name exist across different projects, you'll get an error:
|
|
592
|
+
```json
|
|
593
|
+
{
|
|
594
|
+
"success": false,
|
|
595
|
+
"error": "Multiple scenarios named 'login' found. Please specify projectId.",
|
|
596
|
+
"availableProjectIds": ["google", "localhost-3000"],
|
|
597
|
+
"hint": "Use: executeScenario({ name: \"login\", projectId: \"one-of-the-above\" })"
|
|
598
|
+
}
|
|
566
599
|
```
|
|
567
600
|
|
|
568
601
|
#### listScenarios
|
|
569
|
-
Get all available scenarios with metadata
|
|
570
|
-
- **Parameters**:
|
|
571
|
-
|
|
572
|
-
- **
|
|
573
|
-
- **
|
|
602
|
+
Get all available scenarios with metadata from **all websites**. Agent can filter by `projectId`, `entryUrl`, or `exitUrl`.
|
|
603
|
+
- **Parameters**: None
|
|
604
|
+
- **Use case**: Browse recorded scenarios across all websites
|
|
605
|
+
- **Returns**: Array of scenarios with names, descriptions, tags, timestamps, `projectId`, `entryUrl`, `exitUrl`
|
|
606
|
+
- **Example**:
|
|
607
|
+
```javascript
|
|
608
|
+
// List all scenarios from all websites
|
|
609
|
+
const scenarios = await listScenarios()
|
|
610
|
+
|
|
611
|
+
// Agent filters by projectId
|
|
612
|
+
const googleScenarios = scenarios.filter(s => s.projectId === "google")
|
|
613
|
+
|
|
614
|
+
// Agent filters by URL
|
|
615
|
+
const localhostScenarios = scenarios.filter(s => s.entryUrl.includes("localhost"))
|
|
616
|
+
```
|
|
574
617
|
|
|
575
618
|
#### searchScenarios
|
|
576
|
-
Search scenarios by text or tags.
|
|
619
|
+
Search scenarios by text or tags across **all websites**. Agent can further filter results by `projectId` or URLs.
|
|
577
620
|
- **Parameters**:
|
|
578
621
|
- `text` (optional): Search in name/description
|
|
579
622
|
- `tags` (optional): Array of tags to filter
|
|
580
|
-
|
|
581
|
-
- **
|
|
582
|
-
- **
|
|
623
|
+
- **Use case**: Find specific scenarios across all websites
|
|
624
|
+
- **Returns**: Matching scenarios with `projectId`, `entryUrl`, `exitUrl` metadata
|
|
625
|
+
- **Example**:
|
|
626
|
+
```javascript
|
|
627
|
+
// Search across all websites
|
|
628
|
+
const results = await searchScenarios({ text: "login" })
|
|
629
|
+
|
|
630
|
+
// Search by tags
|
|
631
|
+
const authScenarios = await searchScenarios({ tags: ["auth"] })
|
|
632
|
+
|
|
633
|
+
// Agent filters results by domain
|
|
634
|
+
const googleLogins = results.filter(s => s.projectId === "google")
|
|
635
|
+
```
|
|
583
636
|
|
|
584
637
|
#### getScenarioInfo
|
|
585
|
-
Get detailed information about a scenario.
|
|
638
|
+
Get detailed information about a scenario. Searches all projects automatically.
|
|
586
639
|
- **Parameters**:
|
|
587
640
|
- `name` (required): Scenario name
|
|
588
641
|
- `includeSecrets` (optional): Include secret values (default: false)
|
|
589
|
-
- `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
|
|
590
642
|
- **Use case**: Inspect scenario actions and dependencies
|
|
591
|
-
- **Returns**: Full scenario details (actions, metadata, dependencies)
|
|
643
|
+
- **Returns**: Full scenario details (actions, metadata, dependencies, project info)
|
|
592
644
|
|
|
593
645
|
#### deleteScenario
|
|
594
|
-
Delete a scenario and its associated secrets.
|
|
646
|
+
Delete a scenario and its associated secrets. Searches all projects to find the scenario.
|
|
595
647
|
- **Parameters**:
|
|
596
648
|
- `name` (required): Scenario name
|
|
597
|
-
- `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
|
|
598
649
|
- **Use case**: Clean up unused scenarios
|
|
599
650
|
- **Returns**: Success confirmation
|
|
600
651
|
|
|
601
652
|
#### exportScenarioAsCode ⭐ **NEW**
|
|
602
|
-
Export recorded scenario as executable test code for various frameworks. Automatically cleans unstable selectors (CSS Modules, styled-components, Emotion).
|
|
653
|
+
Export recorded scenario as executable test code for various frameworks. Automatically cleans unstable selectors (CSS Modules, styled-components, Emotion). Optionally generates Page Object class for the page. Can append tests to existing files. Searches all projects to find the scenario.
|
|
603
654
|
|
|
604
655
|
- **Parameters**:
|
|
605
656
|
- `scenarioName` (required): Name of scenario to export
|
|
606
657
|
- `language` (required): Target framework - `"playwright-typescript"`, `"playwright-python"`, `"selenium-python"`, `"selenium-java"`
|
|
607
658
|
- `cleanSelectors` (optional): Remove unstable CSS classes (default: true)
|
|
608
659
|
- `includeComments` (optional): Include descriptive comments (default: true)
|
|
609
|
-
- `
|
|
660
|
+
- `generatePageObject` (optional): Also generate Page Object class for the page (default: false)
|
|
661
|
+
- `pageObjectClassName` (optional): Custom Page Object class name (auto-generated if not provided)
|
|
662
|
+
- `appendToFile` (optional): Path to existing test file to append to (enables **append mode**) ⭐ **NEW**
|
|
663
|
+
- `testName` (optional): Override test name (default: from scenario name) ⭐ **NEW**
|
|
664
|
+
- `insertPosition` (optional): Where to insert: `'end'` (default), `'before'`, `'after'` ⭐ **NEW**
|
|
665
|
+
- `referenceTestName` (optional): Reference test name for before/after insertion ⭐ **NEW**
|
|
610
666
|
|
|
611
|
-
- **Use case**: Convert recorded scenarios into maintainable test code
|
|
667
|
+
- **Use case**: Convert recorded scenarios into maintainable test code with optional Page Objects, or append to existing test suites
|
|
612
668
|
|
|
613
|
-
- **Returns**:
|
|
669
|
+
- **Returns**:
|
|
670
|
+
- **Without `appendToFile`**: Test code as string (or JSON with Page Object)
|
|
671
|
+
- **With `appendToFile`**: JSON with `{success, mode: "append", file, testName, message}`
|
|
614
672
|
|
|
615
|
-
- **Example
|
|
673
|
+
- **Example 1 - Test only** (default behavior):
|
|
616
674
|
```javascript
|
|
617
675
|
// Export scenario as Playwright TypeScript
|
|
618
676
|
exportScenarioAsCode({
|
|
@@ -632,6 +690,69 @@ Export recorded scenario as executable test code for various frameworks. Automat
|
|
|
632
690
|
// });
|
|
633
691
|
```
|
|
634
692
|
|
|
693
|
+
- **Example 2 - Test + Page Object** ⭐ **NEW**:
|
|
694
|
+
```javascript
|
|
695
|
+
// Export with Page Object class
|
|
696
|
+
exportScenarioAsCode({
|
|
697
|
+
scenarioName: "login_test",
|
|
698
|
+
language: "playwright-typescript",
|
|
699
|
+
generatePageObject: true,
|
|
700
|
+
pageObjectClassName: "LoginPage"
|
|
701
|
+
})
|
|
702
|
+
|
|
703
|
+
// Returns JSON with both files:
|
|
704
|
+
{
|
|
705
|
+
"success": true,
|
|
706
|
+
"testCode": "import { test } from '@playwright/test';\nimport { LoginPage } from './LoginPage';\n\ntest('login_test', async ({ page }) => {\n const loginPage = new LoginPage(page);\n await loginPage.goto();\n await loginPage.fillEmailInput('user@test.com');\n await loginPage.clickLoginButton();\n});",
|
|
707
|
+
"pageObjectCode": "import { Page, Locator } from '@playwright/test';\n\nexport class LoginPage {\n readonly page: Page;\n readonly emailInput: Locator;\n readonly loginButton: Locator;\n \n constructor(page: Page) {\n this.page = page;\n this.emailInput = page.locator('#email');\n this.loginButton = page.locator('button[type=\"submit\"]');\n }\n \n async goto() {\n await this.page.goto('https://example.com/login');\n }\n \n async fillEmailInput(text: string) {\n await this.emailInput.fill(text);\n }\n \n async clickLoginButton() {\n await this.loginButton.click();\n }\n}",
|
|
708
|
+
"pageObjectClassName": "LoginPage",
|
|
709
|
+
"framework": "playwright-typescript",
|
|
710
|
+
"elementCount": 12
|
|
711
|
+
}
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
- **Example 3 - Append Mode** ⭐ **NEW**:
|
|
715
|
+
```javascript
|
|
716
|
+
// Append test to end of existing file
|
|
717
|
+
exportScenarioAsCode({
|
|
718
|
+
scenarioName: "new_feature_test",
|
|
719
|
+
language: "playwright-typescript",
|
|
720
|
+
appendToFile: "./tests/features.spec.ts"
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
// Returns:
|
|
724
|
+
{
|
|
725
|
+
"success": true,
|
|
726
|
+
"mode": "append",
|
|
727
|
+
"file": "./tests/features.spec.ts",
|
|
728
|
+
"testName": "new_feature_test",
|
|
729
|
+
"insertPosition": "end",
|
|
730
|
+
"message": "Test 'new_feature_test' successfully appended to ./tests/features.spec.ts"
|
|
731
|
+
}
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
- **Example 4 - Append with Position Control** ⭐ **NEW**:
|
|
735
|
+
```javascript
|
|
736
|
+
// Insert test before specific test
|
|
737
|
+
exportScenarioAsCode({
|
|
738
|
+
scenarioName: "setup_test",
|
|
739
|
+
language: "selenium-python",
|
|
740
|
+
appendToFile: "./tests/test_suite.py",
|
|
741
|
+
insertPosition: "before",
|
|
742
|
+
referenceTestName: "main_test",
|
|
743
|
+
testName: "test_setup_data" // Override name
|
|
744
|
+
})
|
|
745
|
+
|
|
746
|
+
// Or insert after specific test
|
|
747
|
+
exportScenarioAsCode({
|
|
748
|
+
scenarioName: "cleanup",
|
|
749
|
+
language: "playwright-python",
|
|
750
|
+
appendToFile: "./tests/test_flow.py",
|
|
751
|
+
insertPosition: "after",
|
|
752
|
+
referenceTestName: "test_main_flow"
|
|
753
|
+
})
|
|
754
|
+
```
|
|
755
|
+
|
|
635
756
|
- **Selector Cleaning**: Automatically removes unstable patterns:
|
|
636
757
|
- CSS Modules: `Button_primary__2x3yZ` → removed
|
|
637
758
|
- Styled-components: `sc-AbCdEf-0` → removed
|
|
@@ -639,6 +760,61 @@ Export recorded scenario as executable test code for various frameworks. Automat
|
|
|
639
760
|
- Hash suffixes: `component_a1b2c3d` → removed
|
|
640
761
|
- Prefers stable selectors: `data-testid`, `role`, `aria-label`, semantic attributes
|
|
641
762
|
|
|
763
|
+
#### generatePageObject ⭐ **NEW**
|
|
764
|
+
Generate Page Object Model (POM) class from current page structure. Analyzes page, extracts interactive elements, and generates framework-specific code with smart naming and helper methods.
|
|
765
|
+
|
|
766
|
+
- **Parameters**:
|
|
767
|
+
- `className` (optional): Page Object class name (auto-generated from page title/URL if not provided)
|
|
768
|
+
- `framework` (optional): Target framework - `"playwright-typescript"` (default), `"playwright-python"`, `"selenium-python"`, `"selenium-java"`
|
|
769
|
+
- `includeComments` (optional): Include descriptive comments (default: true)
|
|
770
|
+
- `groupElements` (optional): Group elements by page sections (default: true)
|
|
771
|
+
|
|
772
|
+
- **Features**:
|
|
773
|
+
- **Smart Selector Generation**: Prioritizes id > name > data-testid > unique class > CSS path
|
|
774
|
+
- **Intelligent Naming**: Auto-generates element names from labels, placeholders, text, attributes
|
|
775
|
+
- **Section Grouping**: Groups elements by semantic sections (header, nav, form, footer, main, etc.)
|
|
776
|
+
- **Helper Methods**: Auto-generates fill() and click() methods for common actions
|
|
777
|
+
- **Multi-Framework**: Supports Playwright (TS/Python) and Selenium (Python/Java)
|
|
778
|
+
|
|
779
|
+
- **Use cases**:
|
|
780
|
+
- Generate POM classes for test automation
|
|
781
|
+
- Create maintainable test structure from existing pages
|
|
782
|
+
- Bootstrap test framework setup quickly
|
|
783
|
+
- Extract page structure for documentation
|
|
784
|
+
|
|
785
|
+
- **Returns**: Page Object code with metadata (className, url, title, elementCount, framework)
|
|
786
|
+
|
|
787
|
+
- **Example**:
|
|
788
|
+
```javascript
|
|
789
|
+
// 1. Navigate to page
|
|
790
|
+
openBrowser({ url: "https://example.com/login" })
|
|
791
|
+
|
|
792
|
+
// 2. Generate Page Object
|
|
793
|
+
generatePageObject({
|
|
794
|
+
className: "LoginPage",
|
|
795
|
+
framework: "playwright-typescript",
|
|
796
|
+
includeComments: true,
|
|
797
|
+
groupElements: true
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
// Returns:
|
|
801
|
+
{
|
|
802
|
+
"success": true,
|
|
803
|
+
"className": "LoginPage",
|
|
804
|
+
"url": "https://example.com/login",
|
|
805
|
+
"title": "Login - Example Site",
|
|
806
|
+
"elementCount": 12,
|
|
807
|
+
"framework": "playwright-typescript",
|
|
808
|
+
"code": "import { Page, Locator } from '@playwright/test';\n\nexport class LoginPage {\n readonly page: Page;\n \n /** Email input field */\n readonly emailInput: Locator;\n /** Password input field */\n readonly passwordInput: Locator;\n /** Login button */\n readonly loginButton: Locator;\n \n constructor(page: Page) {\n this.page = page;\n this.emailInput = page.locator('#email');\n this.passwordInput = page.locator('#password');\n this.loginButton = page.locator('button[type=\"submit\"]');\n }\n \n async goto() {\n await this.page.goto('https://example.com/login');\n }\n \n async fillEmailInput(text: string) {\n await this.emailInput.fill(text);\n }\n \n async fillPasswordInput(text: string) {\n await this.passwordInput.fill(text);\n }\n \n async clickLoginButton() {\n await this.loginButton.click();\n }\n}"
|
|
809
|
+
}
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
- **Supported Frameworks**:
|
|
813
|
+
- `playwright-typescript`: Playwright with TypeScript (locators, async/await, Page Object pattern)
|
|
814
|
+
- `playwright-python`: Playwright with Python (sync API, snake_case naming)
|
|
815
|
+
- `selenium-python`: Selenium with Python (WebDriver, explicit waits, By locators)
|
|
816
|
+
- `selenium-java`: Selenium with Java (WebDriver, Page Factory compatible)
|
|
817
|
+
|
|
642
818
|
---
|
|
643
819
|
|
|
644
820
|
## Typical Workflow Example
|