cursorflow 2.2.5__py3-none-any.whl → 2.2.6__py3-none-any.whl
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.
- cursorflow/__init__.py +1 -1
- cursorflow/cli.py +2 -2
- cursorflow/core/browser_controller.py +6 -4
- cursorflow/core/cursorflow.py +15 -1
- cursorflow/core/log_collector.py +5 -1
- cursorflow/log_sources/local_file.py +4 -0
- cursorflow/log_sources/ssh_remote.py +4 -0
- cursorflow/rules/cursorflow-usage.mdc +54 -59
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/METADATA +2 -2
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/RECORD +14 -14
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/WHEEL +0 -0
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/entry_points.txt +0 -0
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/licenses/LICENSE +0 -0
- {cursorflow-2.2.5.dist-info → cursorflow-2.2.6.dist-info}/top_level.txt +0 -0
cursorflow/__init__.py
CHANGED
cursorflow/cli.py
CHANGED
@@ -194,7 +194,7 @@ def test(base_url, path, actions, output, logs, config, verbose, headless, timeo
|
|
194
194
|
# Simple path navigation
|
195
195
|
test_actions = [
|
196
196
|
{"navigate": path},
|
197
|
-
{"
|
197
|
+
{"wait_for_selector": "body"},
|
198
198
|
{"screenshot": "page_loaded"}
|
199
199
|
]
|
200
200
|
console.print(f"📋 Using simple path navigation to [cyan]{path}[/cyan]")
|
@@ -202,7 +202,7 @@ def test(base_url, path, actions, output, logs, config, verbose, headless, timeo
|
|
202
202
|
# Default actions - just navigate to root and screenshot
|
203
203
|
test_actions = [
|
204
204
|
{"navigate": "/"},
|
205
|
-
{"
|
205
|
+
{"wait_for_selector": "body"},
|
206
206
|
{"screenshot": "baseline"}
|
207
207
|
]
|
208
208
|
console.print(f"📋 Using default actions (navigate to root + screenshot)")
|
@@ -1148,13 +1148,15 @@ class BrowserController:
|
|
1148
1148
|
# v2.0 Enhancement: Resource loading analysis
|
1149
1149
|
resource_analysis = await self._capture_resource_loading_analysis()
|
1150
1150
|
|
1151
|
-
# v2.
|
1152
|
-
|
1151
|
+
# v2.2 Enhancement: Enhanced context capture
|
1152
|
+
javascript_context = await self._capture_javascript_context()
|
1153
|
+
storage_state = await self._capture_storage_state() # This also serves as storage_analysis
|
1154
|
+
form_state = await self._capture_form_state()
|
1153
1155
|
|
1154
1156
|
# Create enhanced analysis summary
|
1155
1157
|
analysis_summary = self._create_analysis_summary(
|
1156
1158
|
dom_analysis, network_data, console_data, performance_data,
|
1157
|
-
font_analysis, animation_analysis, resource_analysis,
|
1159
|
+
font_analysis, animation_analysis, resource_analysis, storage_state
|
1158
1160
|
)
|
1159
1161
|
|
1160
1162
|
return {
|
@@ -1171,7 +1173,7 @@ class BrowserController:
|
|
1171
1173
|
"font_analysis": font_analysis,
|
1172
1174
|
"animation_analysis": animation_analysis,
|
1173
1175
|
"resource_analysis": resource_analysis,
|
1174
|
-
"storage_analysis":
|
1176
|
+
"storage_analysis": storage_state, # v2.2 uses storage_state
|
1175
1177
|
|
1176
1178
|
"analysis_summary": analysis_summary,
|
1177
1179
|
"capture_timestamp": time.time(),
|
cursorflow/core/cursorflow.py
CHANGED
@@ -143,6 +143,19 @@ class CursorFlow:
|
|
143
143
|
)
|
144
144
|
summary = self.correlator.get_summary(organized_timeline)
|
145
145
|
|
146
|
+
# Capture comprehensive data if screenshots were taken
|
147
|
+
comprehensive_data = {}
|
148
|
+
if self.artifacts.get("screenshots"):
|
149
|
+
# Get comprehensive data from last screenshot
|
150
|
+
last_screenshot = self.artifacts["screenshots"][-1]
|
151
|
+
if "comprehensive_data_path" in last_screenshot:
|
152
|
+
import json
|
153
|
+
try:
|
154
|
+
with open(last_screenshot["comprehensive_data_path"], 'r') as f:
|
155
|
+
comprehensive_data = json.load(f)
|
156
|
+
except Exception as e:
|
157
|
+
self.logger.warning(f"Could not load comprehensive data: {e}")
|
158
|
+
|
146
159
|
# Package results
|
147
160
|
results = {
|
148
161
|
"success": success,
|
@@ -152,7 +165,8 @@ class CursorFlow:
|
|
152
165
|
"browser_events": self.timeline, # Raw browser events
|
153
166
|
"server_logs": server_logs, # Raw server logs
|
154
167
|
"summary": summary, # Basic counts
|
155
|
-
"artifacts": self.artifacts
|
168
|
+
"artifacts": self.artifacts,
|
169
|
+
"comprehensive_data": comprehensive_data # Complete page intelligence
|
156
170
|
}
|
157
171
|
|
158
172
|
self.logger.info(f"Test execution completed: {success}, timeline events: {len(organized_timeline)}")
|
cursorflow/core/log_collector.py
CHANGED
@@ -164,7 +164,11 @@ class LogCollector:
|
|
164
164
|
async def _monitor_source(self, source):
|
165
165
|
"""Monitor a single log source"""
|
166
166
|
try:
|
167
|
-
|
167
|
+
# connect() returns bool, not awaitable - just call it
|
168
|
+
connected = await source.connect()
|
169
|
+
if not connected:
|
170
|
+
self.logger.warning(f"Log source {source} failed to connect")
|
171
|
+
return
|
168
172
|
|
169
173
|
while self.monitoring:
|
170
174
|
try:
|
@@ -168,6 +168,10 @@ class LocalFileLogSource:
|
|
168
168
|
"""Connect to log sources - compatibility method for log_collector"""
|
169
169
|
return await self.start_monitoring()
|
170
170
|
|
171
|
+
async def disconnect(self):
|
172
|
+
"""Disconnect from log sources - compatibility method for log_collector"""
|
173
|
+
return await self.stop_monitoring()
|
174
|
+
|
171
175
|
async def get_new_entries(self) -> List[Dict]:
|
172
176
|
"""
|
173
177
|
Get new log entries since last call (required interface method)
|
@@ -165,6 +165,10 @@ class SSHRemoteLogSource:
|
|
165
165
|
"""Connect to SSH log sources - compatibility method for log_collector"""
|
166
166
|
return await self.start_monitoring()
|
167
167
|
|
168
|
+
async def disconnect(self):
|
169
|
+
"""Disconnect from SSH log sources - compatibility method for log_collector"""
|
170
|
+
return await self.stop_monitoring()
|
171
|
+
|
168
172
|
async def get_new_entries(self) -> List[Dict]:
|
169
173
|
"""
|
170
174
|
Get new log entries since last call (required interface method)
|
@@ -225,74 +225,69 @@ print(f"Performance metrics: {screenshot_data['performance_data']}")
|
|
225
225
|
# Playwright trace available at: .cursorflow/artifacts/traces/session.zip
|
226
226
|
```
|
227
227
|
|
228
|
-
## 🚀 **CursorFlow CLI Usage
|
228
|
+
## 🚀 **CursorFlow CLI Usage**
|
229
229
|
|
230
230
|
### **Basic Testing:**
|
231
231
|
```bash
|
232
|
-
#
|
233
|
-
cursorflow test --base-url http://localhost:3000 --path
|
234
|
-
|
235
|
-
#
|
236
|
-
cursorflow test \
|
237
|
-
--
|
238
|
-
--
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
"options": {
|
255
|
-
"clip": {"selector": "#header"},
|
256
|
-
"mask": [".user-email", ".sensitive-data"],
|
257
|
-
"full_page": false,
|
258
|
-
"quality": 90
|
259
|
-
}
|
260
|
-
}}
|
261
|
-
]'
|
232
|
+
# Simple page capture
|
233
|
+
cursorflow test --base-url http://localhost:3000 --path /dashboard
|
234
|
+
|
235
|
+
# Inline actions (no JSON needed)
|
236
|
+
cursorflow test --base-url http://localhost:3000 \
|
237
|
+
--path /messages \
|
238
|
+
--wait-for ".message-item" \
|
239
|
+
--wait 2 \
|
240
|
+
--hover ".message-item:first-child" \
|
241
|
+
--click ".message-item:first-child" \
|
242
|
+
--screenshot "result" \
|
243
|
+
--show-console \
|
244
|
+
--open-trace
|
245
|
+
|
246
|
+
# Custom actions with JSON
|
247
|
+
cursorflow test --base-url http://localhost:3000 --actions '[
|
248
|
+
{"navigate": "/page"},
|
249
|
+
{"hover": ".menu"},
|
250
|
+
{"click": "#button"},
|
251
|
+
{"screenshot": "result"}
|
252
|
+
]'
|
253
|
+
```
|
262
254
|
|
263
|
-
|
264
|
-
|
265
|
-
#
|
266
|
-
# -
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
270
|
-
#
|
255
|
+
### **All CLI Commands:**
|
256
|
+
```bash
|
257
|
+
cursorflow test # Test UI with comprehensive data capture
|
258
|
+
cursorflow rerun # Re-run last test
|
259
|
+
cursorflow inspect # Quick element inspection
|
260
|
+
cursorflow count # Count matching elements
|
261
|
+
cursorflow timeline # View event timeline
|
262
|
+
cursorflow sessions # Manage saved sessions
|
263
|
+
cursorflow cleanup # Clean artifacts (use --yes for autonomous)
|
264
|
+
cursorflow install-rules # Install Cursor rules (use --yes)
|
271
265
|
```
|
272
266
|
|
273
|
-
### **
|
267
|
+
### **Inline Action Flags:**
|
274
268
|
```bash
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
269
|
+
--click ".selector" # Click element
|
270
|
+
--hover ".selector" # Hover element
|
271
|
+
--fill "#input=value" # Fill form field
|
272
|
+
--wait 2 # Wait seconds
|
273
|
+
--wait-for ".selector" # Wait for element
|
274
|
+
--wait-for-network-idle # Wait for network idle
|
275
|
+
--screenshot "name" # Capture screenshot
|
276
|
+
--show-console # Show console errors
|
277
|
+
--open-trace # Auto-open Playwright trace
|
278
|
+
--save-session "name" # Save browser state
|
279
|
+
--use-session "name" # Restore browser state
|
281
280
|
```
|
282
281
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
| `screenshot` | `{"screenshot": "name"}` | Take basic screenshot |
|
293
|
-
| 🆕 `screenshot` | `{"screenshot": {"name": "test", "options": {"clip": {"selector": "#header"}}}}` | Enhanced screenshot with clipping |
|
294
|
-
| 🆕 `screenshot` | `{"screenshot": {"name": "test", "options": {"mask": [".sensitive"]}}}` | Screenshot with masked elements |
|
295
|
-
| 🆕 `screenshot` | `{"screenshot": {"name": "test.jpg", "options": {"quality": 90}}}` | JPEG screenshot with quality |
|
282
|
+
### **Available Actions (94+ via Pass-Through):**
|
283
|
+
|
284
|
+
CursorFlow passes actions directly to Playwright - ANY Page method works:
|
285
|
+
- `click`, `dblclick`, `hover`, `tap`, `press`
|
286
|
+
- `fill`, `type`, `check`, `uncheck`, `select_option`
|
287
|
+
- `focus`, `blur`, `drag_and_drop`
|
288
|
+
- `wait_for_selector`, `wait_for_load_state`, `wait_for_timeout`
|
289
|
+
- `goto`, `reload`, `evaluate`, `route`
|
290
|
+
- And 80+ more: https://playwright.dev/python/docs/api/class-page
|
296
291
|
|
297
292
|
## Common Usage Patterns
|
298
293
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cursorflow
|
3
|
-
Version: 2.2.
|
3
|
+
Version: 2.2.6
|
4
4
|
Summary: 🔥 Complete page intelligence for AI-driven development with Hot Reload Intelligence - captures DOM, network, console, performance, HMR events, and comprehensive page analysis
|
5
5
|
Author-email: GeekWarrior Development <rbush@cooltheory.com>
|
6
6
|
License-Expression: MIT
|
@@ -140,7 +140,7 @@ cursorflow cleanup --all
|
|
140
140
|
cursorflow cleanup --all --dry-run
|
141
141
|
```
|
142
142
|
|
143
|
-
**See:** [
|
143
|
+
**See:** [Complete Usage Guide](docs/user/USAGE_GUIDE.md#artifact-management)
|
144
144
|
|
145
145
|
---
|
146
146
|
|
@@ -1,38 +1,38 @@
|
|
1
|
-
cursorflow/__init__.py,sha256=
|
1
|
+
cursorflow/__init__.py,sha256=j0MIwqCJf-WXoJkccyHFTM2sRiL2KSeeRx8dfLiJA0I,2763
|
2
2
|
cursorflow/auto_init.py,sha256=dXQaXXiXe4wkUP-jd8fcJ5fYVt7ASdTb47b7SzXymOM,6122
|
3
3
|
cursorflow/auto_updater.py,sha256=oQ12TIMZ6Cm3HF-x9iRWFtvOLkRh-JWPqitS69-4roE,7851
|
4
|
-
cursorflow/cli.py,sha256=
|
4
|
+
cursorflow/cli.py,sha256=JmT0uw5lrZhUhN_MOkUtkGScPSYw7PzkQKT2e2In24o,50347
|
5
5
|
cursorflow/install_cursorflow_rules.py,sha256=DsZ0680y9JMuTKFXjdgYtOKIEAjBMsdwL8LmA9WEb5A,11864
|
6
6
|
cursorflow/post_install.py,sha256=WieBiKWG0qBAQpF8iMVWUyb9Fr2Xky9qECTMPrlAbpE,2678
|
7
7
|
cursorflow/updater.py,sha256=SroSQHQi5cYyzcOK_bf-WzmQmE7yeOs8qo3r__j-Z6E,19583
|
8
8
|
cursorflow/core/action_validator.py,sha256=SCk3w_62D1y0cCRDOajK8L44-abSj_KpnUBgR_yNVW4,6846
|
9
9
|
cursorflow/core/agent.py,sha256=f3lecgEzDRDdGTVccAtorpLGfNJJ49bbsQAmgr0vNGg,10136
|
10
10
|
cursorflow/core/auth_handler.py,sha256=oRafO6ZdxoHryBIvHsrNV8TECed4GXpJsdEiH0KdPPk,17149
|
11
|
-
cursorflow/core/browser_controller.py,sha256=
|
11
|
+
cursorflow/core/browser_controller.py,sha256=PuODrTefj3fH1FPuinvXmCcRfjLhWL9yWyWkmJgNd70,147220
|
12
12
|
cursorflow/core/browser_engine.py,sha256=7N9hPOyDrEhLWYgZW2981N9gKlHF6Lbp7D7h0zBzuz8,14851
|
13
13
|
cursorflow/core/config_validator.py,sha256=HRtONSOmM0Xxt3-ok3xwnBADRiNnI0nNOMaS2OqOkDk,7286
|
14
14
|
cursorflow/core/css_iterator.py,sha256=whLCIwbHZEWaH1HCbmqhNX5zrh_fL-r3hsxKjYsukcE,16478
|
15
15
|
cursorflow/core/cursor_integration.py,sha256=MAeHjXYeqzaXnhskqkTDB-n5ixIHqapGe93X0lLKhws,67501
|
16
|
-
cursorflow/core/cursorflow.py,sha256=
|
16
|
+
cursorflow/core/cursorflow.py,sha256=OH-QmS8B8dO3RZag5ewqik0TEmVIdnyFYUJF4btzMo4,46375
|
17
17
|
cursorflow/core/error_context_collector.py,sha256=so-aveqwb6_vRDbtKR2ln8_F84aaVIceNi1UHsaVPgc,26196
|
18
18
|
cursorflow/core/error_correlator.py,sha256=g6YaIF2yFXUDrTuWHCyuES6K0696H8LDWmXH1qI8ddA,13367
|
19
19
|
cursorflow/core/event_correlator.py,sha256=lCzXFnii17AQt3rOVOclez_AnjvBCF_2ZlnFG0mIN6c,7808
|
20
20
|
cursorflow/core/file_change_monitor.py,sha256=tl_ZdsGW8LZBTImniD-lqaGgNb9dYjlDsP2XmevE0xk,21258
|
21
21
|
cursorflow/core/hmr_detector.py,sha256=IrGYhXIeTBukffRXF74SW45cB_Im0cmq8RxxjtSz-2w,17431
|
22
|
-
cursorflow/core/log_collector.py,sha256=
|
22
|
+
cursorflow/core/log_collector.py,sha256=5ZoPlTyV1-1Q5Wn7NmW4aQK211i5fjrXQt69osVRSD0,14427
|
23
23
|
cursorflow/core/log_monitor.py,sha256=pONMu_JHEnT0T62OA5KRZ4nClzKgNpifPyrfN5w_RM8,6704
|
24
24
|
cursorflow/core/mockup_comparator.py,sha256=VLfEEaTgbcY0oTb-bhBD2uTbXGjbnOV7LXNVvXpWMrM,64695
|
25
25
|
cursorflow/core/persistent_session.py,sha256=FsEHj4wKkycmdp6PFRHv3g333Y74yqra0x_qhUTQpik,36075
|
26
26
|
cursorflow/core/report_generator.py,sha256=-vosfyrnfVyWDbAIMlMurl90xOXqBae8d6aLd9sEqiY,10113
|
27
27
|
cursorflow/core/trace_manager.py,sha256=Jj9ultZrL1atiZXfcRVI6ynCnnfqZM-X0_taxt-llJ0,7189
|
28
|
-
cursorflow/log_sources/local_file.py,sha256=
|
29
|
-
cursorflow/log_sources/ssh_remote.py,sha256=
|
28
|
+
cursorflow/log_sources/local_file.py,sha256=GVnhsaifIdc41twXwbxRM9-fBeRDsknDpk5IEGulnhQ,8318
|
29
|
+
cursorflow/log_sources/ssh_remote.py,sha256=_Kwh0bhRpKgq-0c98oaX2hN6h9cT-wCHlqY5NiWVCoY,8388
|
30
30
|
cursorflow/rules/__init__.py,sha256=gPcA-IkhXj03sl7cvZV0wwo7CtEkcyuKs4y0F5oQbqE,458
|
31
31
|
cursorflow/rules/cursorflow-installation.mdc,sha256=D55pzzDPAVVbE3gAtKPUGoT-2fvB-FI2l6yrTdzUIEo,10208
|
32
|
-
cursorflow/rules/cursorflow-usage.mdc,sha256=
|
33
|
-
cursorflow-2.2.
|
34
|
-
cursorflow-2.2.
|
35
|
-
cursorflow-2.2.
|
36
|
-
cursorflow-2.2.
|
37
|
-
cursorflow-2.2.
|
38
|
-
cursorflow-2.2.
|
32
|
+
cursorflow/rules/cursorflow-usage.mdc,sha256=kyRk9SaqkjjT6FRyMpEwzJ-KySpxCxAEQAmtxldWOPY,21325
|
33
|
+
cursorflow-2.2.6.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
|
34
|
+
cursorflow-2.2.6.dist-info/METADATA,sha256=OQVM0yPYW53WhTXRw_ZyzwIeF-5vl5zJQHgDgjPVHAQ,14527
|
35
|
+
cursorflow-2.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
36
|
+
cursorflow-2.2.6.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
|
37
|
+
cursorflow-2.2.6.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
|
38
|
+
cursorflow-2.2.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|