cursorflow 2.4.1__py3-none-any.whl → 2.4.2__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
@@ -357,11 +357,13 @@ def test(base_url, path, actions, output, logs, config, verbose, headless, timeo
357
357
  help='JSON array of viewports to test: [{"width": 1440, "height": 900, "name": "desktop"}]')
358
358
  @click.option('--diff-threshold', '-t', type=float, default=0.1,
359
359
  help='Visual difference threshold (0.0-1.0)')
360
+ @click.option('--block-tracking', is_flag=True,
361
+ help='Block tracking scripts (Google Analytics, Facebook Pixel, etc.) to prevent timeout')
360
362
  @click.option('--output', '-o', default='mockup_comparison_results.json',
361
363
  help='Output file for comparison results')
362
364
  @click.option('--verbose', is_flag=True,
363
365
  help='Verbose output')
364
- def compare_mockup(mockup_url, base_url, mockup_actions, implementation_actions, viewports, diff_threshold, output, verbose):
366
+ def compare_mockup(mockup_url, base_url, mockup_actions, implementation_actions, viewports, diff_threshold, block_tracking, output, verbose):
365
367
  """Compare mockup design to work-in-progress implementation"""
366
368
 
367
369
  console.print(f"🎨 Comparing mockup [blue]{mockup_url}[/blue] to implementation [blue]{base_url}[/blue]")
@@ -404,10 +406,17 @@ def compare_mockup(mockup_url, base_url, mockup_actions, implementation_actions,
404
406
  # Initialize CursorFlow
405
407
  try:
406
408
  from .core.cursorflow import CursorFlow
409
+
410
+ # Configure browser with tracking blocking if requested
411
+ browser_config = {'headless': True}
412
+ if block_tracking:
413
+ browser_config['block_tracking'] = True
414
+ console.print("🚫 Blocking tracking scripts (Google Analytics, Facebook Pixel, etc.)")
415
+
407
416
  flow = CursorFlow(
408
417
  base_url=base_url,
409
418
  log_config={'source': 'local', 'paths': ['logs/app.log']},
410
- browser_config={'headless': True}
419
+ browser_config=browser_config
411
420
  )
412
421
  except Exception as e:
413
422
  console.print(f"[red]Error initializing CursorFlow: {e}[/red]")
@@ -915,12 +924,25 @@ def inspect(base_url, path, selector, verbose):
915
924
  visual = element.get('visual_context', {})
916
925
  if visual:
917
926
  console.print(f"\n👁️ Visual Context:")
918
- if visual.get('is_visible'):
927
+ # Check nested visibility structure
928
+ visibility = visual.get('visibility', {})
929
+ is_visible = visibility.get('is_visible', False)
930
+ is_in_viewport = visibility.get('is_in_viewport', False)
931
+
932
+ if is_visible:
919
933
  console.print(f" Visibility: ✅ Visible")
934
+ if is_in_viewport:
935
+ console.print(f" In Viewport: ✅ Yes")
936
+ else:
937
+ console.print(f" In Viewport: ⬇️ Below fold")
920
938
  else:
921
939
  console.print(f" Visibility: ❌ Hidden")
922
- if visual.get('z_index'):
923
- console.print(f" Z-index: {visual.get('z_index')}")
940
+
941
+ # Z-index from layering info
942
+ layering = visual.get('layering', {})
943
+ z_index = layering.get('z_index')
944
+ if z_index and z_index != 'auto':
945
+ console.print(f" Z-index: {z_index}")
924
946
 
925
947
  console.print("") # Spacing between elements
926
948
 
@@ -1067,14 +1089,19 @@ def measure(base_url, path, selector, verbose):
1067
1089
 
1068
1090
  @main.command()
1069
1091
  @click.option('--base-url', '-u', required=True)
1092
+ @click.option('--path', '-p', default='/', help='Path to navigate to')
1070
1093
  @click.option('--selector', '-s', required=True)
1071
- def count(base_url, selector):
1094
+ def count(base_url, path, selector):
1072
1095
  """
1073
1096
  Quick element count without full test
1074
1097
 
1075
- Phase 3.5: Count matching elements
1098
+ Counts how many elements match the given selector.
1099
+
1100
+ Examples:
1101
+ cursorflow count --base-url http://localhost:3000 --selector ".message-item"
1102
+ cursorflow count -u http://localhost:3000 -p /dashboard -s "button"
1076
1103
  """
1077
- console.print(f"🔢 Counting selector: [cyan]{selector}[/cyan]")
1104
+ console.print(f"🔢 Counting selector: [cyan]{selector}[/cyan] at [blue]{path}[/blue]\n")
1078
1105
 
1079
1106
  try:
1080
1107
  from .core.cursorflow import CursorFlow
@@ -1084,15 +1111,32 @@ def count(base_url, selector):
1084
1111
  browser_config={'headless': True}
1085
1112
  )
1086
1113
 
