189 lines
7.8 KiB
Python
189 lines
7.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test button persistence throughout a live session
|
|
"""
|
|
|
|
import sys
|
|
import asyncio
|
|
import time
|
|
from pathlib import Path
|
|
|
|
# Add analyzer to path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from analyzer.tui.textual.app_v2 import StreamLensAppV2
|
|
from analyzer.analysis.core import EthernetAnalyzer
|
|
from analyzer.models.flow_stats import FlowStats, FrameTypeStats
|
|
from textual_inspector import inspect_textual_app, print_widget_tree
|
|
|
|
async def simulate_data_loading_with_monitoring():
|
|
"""Simulate data loading while monitoring button persistence"""
|
|
|
|
print("🧪 Testing Button Persistence Throughout Session")
|
|
print("=" * 60)
|
|
|
|
# Create analyzer and app
|
|
analyzer = EthernetAnalyzer()
|
|
app = StreamLensAppV2(analyzer=analyzer)
|
|
|
|
async with app.run_test() as pilot:
|
|
print("📱 App started - checking initial button state...")
|
|
|
|
# Helper function to count buttons
|
|
def count_buttons():
|
|
app_data = inspect_textual_app(app)
|
|
button_count = 0
|
|
visible_buttons = 0
|
|
properly_sized = 0
|
|
|
|
def count_buttons_recursive(widget_data):
|
|
nonlocal button_count, visible_buttons, properly_sized
|
|
|
|
if widget_data.get('type') == 'Button' or 'Button' in widget_data.get('type', ''):
|
|
button_count += 1
|
|
if widget_data.get('visible', False):
|
|
visible_buttons += 1
|
|
size = widget_data.get('size', {})
|
|
if size.get('width', 0) > 0 and size.get('height', 0) > 0:
|
|
properly_sized += 1
|
|
|
|
for child in widget_data.get('children', []):
|
|
count_buttons_recursive(child)
|
|
|
|
count_buttons_recursive(app_data.get('current_screen', {}))
|
|
return button_count, visible_buttons, properly_sized
|
|
|
|
# Phase 1: Initial state (no data)
|
|
await asyncio.sleep(1)
|
|
total1, visible1, sized1 = count_buttons()
|
|
print(f"📊 Phase 1 (Initial): {total1} total, {visible1} visible, {sized1} properly sized")
|
|
|
|
# Phase 2: Add some flows to trigger refresh
|
|
print("\n🔄 Phase 2: Adding flow data to trigger refresh...")
|
|
|
|
# Add flows with different frame types
|
|
flow1 = FlowStats(src_ip="192.168.1.1", dst_ip="192.168.1.2")
|
|
flow1.frame_types["CH10-Data"] = FrameTypeStats("CH10-Data", count=100)
|
|
flow1.frame_types["UDP"] = FrameTypeStats("UDP", count=50)
|
|
analyzer.flows["flow1"] = flow1
|
|
|
|
flow2 = FlowStats(src_ip="192.168.1.3", dst_ip="192.168.1.4")
|
|
flow2.frame_types["PTP-Sync"] = FrameTypeStats("PTP-Sync", count=200)
|
|
flow2.frame_types["PTP-Signaling"] = FrameTypeStats("PTP-Signaling", count=75)
|
|
analyzer.flows["flow2"] = flow2
|
|
|
|
# Wait for UI to process the changes
|
|
await asyncio.sleep(2)
|
|
total2, visible2, sized2 = count_buttons()
|
|
print(f"📊 Phase 2 (With Data): {total2} total, {visible2} visible, {sized2} properly sized")
|
|
|
|
# Phase 3: Add more data to test ordering/refresh
|
|
print("\n🔄 Phase 3: Adding more data to test refresh logic...")
|
|
|
|
flow3 = FlowStats(src_ip="192.168.1.5", dst_ip="192.168.1.6")
|
|
flow3.frame_types["TMATS"] = FrameTypeStats("TMATS", count=500) # High count should reorder
|
|
flow3.frame_types["TCP"] = FrameTypeStats("TCP", count=25)
|
|
analyzer.flows["flow3"] = flow3
|
|
|
|
# Wait for refresh
|
|
await asyncio.sleep(2)
|
|
total3, visible3, sized3 = count_buttons()
|
|
print(f"📊 Phase 3 (More Data): {total3} total, {visible3} visible, {sized3} properly sized")
|
|
|
|
# Phase 4: Final check with detailed analysis
|
|
print("\n🔍 Phase 4: Detailed button analysis...")
|
|
|
|
app_data = inspect_textual_app(app)
|
|
buttons_found = []
|
|
|
|
def analyze_buttons(widget_data, path=""):
|
|
if widget_data.get('type') == 'Button' or 'Button' in widget_data.get('type', ''):
|
|
button_info = {
|
|
'id': widget_data.get('id'),
|
|
'label': widget_data.get('label', 'NO LABEL'),
|
|
'visible': widget_data.get('visible', False),
|
|
'size': widget_data.get('size', {}),
|
|
'classes': widget_data.get('classes', [])
|
|
}
|
|
buttons_found.append(button_info)
|
|
|
|
for child in widget_data.get('children', []):
|
|
analyze_buttons(child, f"{path}/{widget_data.get('type', 'Unknown')}")
|
|
|
|
analyze_buttons(app_data.get('current_screen', {}))
|
|
|
|
print(f"\n📋 Final Button States:")
|
|
for i, button in enumerate(buttons_found, 1):
|
|
label = button.get('label', 'NO LABEL')
|
|
size = button.get('size', {})
|
|
visible = button.get('visible', False)
|
|
|
|
status_icons = []
|
|
if visible: status_icons.append("👁️")
|
|
if size.get('height', 0) > 0: status_icons.append("📏")
|
|
if label and label != 'NO LABEL': status_icons.append("📝")
|
|
|
|
status = " ".join(status_icons) if status_icons else "❌"
|
|
|
|
print(f" {i:2d}. {button.get('id', 'unknown'):20} '{label:12}' {size.get('width', 0):2d}x{size.get('height', 0)} {status}")
|
|
|
|
# Summary
|
|
print(f"\n📈 PERSISTENCE TEST RESULTS:")
|
|
print(f" Phase 1 (Initial): {total1:2d} buttons ({visible1} visible, {sized1} sized)")
|
|
print(f" Phase 2 (Data): {total2:2d} buttons ({visible2} visible, {sized2} sized)")
|
|
print(f" Phase 3 (More): {total3:2d} buttons ({visible3} visible, {sized3} sized)")
|
|
|
|
# Check for consistency
|
|
if total1 == total2 == total3:
|
|
print(f" ✅ BUTTON COUNT STABLE throughout session")
|
|
else:
|
|
print(f" 🚨 Button count changed: {total1} → {total2} → {total3}")
|
|
|
|
if visible1 == visible2 == visible3:
|
|
print(f" ✅ BUTTON VISIBILITY STABLE throughout session")
|
|
else:
|
|
print(f" 🚨 Visibility changed: {visible1} → {visible2} → {visible3}")
|
|
|
|
if sized1 == sized2 == sized3 and sized3 > 0:
|
|
print(f" ✅ BUTTON SIZING STABLE and working throughout session")
|
|
else:
|
|
print(f" 🚨 Sizing changed: {sized1} → {sized2} → {sized3}")
|
|
|
|
# Final verdict
|
|
all_stable = (total1 == total2 == total3 and
|
|
visible1 == visible2 == visible3 and
|
|
sized1 == sized2 == sized3 and
|
|
sized3 > 0)
|
|
|
|
if all_stable:
|
|
print(f"\n🎉 SUCCESS: Buttons persist properly throughout the session!")
|
|
else:
|
|
print(f"\n⚠️ Issues detected in button persistence")
|
|
|
|
return all_stable
|
|
|
|
def main():
|
|
print("🧪 StreamLens Button Persistence Test")
|
|
print("This test simulates a full session with data loading")
|
|
print("=" * 60)
|
|
|
|
try:
|
|
success = asyncio.run(simulate_data_loading_with_monitoring())
|
|
|
|
if success:
|
|
print(f"\n✅ All button persistence tests PASSED!")
|
|
print(f"\n🎯 Both issues have been resolved:")
|
|
print(f" ✅ Buttons persist throughout the session")
|
|
print(f" ✅ Button text is visible (proper height)")
|
|
else:
|
|
print(f"\n❌ Some persistence issues remain")
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n🛑 Test interrupted by user")
|
|
except Exception as e:
|
|
print(f"\n❌ Test failed with error: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
if __name__ == "__main__":
|
|
main() |