cursorflow 1.3.0__py3-none-any.whl → 1.3.1__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/cli.py +33 -11
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/METADATA +28 -7
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/RECORD +7 -7
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/WHEEL +0 -0
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/entry_points.txt +0 -0
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/licenses/LICENSE +0 -0
- {cursorflow-1.3.0.dist-info → cursorflow-1.3.1.dist-info}/top_level.txt +0 -0
cursorflow/cli.py
CHANGED
@@ -26,11 +26,14 @@ def main():
|
|
26
26
|
pass
|
27
27
|
|
28
28
|
@main.command()
|
29
|
-
@click.
|
30
|
-
|
31
|
-
|
29
|
+
@click.option('--base-url', '-u', required=True,
|
30
|
+
help='Base URL for testing (e.g., http://localhost:3000)')
|
31
|
+
@click.option('--path', '-p',
|
32
|
+
help='Simple path to navigate to (e.g., "/dashboard")')
|
32
33
|
@click.option('--actions', '-a',
|
33
34
|
help='JSON file with test actions, or inline JSON string')
|
35
|
+
@click.option('--output', '-o',
|
36
|
+
help='Output file for results (auto-generated if not specified)')
|
34
37
|
@click.option('--logs', '-l',
|
35
38
|
type=click.Choice(['local', 'ssh', 'docker', 'systemd']),
|
36
39
|
default='local',
|
@@ -39,7 +42,11 @@ def main():
|
|
39
42
|
help='Configuration file path')
|
40
43
|
@click.option('--verbose', '-v', is_flag=True,
|
41
44
|
help='Verbose output')
|
42
|
-
|
45
|
+
@click.option('--headless', is_flag=True, default=True,
|
46
|
+
help='Run browser in headless mode')
|
47
|
+
@click.option('--timeout', type=int, default=30,
|
48
|
+
help='Timeout in seconds for actions')
|
49
|
+
def test(base_url, path, actions, output, logs, config, verbose, headless, timeout):
|
43
50
|
"""Test UI flows and interactions with real-time log monitoring"""
|
44
51
|
|
45
52
|
if verbose:
|
@@ -65,14 +72,22 @@ def test(test_name, base_url, actions, logs, config, verbose):
|
|
65
72
|
except Exception as e:
|
66
73
|
console.print(f"[red]❌ Failed to load actions: {e}[/red]")
|
67
74
|
return
|
75
|
+
elif path:
|
76
|
+
# Simple path navigation
|
77
|
+
test_actions = [
|
78
|
+
{"navigate": path},
|
79
|
+
{"wait_for": "body"},
|
80
|
+
{"screenshot": "page_loaded"}
|
81
|
+
]
|
82
|
+
console.print(f"📋 Using simple path navigation to [cyan]{path}[/cyan]")
|
68
83
|
else:
|
69
|
-
# Default actions - just navigate and screenshot
|
84
|
+
# Default actions - just navigate to root and screenshot
|
70
85
|
test_actions = [
|
71
86
|
{"navigate": "/"},
|
72
87
|
{"wait_for": "body"},
|
73
88
|
{"screenshot": "baseline"}
|
74
89
|
]
|
75
|
-
console.print(f"📋 Using default actions (navigate + screenshot)")
|
90
|
+
console.print(f"📋 Using default actions (navigate to root + screenshot)")
|
76
91
|
|
77
92
|
# Load configuration
|
78
93
|
agent_config = {}
|
@@ -80,7 +95,8 @@ def test(test_name, base_url, actions, logs, config, verbose):
|
|
80
95
|
with open(config, 'r') as f:
|
81
96
|
agent_config = json.load(f)
|
82
97
|
|
83
|
-
|
98
|
+
test_description = path if path else "root page"
|
99
|
+
console.print(f"🎯 Testing [bold]{test_description}[/bold] at [blue]{base_url}[/blue]")
|
84
100
|
|
85
101
|
# Initialize CursorFlow (framework-agnostic)
|
86
102
|
try:
|
@@ -88,6 +104,7 @@ def test(test_name, base_url, actions, logs, config, verbose):
|
|
88
104
|
flow = CursorFlow(
|
89
105
|
base_url=base_url,
|
90
106
|
log_config={'source': logs, 'paths': ['logs/app.log']},
|
107
|
+
browser_config={'headless': headless, 'timeout': timeout},
|
91
108
|
**agent_config
|
92
109
|
)
|
93
110
|
except Exception as e:
|
@@ -99,7 +116,7 @@ def test(test_name, base_url, actions, logs, config, verbose):
|
|
99
116
|
console.print(f"🚀 Executing {len(test_actions)} actions...")
|
100
117
|
results = asyncio.run(flow.execute_and_collect(test_actions))
|
101
118
|
|
102
|
-
console.print(f"✅ Test completed: {
|
119
|
+
console.print(f"✅ Test completed: {test_description}")
|
103
120
|
console.print(f"📊 Browser events: {len(results.get('browser_events', []))}")
|
104
121
|
console.print(f"📋 Server logs: {len(results.get('server_logs', []))}")
|
105
122
|
console.print(f"📸 Screenshots: {len(results.get('artifacts', {}).get('screenshots', []))}")
|
@@ -110,11 +127,16 @@ def test(test_name, base_url, actions, logs, config, verbose):
|
|
110
127
|
console.print(f"⏰ Timeline events: {len(timeline)}")
|
111
128
|
|
112
129
|
# Save results to file for Cursor analysis
|
113
|
-
|
114
|
-
|
130
|
+
if not output:
|
131
|
+
# Auto-generate meaningful filename
|
132
|
+
session_id = results.get('session_id', 'unknown')
|
133
|
+
path_part = path.replace('/', '_') if path else 'root'
|
134
|
+
output = f"cursorflow_{path_part}_{session_id}.json"
|
135
|
+
|
136
|
+
with open(output, 'w') as f:
|
115
137
|
json.dump(results, f, indent=2, default=str)
|
116
138
|
|
117
|
-
console.print(f"💾 Full results saved to: [cyan]{
|
139
|
+
console.print(f"💾 Full results saved to: [cyan]{output}[/cyan]")
|
118
140
|
console.print(f"📁 Artifacts stored in: [cyan].cursorflow/artifacts/[/cyan]")
|
119
141
|
|
120
142
|
except Exception as e:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cursorflow
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.1
|
4
4
|
Summary: Complete page intelligence for AI-driven development - captures DOM, network, console, and performance data
|
5
5
|
Author-email: GeekWarrior Development <support@cursorflow.dev>
|
6
6
|
License-Expression: MIT
|
@@ -77,8 +77,12 @@ All data structured for AI consumption:
|
|
77
77
|
# Install
|
78
78
|
pip install cursorflow
|
79
79
|
|
80
|
-
# Test any
|
81
|
-
cursorflow test
|
80
|
+
# Test any page - captures everything automatically
|
81
|
+
cursorflow test --base-url http://localhost:3000 --actions '[
|
82
|
+
{"navigate": "/dashboard"},
|
83
|
+
{"wait_for": "#main-content"},
|
84
|
+
{"screenshot": "dashboard-loaded"}
|
85
|
+
]'
|
82
86
|
|
83
87
|
# Compare mockup to implementation
|
84
88
|
cursorflow compare-mockup https://mockup.com/design --base-url http://localhost:3000
|
@@ -134,14 +138,31 @@ results = await flow.css_iteration_persistent(
|
|
134
138
|
## 🔧 CLI Commands
|
135
139
|
|
136
140
|
```bash
|
137
|
-
# Test
|
138
|
-
cursorflow test
|
141
|
+
# Test any page with custom actions
|
142
|
+
cursorflow test --base-url http://localhost:3000 --actions '[
|
143
|
+
{"navigate": "/login"},
|
144
|
+
{"fill": {"selector": "#username", "value": "test@example.com"}},
|
145
|
+
{"fill": {"selector": "#password", "value": "password123"}},
|
146
|
+
{"click": "#login-button"},
|
147
|
+
{"wait_for": ".dashboard"},
|
148
|
+
{"screenshot": "logged-in"}
|
149
|
+
]'
|
150
|
+
|
151
|
+
# Simple page test (just navigate and screenshot)
|
152
|
+
cursorflow test --base-url http://localhost:3000 --path "/dashboard"
|
139
153
|
|
140
154
|
# Compare mockup to implementation
|
141
|
-
cursorflow compare-mockup https://mockup.com/design
|
155
|
+
cursorflow compare-mockup https://mockup.com/design \
|
156
|
+
--base-url http://localhost:3000 \
|
157
|
+
--viewports '[{"width": 1440, "height": 900, "name": "desktop"}]'
|
142
158
|
|
143
159
|
# Iterate on CSS improvements
|
144
|
-
cursorflow iterate-mockup https://mockup.com/design
|
160
|
+
cursorflow iterate-mockup https://mockup.com/design \
|
161
|
+
--base-url http://localhost:3000 \
|
162
|
+
--css-improvements '[
|
163
|
+
{"name": "spacing", "css": ".container { gap: 2rem; }"},
|
164
|
+
{"name": "colors", "css": ".button { background: blue; }"}
|
165
|
+
]'
|
145
166
|
```
|
146
167
|
|
147
168
|
## 🌐 Universal Framework Support
|
@@ -1,6 +1,6 @@
|
|
1
1
|
cursorflow/__init__.py,sha256=nRmHnnnsbDH1A7_d3XkmzB5iJ44bt124zAQhaEhscyY,2450
|
2
2
|
cursorflow/auto_updater.py,sha256=oQ12TIMZ6Cm3HF-x9iRWFtvOLkRh-JWPqitS69-4roE,7851
|
3
|
-
cursorflow/cli.py,sha256=
|
3
|
+
cursorflow/cli.py,sha256=JRznfNAaXuthmCVwQX7yvX8FtAFrZYwemUA7BfvfFOo,25036
|
4
4
|
cursorflow/updater.py,sha256=pvbSZgg6hgWZBE5AAUPppS5Yzv0yNMp2X_CL2GALg_w,18783
|
5
5
|
cursorflow/core/agent.py,sha256=f3lecgEzDRDdGTVccAtorpLGfNJJ49bbsQAmgr0vNGg,10136
|
6
6
|
cursorflow/core/auth_handler.py,sha256=oRafO6ZdxoHryBIvHsrNV8TECed4GXpJsdEiH0KdPPk,17149
|
@@ -19,9 +19,9 @@ cursorflow/core/persistent_session.py,sha256=FsEHj4wKkycmdp6PFRHv3g333Y74yqra0x_
|
|
19
19
|
cursorflow/core/report_generator.py,sha256=-vosfyrnfVyWDbAIMlMurl90xOXqBae8d6aLd9sEqiY,10113
|
20
20
|
cursorflow/log_sources/local_file.py,sha256=SwA294n_Ozg76ZUF5nPn5W2Fts_XtSOHEcO2S65vnjc,6768
|
21
21
|
cursorflow/log_sources/ssh_remote.py,sha256=TrE9FZ4aI6Cz1vChjvG8RC2KrNlgRKtG0_hC1w8pGDA,7106
|
22
|
-
cursorflow-1.3.
|
23
|
-
cursorflow-1.3.
|
24
|
-
cursorflow-1.3.
|
25
|
-
cursorflow-1.3.
|
26
|
-
cursorflow-1.3.
|
27
|
-
cursorflow-1.3.
|
22
|
+
cursorflow-1.3.1.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
|
23
|
+
cursorflow-1.3.1.dist-info/METADATA,sha256=hpTsD-iCuuDDt8hCuGKsC8yTP3AgTdPmUAIHAPDhwTQ,7659
|
24
|
+
cursorflow-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
25
|
+
cursorflow-1.3.1.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
|
26
|
+
cursorflow-1.3.1.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
|
27
|
+
cursorflow-1.3.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|