1087
- # Quick count
1088
- asyncio.run(flow.execute_and_collect([
1089
- {"navigate": "/"}
1114
+ # Execute with screenshot to get comprehensive data
1115
+ results = asyncio.run(flow.execute_and_collect([
1116
+ {"navigate": path},
1117
+ {"wait_for_selector": "body"},
1118
+ {"screenshot": "count"}
1090
1119
  ]))
1091
1120
 
1092
- console.print(f"✅ Element count retrieved")
1121
+ # Extract element data
1122
+ comprehensive_data = results.get('comprehensive_data', {})
1123
+ dom_analysis = comprehensive_data.get('dom_analysis', {})
1124
+ elements = dom_analysis.get('elements', [])
1125
+
1126
+ # Count matching elements
1127
+ matching_count = sum(1 for element in elements if _element_matches_selector(element, selector))
1128
+
1129
+ if matching_count == 0:
1130
+ console.print(f"[yellow]⚠️ No elements found matching: {selector}[/yellow]")
1131
+ console.print(f"💡 Total elements on page: {len(elements)}")
1132
+ else:
1133
+ console.print(f"[bold green]✅ Found {matching_count} element(s) matching: {selector}[/bold green]")
1134
+ console.print(f"💡 Total elements on page: {len(elements)}")
1093
1135
 
1094
1136
  except Exception as e:
1095
1137
  console.print(f"[red]❌ Count failed: {e}[/red]")
1138
+ import traceback
1139
+ console.print(traceback.format_exc())
1096
1140
 
1097
1141
  @main.command()
1098
1142
  @click.option('--click', '-c', multiple=True)
@@ -131,6 +131,10 @@ class BrowserController:
131
131
  self.context = await self.browser.new_context(**context_config)
132
132
  self.page = await self.context.new_page()
133
133
 
134
+ # Block tracking scripts if requested (prevents timeout on pages with analytics)
135
+ if self.config.get("block_tracking", False):
136
+ await self._setup_tracking_blocker()
137
+
134
138
  # v2.0 Enhancement: Initialize Error Context Collector
135
139
  self.error_context_collector = ErrorContextCollector(self.page, self.logger)
136
140
 
@@ -169,6 +173,33 @@ class BrowserController:
169
173
 
170
174
  raise
171
175
 
176
+ async def _setup_tracking_blocker(self):
177
+ """Block common tracking scripts to prevent networkidle timeout"""
178
+ tracking_patterns = [
179
+ "*google-analytics.com/*",
180
+ "*googletagmanager.com/*",
181
+ "*facebook.com/tr/*",
182
+ "*facebook.net/*",
183
+ "*doubleclick.net/*",
184
+ "*analytics.google.com/*",
185
+ "*hotjar.com/*",
186
+ "*mixpanel.com/*",
187
+ "*segment.com/*",
188
+ "*googleadservices.com/*",
189
+ "*connect.facebook.net/*",
190
+ "*/analytics/*",
191
+ "*/tracking/*"
192
+ ]
193
+
194
+ async def block_tracking(route):
195
+ """Block tracking request"""
196
+ await route.abort()
197
+
198
+ for pattern in tracking_patterns:
199
+ await self.page.route(pattern, block_tracking)
200
+
201
+ self.logger.info("🚫 Tracking scripts blocked")
202
+
172
203
  async def _setup_event_listeners(self):
173
204
  """Set up universal event listeners for any framework"""
174
205
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cursorflow
3
- Version: 2.4.1
3
+ Version: 2.4.2
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
@@ -1,14 +1,14 @@
1
1
  cursorflow/__init__.py,sha256=2V9xzG2tYxVWOTmSw2v9Jdbr7lSrMi_y2SMUMuNZdvw,2990
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=sukvrOvphTfXZSbFUAqePmp11SKlV2Vu6SL4hgrf20A,62877
4
+ cursorflow/cli.py,sha256=8nSyTyYLHgwetGuyN3WmZQq5JuStWmMY8fbyNnoifO4,65185
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=0jjYEzAr1qtuzHAhBn3Jff8FZrMBPx8gF0mDv7QWcgQ,146683
11
+ cursorflow/core/browser_controller.py,sha256=IegmyrD_wQ0XjigW0cJXxAPhoJRVza3d4pzuWGB1r3Y,147804
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
@@ -30,9 +30,9 @@ cursorflow/log_sources/ssh_remote.py,sha256=_Kwh0bhRpKgq-0c98oaX2hN6h9cT-wCHlqY5
30
30
  cursorflow/rules/__init__.py,sha256=gPcA-IkhXj03sl7cvZV0wwo7CtEkcyuKs4y0F5oQbqE,458
31
31
  cursorflow/rules/cursorflow-installation.mdc,sha256=D55pzzDPAVVbE3gAtKPUGoT-2fvB-FI2l6yrTdzUIEo,10208
32
32
  cursorflow/rules/cursorflow-usage.mdc,sha256=8TUeQ1hq2fTlgPqUBYOVBXrdEN0BR0Xp0d_1L-eUsME,23150
33
- cursorflow-2.4.1.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
34
- cursorflow-2.4.1.dist-info/METADATA,sha256=E4HcwQv4wmoLS6kCTazQRdEcJHM3GCVmDafHxKyG2ME,14793
35
- cursorflow-2.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- cursorflow-2.4.1.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
37
- cursorflow-2.4.1.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
38
- cursorflow-2.4.1.dist-info/RECORD,,
33
+ cursorflow-2.4.2.dist-info/licenses/LICENSE,sha256=e4QbjAsj3bW-xgQOvQelr8sGLYDoqc48k6cKgCr_pBU,1080
34
+ cursorflow-2.4.2.dist-info/METADATA,sha256=K7h8QC0-M2nj5SMm31PzhPsXWyB9AC0rKn4QxIHWPx4,14793
35
+ cursorflow-2.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ cursorflow-2.4.2.dist-info/entry_points.txt,sha256=-Ed_n4Uff7wClEtWS-Py6xmQabecB9f0QAOjX0w7ljA,51
37
+ cursorflow-2.4.2.dist-info/top_level.txt,sha256=t1UZwRyZP4u-ng2CEcNHmk_ZT4ibQxoihB2IjTF7ovc,11
38
+ cursorflow-2.4.2.dist-info/RECORD,,