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 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
- **Directory Management**: All recorder tools support an optional `directory` parameter to specify where scenarios are stored.
509
+ **URL-Based Storage (v2.1+)**: Scenarios are automatically organized by website domain in `~/.config/chrometools-mcp/projects/{domain}/scenarios/`.
510
510
 
511
- **Default Location**: `~/.config/chrometools-mcp` (consistent, predictable location in user's home folder)
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
- You can override the default by:
514
- - Passing explicit `directory` parameter to any recorder tool
515
- - Setting environment variable: `CLAUDE_PROJECT_DIR` or `PROJECT_DIR`
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
- Once a directory is set (explicitly or via environment), it's remembered for the entire MCP server session.
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
- // Use default location (recommended)
522
- enableRecorder() // Saves to ~/.config/chrometools-mcp
523
-
524
- // Or specify explicitly
525
- enableRecorder({ directory: "/path/to/project" })
526
-
527
- // Later calls reuse the same directory automatically
528
- executeScenario({ name: "test" }) // Uses remembered directory
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
- - `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
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
- - `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
572
- - **Use case**: Browse recorded scenarios
573
- - **Returns**: Array of scenarios with names, descriptions, tags, timestamps
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
- - `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
581
- - **Use case**: Find specific scenarios
582
- - **Returns**: Matching scenarios
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
- - `directory` (optional): Directory where scenarios are stored (defaults to `~/.config/chrometools-mcp`)
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**: Generated test code as string
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