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 CHANGED
@@ -26,11 +26,14 @@ def main():
26
26
  pass
27
27
 
28
28
  @main.command()
29
- @click.argument('test_name', required=False, default='ui-test')
30
- @click.option('--base-url', '-u', default='http://localhost:3000',
31
- help='Base URL for testing')
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
- def test(test_name, base_url, actions, logs, config, verbose):
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
- console.print(f"🎯 Testing [bold]{test_name}[/bold] at [blue]{base_url}[/blue]")
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: {test_name}")
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
- output_file = f"{test_name.replace(' ', '_')}_test_results.json"
114
- with open(output_file, 'w') as f:
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]{output_file}[/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.0
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 component - captures everything automatically
81
- cursorflow test dashboard --base-url http://localhost:3000
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 component with complete data capture
138
- cursorflow test component --base-url http://localhost:3000
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 --base-url http://localhost:3000
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 --base-url http://localhost:3000
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=cE4W8XGAaS8NBw94aKVciWMvV6rqi0-waA2bB2O88kM,24026
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.0.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
23
- cursorflow-1.3.0.dist-info/METADATA,sha256=cLggB4V0-twK1XBZMk-Hnrdme0vdN3RwNan9FbrwIqY,6960
24
- cursorflow-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- cursorflow-1.3.0.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
26
- cursorflow-1.3.0.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
27
- cursorflow-1.3.0.dist-info/RECORD,,
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,,