@eddym06/custom-chrome-mcp 1.0.4 → 1.1.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/CONDITIONAL_DESCRIPTIONS.md +174 -0
- package/FUTURE_FEATURES.txt +1503 -0
- package/README.md +300 -3
- package/TEST_WORKFLOW.md +311 -0
- package/USAGE_GUIDE.md +393 -0
- package/demo_features.ts +115 -0
- package/dist/chrome-connector.d.ts +31 -4
- package/dist/chrome-connector.d.ts.map +1 -1
- package/dist/chrome-connector.js +402 -53
- package/dist/chrome-connector.js.map +1 -1
- package/dist/index.js +69 -12
- package/dist/index.js.map +1 -1
- package/dist/tests/execute-script-tests.d.ts +62 -0
- package/dist/tests/execute-script-tests.d.ts.map +1 -0
- package/dist/tests/execute-script-tests.js +280 -0
- package/dist/tests/execute-script-tests.js.map +1 -0
- package/dist/tests/run-execute-tests.d.ts +7 -0
- package/dist/tests/run-execute-tests.d.ts.map +1 -0
- package/dist/tests/run-execute-tests.js +88 -0
- package/dist/tests/run-execute-tests.js.map +1 -0
- package/dist/tools/advanced-network.backup.d.ts +245 -0
- package/dist/tools/advanced-network.backup.d.ts.map +1 -0
- package/dist/tools/advanced-network.backup.js +996 -0
- package/dist/tools/advanced-network.backup.js.map +1 -0
- package/dist/tools/advanced-network.d.ts +580 -0
- package/dist/tools/advanced-network.d.ts.map +1 -0
- package/dist/tools/advanced-network.js +1325 -0
- package/dist/tools/advanced-network.js.map +1 -0
- package/dist/tools/anti-detection.d.ts.map +1 -1
- package/dist/tools/anti-detection.js +13 -8
- package/dist/tools/anti-detection.js.map +1 -1
- package/dist/tools/capture.d.ts +15 -9
- package/dist/tools/capture.d.ts.map +1 -1
- package/dist/tools/capture.js +21 -12
- package/dist/tools/capture.js.map +1 -1
- package/dist/tools/interaction.d.ts +84 -10
- package/dist/tools/interaction.d.ts.map +1 -1
- package/dist/tools/interaction.js +88 -33
- package/dist/tools/interaction.js.map +1 -1
- package/dist/tools/navigation.d.ts.map +1 -1
- package/dist/tools/navigation.js +43 -21
- package/dist/tools/navigation.js.map +1 -1
- package/dist/tools/network-accessibility.d.ts +67 -0
- package/dist/tools/network-accessibility.d.ts.map +1 -0
- package/dist/tools/network-accessibility.js +367 -0
- package/dist/tools/network-accessibility.js.map +1 -0
- package/dist/tools/playwright-launcher.d.ts +1 -1
- package/dist/tools/playwright-launcher.js +6 -6
- package/dist/tools/playwright-launcher.js.map +1 -1
- package/dist/tools/service-worker.d.ts +2 -2
- package/dist/tools/service-worker.d.ts.map +1 -1
- package/dist/tools/service-worker.js +22 -12
- package/dist/tools/service-worker.js.map +1 -1
- package/dist/tools/session.d.ts.map +1 -1
- package/dist/tools/session.js +23 -14
- package/dist/tools/session.js.map +1 -1
- package/dist/tools/system.d.ts +2 -2
- package/dist/tools/system.d.ts.map +1 -1
- package/dist/tools/system.js +9 -5
- package/dist/tools/system.js.map +1 -1
- package/dist/utils/truncate.d.ts +29 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/truncate.js +46 -0
- package/dist/utils/truncate.js.map +1 -0
- package/dist/verify-tools.d.ts +7 -0
- package/dist/verify-tools.d.ts.map +1 -0
- package/dist/verify-tools.js +137 -0
- package/dist/verify-tools.js.map +1 -0
- package/package.json +3 -3
- package/recordings/demo_recording.har +3036 -0
- package/.npmrc.example +0 -2
- package/test-playwright.js +0 -57
package/USAGE_GUIDE.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# Custom Chrome MCP - AI Usage Guide
|
|
2
|
+
|
|
3
|
+
## 🎯 Philosophy: Always Analyze Before Acting
|
|
4
|
+
|
|
5
|
+
**GOLDEN RULE**: Never guess selectors or click blindly. Always analyze the page structure first.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📋 Common Workflows
|
|
10
|
+
|
|
11
|
+
### 1. Basic Web Navigation & Interaction
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
CORRECT WORKFLOW:
|
|
15
|
+
1️⃣ navigate - Go to the website
|
|
16
|
+
2️⃣ wait_for_load_state - Wait for page to fully load (use 'networkidle')
|
|
17
|
+
3️⃣ get_html or screenshot - ANALYZE the page structure
|
|
18
|
+
4️⃣ Identify correct CSS selectors from the HTML
|
|
19
|
+
5️⃣ click or type - Interact using verified selectors
|
|
20
|
+
|
|
21
|
+
EXAMPLE:
|
|
22
|
+
User: "Go to google.com and search for cats"
|
|
23
|
+
|
|
24
|
+
Correct sequence:
|
|
25
|
+
1. navigate("https://google.com")
|
|
26
|
+
2. wait_for_load_state("networkidle")
|
|
27
|
+
3. get_html() → See: <input name="q" class="gLFyf">
|
|
28
|
+
4. type("input[name='q']", "cats")
|
|
29
|
+
5. click("input[value='Google Search']")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**❌ WRONG**:
|
|
33
|
+
```
|
|
34
|
+
navigate → click(".search-button") // NO! You don't know if .search-button exists!
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**✅ RIGHT**:
|
|
38
|
+
```
|
|
39
|
+
navigate → get_html → find selector → click with verified selector
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### 2. Extension Debugging
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
WORKFLOW:
|
|
48
|
+
1️⃣ list_all_targets - Find all execution contexts
|
|
49
|
+
→ Filter by 'service_worker' to see extensions
|
|
50
|
+
2️⃣ Identify your extension - Look for title/url matching your extension
|
|
51
|
+
3️⃣ Get targetId - Copy the ID from the target
|
|
52
|
+
4️⃣ connect_to_target - Establish connection to that target
|
|
53
|
+
5️⃣ execute_in_target - Run code in the extension context
|
|
54
|
+
6️⃣ inspect_service_worker_logs - See console output (optional)
|
|
55
|
+
|
|
56
|
+
EXAMPLE:
|
|
57
|
+
User: "Debug my Chrome extension background script"
|
|
58
|
+
|
|
59
|
+
1. list_all_targets(filterType: 'service_worker')
|
|
60
|
+
→ Result: [{id: "ABC123", title: "My Extension", type: "service_worker"}]
|
|
61
|
+
2. connect_to_target("ABC123")
|
|
62
|
+
3. execute_in_target("ABC123", "return chrome.runtime.getManifest()")
|
|
63
|
+
4. inspect_service_worker_logs("ABC123") → See console.log output
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**⚠️ CRITICAL**:
|
|
67
|
+
- Use `execute_in_target` for extension contexts, NOT `execute_script`
|
|
68
|
+
- `execute_script` only works on page contexts (tabs)
|
|
69
|
+
- Extension service workers are separate execution contexts
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### 3. Network Traffic Interception
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
WORKFLOW FOR INSPECTING REQUESTS:
|
|
77
|
+
1️⃣ enable_response_interception - Start capturing responses
|
|
78
|
+
→ Or use enable_network_interception for simpler request-only capture
|
|
79
|
+
2️⃣ navigate - Trigger the network request
|
|
80
|
+
3️⃣ list_intercepted_responses - See what was captured
|
|
81
|
+
4️⃣ modify_intercepted_response - Change response if needed (optional)
|
|
82
|
+
5️⃣ disable_response_interception - Stop capturing
|
|
83
|
+
|
|
84
|
+
WORKFLOW FOR MOCKING ENDPOINTS:
|
|
85
|
+
1️⃣ create_mock_endpoint - Set up fake API response
|
|
86
|
+
→ Pattern: "*api.example.com/users*"
|
|
87
|
+
→ Response: {"users": [...]}
|
|
88
|
+
2️⃣ navigate - Page will hit mock instead of real API
|
|
89
|
+
3️⃣ Test your frontend with fake data
|
|
90
|
+
4️⃣ delete_mock_endpoint - Clean up
|
|
91
|
+
|
|
92
|
+
⚠️ CONFLICTS:
|
|
93
|
+
- Cannot use response_interception AND mock_endpoint simultaneously
|
|
94
|
+
- Choose one: interception (for analysis) OR mocking (for testing)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### 4. Form Filling & Submission
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
WORKFLOW:
|
|
103
|
+
1️⃣ navigate to form page
|
|
104
|
+
2️⃣ wait_for_load_state('networkidle')
|
|
105
|
+
3️⃣ get_html → Analyze form structure
|
|
106
|
+
4️⃣ Identify input selectors:
|
|
107
|
+
- input#email
|
|
108
|
+
- input[name="password"]
|
|
109
|
+
- button[type="submit"]
|
|
110
|
+
5️⃣ type into each field with verified selectors
|
|
111
|
+
6️⃣ click submit button with verified selector
|
|
112
|
+
|
|
113
|
+
EXAMPLE:
|
|
114
|
+
1. navigate("https://example.com/login")
|
|
115
|
+
2. wait_for_load_state("networkidle")
|
|
116
|
+
3. get_html() → See:
|
|
117
|
+
<input id="email" type="email">
|
|
118
|
+
<input id="password" type="password">
|
|
119
|
+
<button type="submit">Login</button>
|
|
120
|
+
4. type("#email", "user@example.com")
|
|
121
|
+
5. type("#password", "mypassword")
|
|
122
|
+
6. click("button[type='submit']")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### 5. Data Extraction / Web Scraping
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
WORKFLOW:
|
|
131
|
+
1️⃣ navigate to target page
|
|
132
|
+
2️⃣ wait_for_load_state('networkidle') - Ensure dynamic content loaded
|
|
133
|
+
3️⃣ get_html → Get full page structure
|
|
134
|
+
4️⃣ execute_script with complex query:
|
|
135
|
+
return Array.from(document.querySelectorAll('.item'))
|
|
136
|
+
.map(el => ({
|
|
137
|
+
title: el.querySelector('.title').textContent,
|
|
138
|
+
price: el.querySelector('.price').textContent
|
|
139
|
+
}))
|
|
140
|
+
|
|
141
|
+
WHEN TO USE execute_script:
|
|
142
|
+
✅ Complex data extraction (querySelectorAll + map/filter)
|
|
143
|
+
✅ Accessing window variables (return window.appConfig)
|
|
144
|
+
✅ Triggering custom events
|
|
145
|
+
✅ Advanced DOM manipulation
|
|
146
|
+
|
|
147
|
+
WHEN NOT TO USE execute_script:
|
|
148
|
+
❌ Simple clicks (use click tool instead)
|
|
149
|
+
❌ Simple typing (use type tool instead)
|
|
150
|
+
❌ Getting HTML (use get_html instead)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### 6. Visual Analysis & Debugging
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
WORKFLOW:
|
|
159
|
+
1️⃣ navigate
|
|
160
|
+
2️⃣ screenshot - Take visual snapshot
|
|
161
|
+
3️⃣ Analyze screenshot visually
|
|
162
|
+
4️⃣ Identify elements by their visual position
|
|
163
|
+
5️⃣ get_html to find selectors for those elements
|
|
164
|
+
6️⃣ Interact with verified selectors
|
|
165
|
+
|
|
166
|
+
WHEN TO USE SCREENSHOT:
|
|
167
|
+
✅ Page layout is complex
|
|
168
|
+
✅ Need visual confirmation (before/after actions)
|
|
169
|
+
✅ Debugging UI issues
|
|
170
|
+
✅ HTML is too large to analyze
|
|
171
|
+
|
|
172
|
+
WHEN TO USE GET_HTML:
|
|
173
|
+
✅ Need exact selectors
|
|
174
|
+
✅ Scraping structured data
|
|
175
|
+
✅ Analyzing page structure
|
|
176
|
+
✅ Finding element attributes/IDs/classes
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### 7. HAR Recording (Performance Analysis)
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
WORKFLOW:
|
|
185
|
+
1️⃣ start_har_recording - Begin capturing all network traffic
|
|
186
|
+
2️⃣ navigate or perform actions - Trigger network requests
|
|
187
|
+
3️⃣ stop_har_recording - Stop capture
|
|
188
|
+
4️⃣ get_har_entries - Analyze requests/responses
|
|
189
|
+
→ Or export_har_file - Save for external analysis
|
|
190
|
+
|
|
191
|
+
USE CASES:
|
|
192
|
+
- Performance testing (find slow requests)
|
|
193
|
+
- Network debugging (see all API calls)
|
|
194
|
+
- Security analysis (inspect headers/cookies)
|
|
195
|
+
- Regression testing (compare HAR files)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### 8. CSS/JS Injection (Persistent Modifications)
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
WORKFLOW FOR STYLING:
|
|
204
|
+
1️⃣ inject_css_global - Add persistent styles
|
|
205
|
+
→ CSS applies to all new pages automatically
|
|
206
|
+
2️⃣ navigate to any page
|
|
207
|
+
3️⃣ CSS is automatically injected
|
|
208
|
+
4️⃣ clear_all_injections - Remove when done
|
|
209
|
+
|
|
210
|
+
WORKFLOW FOR BEHAVIOR:
|
|
211
|
+
1️⃣ inject_js_global - Add persistent JavaScript
|
|
212
|
+
→ Runs BEFORE page scripts
|
|
213
|
+
→ Can intercept functions
|
|
214
|
+
2️⃣ navigate to any page
|
|
215
|
+
3️⃣ Your code runs automatically
|
|
216
|
+
4️⃣ clear_all_injections - Remove when done
|
|
217
|
+
|
|
218
|
+
USE CASES:
|
|
219
|
+
- UI customization (dark mode, hide elements)
|
|
220
|
+
- Function interception (override fetch, console.log)
|
|
221
|
+
- Auto-fill forms
|
|
222
|
+
- Add custom buttons/features
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 🚫 Common Mistakes to Avoid
|
|
228
|
+
|
|
229
|
+
### ❌ Mistake #1: Guessing Selectors
|
|
230
|
+
```javascript
|
|
231
|
+
// WRONG
|
|
232
|
+
navigate("https://example.com")
|
|
233
|
+
click(".login-button") // What if .login-button doesn't exist?
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
// RIGHT
|
|
238
|
+
navigate("https://example.com")
|
|
239
|
+
get_html() // See: <button id="signin">Login</button>
|
|
240
|
+
click("#signin") // Use verified selector
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### ❌ Mistake #2: Not Waiting for Page Load
|
|
246
|
+
```javascript
|
|
247
|
+
// WRONG
|
|
248
|
+
navigate("https://example.com")
|
|
249
|
+
click("#button") // Button might not exist yet!
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
// RIGHT
|
|
254
|
+
navigate("https://example.com")
|
|
255
|
+
wait_for_load_state("networkidle") // Wait for page to finish loading
|
|
256
|
+
get_html() // Now analyze
|
|
257
|
+
click("#button") // Now interact
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### ❌ Mistake #3: Using Wrong Tool for Context
|
|
263
|
+
```javascript
|
|
264
|
+
// WRONG - Trying to debug extension with execute_script
|
|
265
|
+
list_all_targets() // Find extension targetId: "ABC123"
|
|
266
|
+
execute_script("chrome.runtime.getManifest()") // ❌ Won't work!
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
// RIGHT - Use execute_in_target for extensions
|
|
271
|
+
list_all_targets() // Find extension: "ABC123"
|
|
272
|
+
connect_to_target("ABC123")
|
|
273
|
+
execute_in_target("ABC123", "return chrome.runtime.getManifest()") // ✅ Works!
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### ❌ Mistake #4: Over-using execute_script
|
|
279
|
+
```javascript
|
|
280
|
+
// WRONG - Using execute_script for simple actions
|
|
281
|
+
execute_script("document.querySelector('#button').click()")
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// RIGHT - Use dedicated tools
|
|
286
|
+
get_html() // Verify selector exists
|
|
287
|
+
click("#button") // Simpler, more reliable
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
### ❌ Mistake #5: Not Analyzing Before Clicking
|
|
293
|
+
```javascript
|
|
294
|
+
// WRONG
|
|
295
|
+
User: "Click the submit button on example.com"
|
|
296
|
+
navigate("https://example.com")
|
|
297
|
+
click("button") // Which button? There might be many!
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// RIGHT
|
|
302
|
+
navigate("https://example.com")
|
|
303
|
+
get_html() // Analyze: <button class="submit-btn">Submit</button>
|
|
304
|
+
click(".submit-btn") // Use specific selector
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 🎓 Decision Trees
|
|
310
|
+
|
|
311
|
+
### "Should I use screenshot or get_html?"
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
START: Need to analyze page
|
|
315
|
+
├─ Need exact selectors/IDs/classes? → get_html
|
|
316
|
+
├─ Need visual layout/position? → screenshot
|
|
317
|
+
├─ HTML is very large (>50KB)? → screenshot first, then get_html if needed
|
|
318
|
+
└─ Need both? → screenshot (visual), then get_html (selectors)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### "Should I use execute_script or dedicated tools?"
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
START: Need to interact with page
|
|
325
|
+
├─ Simple click? → click tool
|
|
326
|
+
├─ Simple type? → type tool
|
|
327
|
+
├─ Get HTML? → get_html tool
|
|
328
|
+
├─ Complex query (querySelectorAll + map)? → execute_script
|
|
329
|
+
├─ Access window variables? → execute_script
|
|
330
|
+
└─ Trigger custom events? → execute_script
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### "Which interception tool should I use?"
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
START: Need to intercept network traffic
|
|
337
|
+
├─ Need to ANALYZE real traffic? → enable_response_interception
|
|
338
|
+
├─ Need to MOCK/FAKE responses? → create_mock_endpoint
|
|
339
|
+
├─ Need WebSocket traffic? → enable_websocket_interception
|
|
340
|
+
├─ Need HAR file for analysis? → start_har_recording
|
|
341
|
+
└─ Just need simple request logging? → enable_network_interception
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## 🔧 Troubleshooting
|
|
347
|
+
|
|
348
|
+
### Problem: "Element not found" errors
|
|
349
|
+
**Solution**: Always use get_html BEFORE clicking to verify selector exists
|
|
350
|
+
|
|
351
|
+
### Problem: "Timeout" errors
|
|
352
|
+
**Solution**: Use wait_for_load_state("networkidle") after navigation
|
|
353
|
+
|
|
354
|
+
### Problem: "Cannot read property of undefined" in extension
|
|
355
|
+
**Solution**: Verify you're using execute_in_target, not execute_script
|
|
356
|
+
|
|
357
|
+
### Problem: Mock endpoint not working
|
|
358
|
+
**Solution**: Check if response_interception is active (conflicts with mocks)
|
|
359
|
+
|
|
360
|
+
### Problem: Injection not persisting
|
|
361
|
+
**Solution**: Use inject_css_global/inject_js_global, not execute_script
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## 💡 Pro Tips
|
|
366
|
+
|
|
367
|
+
1. **Always analyze before acting** - get_html or screenshot first
|
|
368
|
+
2. **Use specific selectors** - ID > class > tag name
|
|
369
|
+
3. **Wait for page load** - Use wait_for_load_state("networkidle")
|
|
370
|
+
4. **Test selectors in browser console** - Before using them in tools
|
|
371
|
+
5. **Use timeouts wisely** - Increase for slow pages, decrease for fast ones
|
|
372
|
+
6. **Clean up after yourself** - Clear injections, disable interceptors
|
|
373
|
+
7. **Read tool descriptions** - They contain workflows and examples
|
|
374
|
+
8. **Combine tools logically** - navigate → wait → analyze → interact
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 📚 Quick Reference
|
|
379
|
+
|
|
380
|
+
| Task | Tools | Workflow |
|
|
381
|
+
|------|-------|----------|
|
|
382
|
+
| Navigate web | navigate → wait_for_load_state → get_html → click/type | Analysis-first approach |
|
|
383
|
+
| Debug extension | list_all_targets → connect_to_target → execute_in_target | Extension-specific execution |
|
|
384
|
+
| Intercept traffic | enable_response_interception → navigate → list_intercepted_responses | Live traffic capture |
|
|
385
|
+
| Mock APIs | create_mock_endpoint → navigate | Testing without backend |
|
|
386
|
+
| Scrape data | navigate → wait → get_html → execute_script (complex queries) | Structured extraction |
|
|
387
|
+
| Visual debug | navigate → screenshot → analyze → get_html → interact | Visual-first analysis |
|
|
388
|
+
| Performance | start_har_recording → actions → stop → get_har_entries | Full network profile |
|
|
389
|
+
| Inject styles | inject_css_global → navigate → clear_all_injections | Persistent modifications |
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
**Remember**: The AI should read page structure BEFORE attempting any interaction. Never guess - always verify!
|
package/demo_features.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
import { ChromeConnector } from './src/chrome-connector.js';
|
|
3
|
+
import { createAdvancedNetworkTools } from './src/tools/advanced-network.js';
|
|
4
|
+
import { createPlaywrightLauncherTools } from './src/tools/playwright-launcher.js';
|
|
5
|
+
import { createNavigationTools } from './src/tools/navigation.js';
|
|
6
|
+
|
|
7
|
+
async function runDemo() {
|
|
8
|
+
console.log('🚀 Iniciando Demo de Herramientas Avanzadas...');
|
|
9
|
+
|
|
10
|
+
// 1. Inicializar Connector
|
|
11
|
+
const connector = new ChromeConnector(9222);
|
|
12
|
+
|
|
13
|
+
// 2. Obtener manejadores de herramientas
|
|
14
|
+
const launcherTools = createPlaywrightLauncherTools(connector);
|
|
15
|
+
const networkTools = createAdvancedNetworkTools(connector);
|
|
16
|
+
const navTools = createNavigationTools(connector);
|
|
17
|
+
|
|
18
|
+
const getHandler = (tools: any[], name: string) => tools.find(t => t.name === name)?.handler;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// 3. Lanzar Chrome
|
|
22
|
+
console.log('\n🌐 Lanzando Chrome...');
|
|
23
|
+
const launchHandler = getHandler(launcherTools, 'launch_chrome_with_profile');
|
|
24
|
+
if (launchHandler) {
|
|
25
|
+
await launchHandler({ profileDirectory: 'Default' });
|
|
26
|
+
console.log('✅ Chrome lanzado correctamente');
|
|
27
|
+
} else {
|
|
28
|
+
// Si falla el launch (quizas ya esta abierto), intentamos conectar
|
|
29
|
+
console.log('⚠️ No se pudo lanzar (quizás ya abierto), intentando conectar...');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Esperar un momento para la conexión
|
|
33
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
34
|
+
|
|
35
|
+
// 4. Configurar Mock de API
|
|
36
|
+
console.log('\n📦 Configurando Mock de API...');
|
|
37
|
+
const createMock = getHandler(networkTools, 'create_mock_endpoint');
|
|
38
|
+
await createMock({
|
|
39
|
+
urlPattern: '*api.example.com/users*',
|
|
40
|
+
responseBody: JSON.stringify([{ id: 1, name: 'Usuario Demo', role: 'Tester' }]),
|
|
41
|
+
statusCode: 200,
|
|
42
|
+
headers: { 'Content-Type': 'application/json' },
|
|
43
|
+
latency: 1000,
|
|
44
|
+
timeoutMs: 10000
|
|
45
|
+
});
|
|
46
|
+
console.log('✅ Mock registrado para *api.example.com/users*');
|
|
47
|
+
|
|
48
|
+
// 5. Inyectar CSS Global
|
|
49
|
+
console.log('\n🎨 Inyectando CSS Global...');
|
|
50
|
+
const injectCss = getHandler(networkTools, 'inject_css_global');
|
|
51
|
+
await injectCss({
|
|
52
|
+
css: 'body { background-color: #f0f8ff !important; border: 5px solid red !important; }',
|
|
53
|
+
name: 'demo-theme',
|
|
54
|
+
timeoutMs: 5000
|
|
55
|
+
});
|
|
56
|
+
console.log('✅ CSS inyectado (Fondo azul claro, borde rojo)');
|
|
57
|
+
|
|
58
|
+
// 6. Iniciar Grabación HAR
|
|
59
|
+
console.log('\n📹 Iniciando grabación HAR...');
|
|
60
|
+
const startHar = getHandler(networkTools, 'start_har_recording');
|
|
61
|
+
await startHar({});
|
|
62
|
+
console.log('✅ Grabación HAR iniciada');
|
|
63
|
+
|
|
64
|
+
// 7. Navegar a una página para probar
|
|
65
|
+
console.log('\nse Navegando a example.com...');
|
|
66
|
+
const navigate = getHandler(navTools, 'navigate');
|
|
67
|
+
await navigate({ url: 'https://example.com' });
|
|
68
|
+
console.log('✅ Navegación completada');
|
|
69
|
+
|
|
70
|
+
// 8. Simular "fetch" en la consola para probar el Mock
|
|
71
|
+
console.log('\n🧪 Probando Mock (Simulando fetch)...');
|
|
72
|
+
// Esto es un truco: inyectamos JS que hace un fetch
|
|
73
|
+
const injectJs = getHandler(networkTools, 'inject_js_global');
|
|
74
|
+
await injectJs({
|
|
75
|
+
javascript: `
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
console.log("Haciendo fetch a api.example.com...");
|
|
78
|
+
fetch("https://api.example.com/users")
|
|
79
|
+
.then(r => r.json())
|
|
80
|
+
.then(d => {
|
|
81
|
+
console.log("Respuesta Mock recibida:", d);
|
|
82
|
+
const div = document.createElement("div");
|
|
83
|
+
div.style = "position: fixed; top: 10px; right: 10px; background: gold; padding: 20px; z-index: 9999;";
|
|
84
|
+
div.innerText = "MOCK DATA: " + JSON.stringify(d);
|
|
85
|
+
document.body.appendChild(div);
|
|
86
|
+
});
|
|
87
|
+
}, 1000);
|
|
88
|
+
`,
|
|
89
|
+
name: 'mock-test',
|
|
90
|
+
runImmediately: true
|
|
91
|
+
});
|
|
92
|
+
console.log('✅ JS para probar Mock inyectado');
|
|
93
|
+
|
|
94
|
+
// Esperar para que ocurra el tráfico
|
|
95
|
+
console.log('⏳ Esperando 5 segundos para capturar tráfico...');
|
|
96
|
+
await new Promise(r => setTimeout(r, 5000));
|
|
97
|
+
|
|
98
|
+
// 9. Exportar HAR
|
|
99
|
+
console.log('\n💾 Exportando archivo HAR...');
|
|
100
|
+
const exportHar = getHandler(networkTools, 'export_har_file');
|
|
101
|
+
const harResult = await exportHar({
|
|
102
|
+
filename: 'demo_recording.har',
|
|
103
|
+
outputDir: './recordings',
|
|
104
|
+
timeoutMs: 30000
|
|
105
|
+
});
|
|
106
|
+
console.log(`✅ HAR exportado: ${JSON.stringify(harResult)}`);
|
|
107
|
+
|
|
108
|
+
console.log('\n🎉 DEMO COMPLETADA EXITOSAMENTE');
|
|
109
|
+
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('❌ Error durante la demo:', error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
runDemo();
|
|
@@ -28,6 +28,7 @@ export declare class ChromeConnector {
|
|
|
28
28
|
private currentTabId;
|
|
29
29
|
private browserContext;
|
|
30
30
|
private chromeProcess;
|
|
31
|
+
private persistentClients;
|
|
31
32
|
constructor(port?: number);
|
|
32
33
|
/**
|
|
33
34
|
* Get platform-specific Chrome paths
|
|
@@ -44,6 +45,10 @@ export declare class ChromeConnector {
|
|
|
44
45
|
* This is more robust for persistent profiles than Playwright's launcher
|
|
45
46
|
*/
|
|
46
47
|
launchWithProfile(options?: LaunchOptions): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Handle Chrome process death - cleanup internal state
|
|
50
|
+
*/
|
|
51
|
+
private handleProcessDeath;
|
|
47
52
|
/**
|
|
48
53
|
* Disconnect from Chrome and close Playwright browser
|
|
49
54
|
*/
|
|
@@ -68,6 +73,15 @@ export declare class ChromeConnector {
|
|
|
68
73
|
* Check if connected
|
|
69
74
|
*/
|
|
70
75
|
isConnected(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Get the CDP port number
|
|
78
|
+
*/
|
|
79
|
+
getPort(): number;
|
|
80
|
+
/**
|
|
81
|
+
* Verify Chrome is alive and connected to port 9222
|
|
82
|
+
* Throws error if connection is dead
|
|
83
|
+
*/
|
|
84
|
+
verifyConnection(): Promise<void>;
|
|
71
85
|
/**
|
|
72
86
|
* List all open tabs and targets (including service workers)
|
|
73
87
|
*/
|
|
@@ -100,10 +114,6 @@ export declare class ChromeConnector {
|
|
|
100
114
|
* Get Chrome version info
|
|
101
115
|
*/
|
|
102
116
|
getVersion(): Promise<any>;
|
|
103
|
-
/**
|
|
104
|
-
* Get current port
|
|
105
|
-
*/
|
|
106
|
-
getPort(): number;
|
|
107
117
|
/**
|
|
108
118
|
* Set current tab
|
|
109
119
|
*/
|
|
@@ -112,5 +122,22 @@ export declare class ChromeConnector {
|
|
|
112
122
|
* Get current tab ID
|
|
113
123
|
*/
|
|
114
124
|
getCurrentTabId(): string | null;
|
|
125
|
+
/**
|
|
126
|
+
* Get or create a persistent client for interceptors
|
|
127
|
+
* These clients stay alive for the entire session
|
|
128
|
+
*/
|
|
129
|
+
getPersistentClient(tabId?: string): Promise<any>;
|
|
130
|
+
/**
|
|
131
|
+
* Close persistent client (used when disabling interceptors)
|
|
132
|
+
*/
|
|
133
|
+
closePersistentClient(tabId?: string): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Helper to inject a visual connection status toast into the page
|
|
136
|
+
*/
|
|
137
|
+
injectConnectionStatus(targetId: string): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Helper to ensure a specific target's window is visible and restored
|
|
140
|
+
*/
|
|
141
|
+
ensureWindowVisible(targetId: string): Promise<void>;
|
|
115
142
|
}
|
|
116
143
|
//# sourceMappingURL=chrome-connector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chrome-connector.d.ts","sourceRoot":"","sources":["../src/chrome-connector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AASzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAA6B;
|
|
1
|
+
{"version":3,"file":"chrome-connector.d.ts","sourceRoot":"","sources":["../src/chrome-connector.ts"],"names":[],"mappings":"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"}
|