#!/usr/bin/env python3
"""
Fixed Selenium Website Accessibility Tester
"""



import json
import time
import csv
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, WebDriverException
from axe_selenium_python import Axe
import os

class TestSeleniumWebSiteAccessibility:
    def __init__(self, headless=True):
        self.driver = None
        self.headless = headless
        self.results = []
        
        # URLs to test on selenium.dev
        self.test_urls = [
            "https://www.selenium.dev/",
            "https://www.selenium.dev/about/",
            "https://www.selenium.dev/project/",
            "https://www.selenium.dev/events/",
            "https://www.selenium.dev/ecosystem/",
            "https://www.selenium.dev/history/",
            "https://www.selenium.dev/getinvolved/",
            "https://www.selenium.dev/sponsors/",
            "https://www.selenium.dev/sponsor/",
            "https://www.selenium.dev/downloads/",
            "https://www.selenium.dev/documentation/",
            "https://www.selenium.dev/projects/",
             "https://www.selenium.dev/support/",
            "https://www.selenium.dev/blog/"
        ]
        
    def setup_driver(self):
        """Initialize Chrome WebDriver"""
        print("🚀 Setting up Chrome WebDriver...")
        
        options = Options()
        if self.headless:
            options.add_argument("--headless")
        
        # Basic options for stable testing
        options.add_argument("--no-sandbox")
        options.add_argument("--disable-dev-shm-usage")
        options.add_argument("--window-size=1920,1080")
        options.add_argument("--disable-gpu")
        options.add_argument("--disable-extensions")
        
        try:
            self.driver = webdriver.Chrome(options=options)
            self.driver.implicitly_wait(10)
        except Exception as e:
            print(f"❌ Failed to initialize WebDriver: {e}")
            print("💡 Make sure Chrome browser is installed")
            raise
    
    def test_page(self, url):
        """Test a single page for accessibility issues"""
        print(f"\n🔍 Testing: {url}")
        
        try:
            # Load page with timeout
            self.driver.get(url)
            
            # Wait for page to load
            WebDriverWait(self.driver, 15).until(
                EC.presence_of_element_located((By.TAG_NAME, "body"))
            )
            time.sleep(2)  # Allow dynamic content to load
            
            # Run accessibility test
            axe = Axe(self.driver)
            axe.inject()
            
            # Test for WCAG AA compliance
            results = axe.run({
                "runOnly": {
                    "type": "tag", 
                    "values": ["wcag2a", "wcag2aa", "wcag21aa"]
                }
            })
            
            # Store results with better error handling
            page_data = {
                'url': url,
                'title': self.driver.title,
                'timestamp': datetime.now().isoformat(),
                'violations': results.get('violations', []),
                'violation_count': len(results.get('violations', []))
            }
            
            self.results.append(page_data)
            
            # Print summary
            violation_count = len(results.get('violations', []))
            if violation_count > 0:
                print(f"⚠️  Found {violation_count} accessibility issues:")
                
                # Group by severity
                violations = results.get('violations', [])
                critical = [v for v in violations if v.get('impact') == 'critical']
                serious = [v for v in violations if v.get('impact') == 'serious']
                moderate = [v for v in violations if v.get('impact') == 'moderate']
                minor = [v for v in violations if v.get('impact') == 'minor']
                
                if critical:
                    print(f"   🔴 {len(critical)} CRITICAL issues")
                if serious:
                    print(f"   🟠 {len(serious)} SERIOUS issues")
                if moderate:
                    print(f"   🟡 {len(moderate)} MODERATE issues")
                if minor:
                    print(f"   🔵 {len(minor)} MINOR issues")
                    
                # Show most important issues
                important_issues = critical + serious
                for issue in important_issues[:3]:  # Show top 3
                    print(f"      • {issue.get('id', 'Unknown')}: {issue.get('help', 'No description')}")
                    
            else:
                print("✅ No accessibility violations found!")
                
        except TimeoutException:
            print(f"⏰ Timeout loading {url}")
            self.results.append({
                'url': url,
                'title': 'Timeout',
                'timestamp': datetime.now().isoformat(),
                'violations': [],
                'violation_count': 0,
                'error': 'Page load timeout'
            })
        except Exception as e:
            print(f"❌ Error testing {url}: {e}")
            self.results.append({
                'url': url,
                'title': 'Error',
                'timestamp': datetime.now().isoformat(),
                'violations': [],
                'violation_count': 0,
                'error': str(e)
            })
    
    def run_tests(self):
        """Run accessibility tests on all pages"""
        print("🧪 Starting Selenium.dev Accessibility Testing")
        print(f"📋 Testing {len(self.test_urls)} pages\n")
        
        self.setup_driver()
        
        try:
            for i, url in enumerate(self.test_urls, 1):
                print(f"{'='*60}")
                print(f"Page {i}/{len(self.test_urls)}")
                self.test_page(url)
                time.sleep(1)  # Brief pause between requests
                
        finally:
            if self.driver:
                self.driver.quit()
                print("\n🔒 WebDriver closed")
    
    def print_summary(self):
        """Print test summary to console"""
        if not self.results:
            print("No results to summarize")
            return
            
        print(f"\n{'='*60}")
        print("📊 ACCESSIBILITY TEST SUMMARY")
        print(f"{'='*60}")
        
        total_pages = len(self.results)
        total_violations = sum(r.get('violation_count', 0) for r in self.results)
        pages_with_issues = len([r for r in self.results if r.get('violation_count', 0) > 0])
        
        print(f"📈 Overall Statistics:")
        print(f"   • Pages tested: {total_pages}")
        print(f"   • Pages with issues: {pages_with_issues}")
        print(f"   • Total violations: {total_violations}")
        if total_pages > 0:
            print(f"   • Average per page: {total_violations/total_pages:.1f}")
        
        # Find most common issues
        all_issues = {}
        critical_pages = []
        
        for result in self.results:
            if result.get('violation_count', 0) > 0:
                for violation in result.get('violations', []):
                    issue_id = violation.get('id', 'unknown')
                    all_issues[issue_id] = all_issues.get(issue_id, 0) + 1
                    
                    if violation.get('impact') == 'critical':
                        critical_pages.append(result['url'])
        
        if all_issues:
            print(f"\n🔥 Most Common Issues:")
            sorted_issues = sorted(all_issues.items(), key=lambda x: x[1], reverse=True)
            for issue, count in sorted_issues[:5]:
                print(f"   • {issue}: appears on {count} pages")
        
        if critical_pages:
            print(f"\n🚨 Pages with CRITICAL issues:")
            # FIX: Convert set to list before slicing
            unique_critical_pages = list(set(critical_pages))
            for page in unique_critical_pages[:5]:  # Show first 5
                print(f"   • {page}")
    
    def save_reports(self):
        """Save detailed reports to files"""
        print(f"\n💾 SAVING REPORTS")
        print(f"Current working directory: {os.getcwd()}")
        print(f"Results count: {len(self.results)}")
        
        if not self.results:
            print("❌ No results to save!")
            return
        
        # Create reports directory
        current_dir = os.getcwd()
        reports_dir = os.path.join(current_dir, "accessibility_reports")
        
        print(f"📁 Creating directory: {reports_dir}")
        
        try:
            os.makedirs(reports_dir, exist_ok=True)
            print(f"✅ Directory created: {os.path.exists(reports_dir)}")
        except Exception as e:
            print(f"❌ Failed to create directory: {e}")
            return
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        #Save human-readable report
        txt_filename = f"selenium_report_{timestamp}.txt"
        txt_path = os.path.join(reports_dir, txt_filename)
        
        print(f"📝 Saving text report to: {txt_path}")
        
        try:
            with open(txt_path, 'w', encoding='utf-8') as f:
                f.write("SELENIUM.DEV ACCESSIBILITY REPORT\n")
                f.write("=" * 50 + "\n")
                f.write(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"Working Directory: {current_dir}\n")
                f.write(f"Reports Directory: {reports_dir}\n\n")
                
                for result in self.results:
                    f.write(f"URL: {result.get('url', 'N/A')}\n")
                    f.write(f"Title: {result.get('title', 'N/A')}\n")
                    f.write(f"Violations: {result.get('violation_count', 0)}\n")
                    
                    if result.get('error'):
                        f.write(f"Error: {result['error']}\n")
                    
                    if result.get('violation_count', 0) > 0:
                        for violation in result.get('violations', []):
                            impact = violation.get('impact', 'unknown').upper()
                            f.write(f"  [{impact}] {violation.get('id', 'Unknown')}\n")
                            f.write(f"    {violation.get('help', 'No description')}\n")
                            f.write(f"    {violation.get('description', 'No details')}\n\n")
                    else:
                        f.write("✅ No violations\n")
                        
                    f.write("-" * 50 + "\n\n")
            
            # Verify file was created
            if os.path.exists(txt_path):
                size = os.path.getsize(txt_path)
                print(f"✅ Text file created: {size} bytes")
            else:
                print(f"❌ Text file NOT found after creation!")
                
        except Exception as e:
            print(f"❌ Failed to save text report: {e}")
            import traceback
            traceback.print_exc()
        
        # 4. List all files in the directory
        print(f"\n📂 Final directory listing for: {reports_dir}")
        try:
            files = os.listdir(reports_dir)
            if files:
                for file in files:
                    file_path = os.path.join(reports_dir, file)
                    size = os.path.getsize(file_path)
                    print(f"   📄 {file} ({size} bytes)")
            else:
                print("   📭 Directory is empty!")
        except Exception as e:
            print(f"❌ Cannot list directory: {e}")
        
        print(f"\n🎉 Reports saved in: {reports_dir}")

def main():
    """Main function"""
    print("🌟 Fixed Selenium.dev Accessibility Tester")
    print("Using axe-core for WCAG compliance testing\n")
    
    # Check if axe-selenium-python is installed
    try:
        import axe_selenium_python
        print("✅ axe-selenium-python is available")
    except ImportError:
        print("❌ ERROR: axe-selenium-python is not installed")
        print("📦 Install it with: pip install axe-selenium-python")
        return
    
    tester = TestSeleniumWebSiteAccessibility(headless=True)
    
    try:
        # Run all tests
        tester.run_tests()
        
        # Show summary
        tester.print_summary()
        
        # Save reports
        tester.save_reports()
        
        print(f"\n🎯 Next Steps:")
        print("1. Review the generated reports")
        print("2. Fix CRITICAL and SERIOUS issues first")
        print("3. Focus on color contrast issues")
        print("4. Test with real screen readers")
        
    except KeyboardInterrupt:
        print("\n⏹️  Testing stopped by user")
    except Exception as e:
        print(f"\n❌ Error: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()