Files
StreamLens/test_button_layout_improvements.py

202 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""
Test script to verify the button layout and table sorting improvements
"""
import sys
import time
from pathlib import Path
# Add analyzer to path
sys.path.insert(0, str(Path(__file__).parent))
from analyzer.analysis.core import EthernetAnalyzer
from analyzer.tui.textual.widgets.filtered_flow_view import FilteredFlowView
def test_button_layout():
"""Test that buttons are now one row high"""
print("Testing button layout improvements...")
# Create analyzer and flow view
analyzer = EthernetAnalyzer()
flow_view = FilteredFlowView(analyzer)
# Check that button height is set to 1
css_content = flow_view.DEFAULT_CSS
print("Checking CSS for button height...")
if "height: 1;" in css_content:
print("✅ Button height set to 1 row")
else:
print("❌ Button height not set correctly")
return False
if "#filter-bar {\n height: 1;" in css_content:
print("✅ Filter bar height set to 1 row")
else:
print("❌ Filter bar height not set correctly")
return False
return True
def test_button_ordering():
"""Test that buttons will be ordered by count"""
print("\nTesting button ordering by count...")
analyzer = EthernetAnalyzer()
# Add mock flow data with different frame type counts
from analyzer.models.flow_stats import FlowStats, FrameTypeStats
# Flow 1: High CH10-Data count
flow1 = FlowStats(src_ip="192.168.1.1", dst_ip="192.168.1.2")
flow1.frame_types["CH10-Data"] = FrameTypeStats("CH10-Data", count=1000)
flow1.frame_types["UDP"] = FrameTypeStats("UDP", count=10)
analyzer.flows["flow1"] = flow1
# Flow 2: High UDP count
flow2 = FlowStats(src_ip="192.168.1.3", dst_ip="192.168.1.4")
flow2.frame_types["UDP"] = FrameTypeStats("UDP", count=500)
flow2.frame_types["PTP-Sync"] = FrameTypeStats("PTP-Sync", count=200)
flow2.frame_types["TMATS"] = FrameTypeStats("TMATS", count=5)
analyzer.flows["flow2"] = flow2
flow_view = FilteredFlowView(analyzer)
# Get frame types and their counts
frame_types = flow_view._get_all_frame_types()
print(f"Frame types detected: {frame_types}")
# Check that they're sorted by count (CH10-Data: 1000, UDP: 510, PTP-Sync: 200, TMATS: 5)
sorted_types = sorted(frame_types.items(), key=lambda x: x[1], reverse=True)
print(f"Sorted frame types: {sorted_types}")
if sorted_types[0][0] == "CH10-Data" and sorted_types[0][1] == 1000:
print("✅ Highest count frame type (CH10-Data) will be first")
else:
print(f"❌ Expected CH10-Data (1000) first, got {sorted_types[0]}")
return False
if sorted_types[1][0] == "UDP" and sorted_types[1][1] == 510:
print("✅ Second highest count frame type (UDP) will be second")
else:
print(f"❌ Expected UDP (510) second, got {sorted_types[1]}")
return False
return True
def test_table_sorting():
"""Test table sorting functionality"""
print("\nTesting table sorting functionality...")
analyzer = EthernetAnalyzer()
flow_view = FilteredFlowView(analyzer)
# Check that sorting state is initialized
if hasattr(flow_view, 'sort_column') and hasattr(flow_view, 'sort_reverse'):
print("✅ Sorting state variables initialized")
else:
print("❌ Sorting state variables not found")
return False
# Check that sort method exists
if hasattr(flow_view, 'action_sort_column'):
print("✅ Sort action method exists")
else:
print("❌ Sort action method not found")
return False
# Check that get_sort_key method exists
if hasattr(flow_view, '_get_sort_key'):
print("✅ Sort key method exists")
else:
print("❌ Sort key method not found")
return False
# Test sort key extraction
test_row = ["1", "192.168.1.1:5000", "239.1.1.1:8000", "UDP", "1,234", "Normal"]
# Test numeric extraction
key = flow_view._get_sort_key(test_row, 4) # Packet count column
if key == 1234:
print("✅ Numeric sort key extraction works (comma removal)")
else:
print(f"❌ Expected 1234, got {key}")
return False
# Test string extraction
key = flow_view._get_sort_key(test_row, 3) # Protocol column
if key == "udp":
print("✅ String sort key extraction works (lowercase)")
else:
print(f"❌ Expected 'udp', got {key}")
return False
return True
def test_key_bindings():
"""Test that key bindings are set up correctly"""
print("\nTesting key bindings...")
# Import the app to check key bindings
from analyzer.tui.textual.app_v2 import StreamLensAppV2
from analyzer.tui.textual.widgets.filtered_flow_view import FilteredFlowView
# Check FilteredFlowView bindings
flow_view_bindings = [binding.key for binding in FilteredFlowView.BINDINGS]
expected_bindings = ['alt+1', 'alt+2', 'alt+3', 'alt+4', 'alt+5', 'alt+6', 'alt+7', 'alt+8', 'alt+9', 'alt+0']
for binding in expected_bindings:
if binding in flow_view_bindings:
print(f"{binding} binding found in FilteredFlowView")
else:
print(f"{binding} binding missing in FilteredFlowView")
return False
# Check main app bindings
app_bindings = [binding[0] for binding in StreamLensAppV2.BINDINGS]
for binding in expected_bindings:
if binding in app_bindings:
print(f"{binding} binding found in main app")
else:
print(f"{binding} binding missing in main app")
return False
return True
if __name__ == "__main__":
print("StreamLens Button Layout & Sorting Test")
print("=" * 50)
try:
success1 = test_button_layout()
success2 = test_button_ordering()
success3 = test_table_sorting()
success4 = test_key_bindings()
if success1 and success2 and success3 and success4:
print(f"\n✅ All tests passed!")
print(f"\n📊 Summary of Improvements:")
print(f" • Buttons are now 1 row high (was 3)")
print(f" • Buttons ordered by frame type count (highest first)")
print(f" • Tables sortable with Alt+1...Alt+0 keys")
print(f" • Smart sorting handles numbers, text, and units")
print(f"\n🎯 Usage:")
print(f" • 1-9,0: Select frame type filters")
print(f" • Alt+1...Alt+0: Sort by columns 1-10")
print(f" • Alt+same key: Toggle sort direction")
else:
print(f"\n❌ Some tests failed")
sys.exit(1)
except Exception as e:
print(f"\n❌ Test failed with error: {e}")
import traceback
traceback.print_exc()
sys.exit(1)