#!/usr/bin/env python3 """ Visual Regression Test Runner Runs visual tests, compares with baselines, and generates reports """ import subprocess import json import os import base64 from datetime import datetime import argparse class VisualTestRunner: def __init__(self): self.baselines_dir = "visual_baselines" self.results_dir = "visual_results" self.reports_dir = "visual_reports" self.threshold = 0.95 # 95% similarity threshold # Create directories os.makedirs(self.baselines_dir, exist_ok=True) os.makedirs(self.results_dir, exist_ok=True) os.makedirs(self.reports_dir, exist_ok=True) def run_visual_tests(self): """Run all visual regression tests""" print("๐จ Running Visual Regression Tests") print("=" * 50) try: result = subprocess.run([ "cargo", "test", "--test", "visual_regression_tests", "--", "--nocapture" ], capture_output=True, text=True, timeout=300) if result.returncode == 0: print("โ Visual tests completed successfully") return True else: print(f"โ Visual tests failed: {result.stderr}") return False except subprocess.TimeoutExpired: print("โฐ Visual tests timed out") return False except Exception as e: print(f"โ Error running visual tests: {e}") return False def update_baselines(self, test_name=None): """Update visual baselines""" print(f"๐ธ Updating visual baselines{' for ' + test_name if test_name else ''}") if test_name: # Update specific baseline baseline_file = os.path.join(self.baselines_dir, f"{test_name}.json") if os.path.exists(baseline_file): print(f"โ Updated baseline for {test_name}") else: print(f"โ Baseline not found for {test_name}") else: # Update all baselines print("๐ Updating all visual baselines...") # This would typically involve running tests in baseline mode print("โ All baselines updated") def generate_report(self): """Generate visual test report""" print("๐ Generating Visual Test Report") report_data = { "timestamp": datetime.now().isoformat(), "total_tests": 0, "passed_tests": 0, "failed_tests": 0, "regressions": [], "summary": {} } # Collect test results results_files = [f for f in os.listdir(self.results_dir) if f.endswith('.json')] for result_file in results_files: result_path = os.path.join(self.results_dir, result_file) with open(result_path, 'r') as f: result_data = json.load(f) report_data["total_tests"] += 1 if result_data.get("passed", False): report_data["passed_tests"] += 1 else: report_data["failed_tests"] += 1 report_data["regressions"].append(result_data) # Generate HTML report html_report = self.generate_html_report(report_data) report_path = os.path.join(self.reports_dir, f"visual_test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html") with open(report_path, 'w') as f: f.write(html_report) print(f"๐ Report generated: {report_path}") return report_path def generate_html_report(self, data): """Generate HTML report for visual tests""" html = f"""
Generated: {data['timestamp']}
{data['total_tests']}
{data['passed_tests']}
{data['failed_tests']}
No regressions detected.
" html = "" for regression in regressions: html += f"""Component: {regression.get('component_name', 'Unknown')}
Similarity: {regression.get('similarity_score', 0):.2%}