#!/usr/bin/env python3
"""
Flask HTML-Formular Test Automator - Frontend-Fokussierter Browser-Tester
=========================================================================

Automatisierte Tests für HTML-Formulare durch echte Browser-Interaktionen.
Testet die tatsächliche Benutzeroberfläche mit JavaScript-Validierungen,
dynamischen Elementen und realistischen User-Interaktionen.

Autor: Till Tomczak  
Version: 1.0
Mercedes-Benz Projektarbeit MYP
"""

import asyncio
import json
import time
import random
import re
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass, asdict
from enum import Enum

# Browser-Automation
try:
    from playwright.async_api import async_playwright, Page, Browser, BrowserContext
    PLAYWRIGHT_AVAILABLE = True
except ImportError:
    PLAYWRIGHT_AVAILABLE = False
    print("⚠️ Playwright nicht verfügbar. Installiere mit: pip install playwright")
    # Fallback-Klassen für Type Hints
    class Page: pass
    class Browser: pass
    class BrowserContext: pass

# Test-Daten-Generierung  
try:
    from faker import Faker
    FAKER_AVAILABLE = True
except ImportError:
    FAKER_AVAILABLE = False
    print("⚠️ Faker nicht verfügbar. Installiere mit: pip install faker")
    # Fallback-Klasse
    class Faker:
        def __init__(self, locale='de_DE'): pass
        def email(self): return "test@example.com"
        def name(self): return "Test User"
        def first_name(self): return "Test"
        def last_name(self): return "User"
        def company(self): return "Test Company"
        def city(self): return "Test City"
        def street_address(self): return "Test Street 123"
        def phone_number(self): return "+49 123 4567890"
        def url(self): return "https://example.com"
        def date(self): return "2024-06-18"
        def text(self, max_nb_chars=200): return "Test text"

# HTML-Parsing
try:
    from bs4 import BeautifulSoup
    BS4_AVAILABLE = True
except ImportError:
    BS4_AVAILABLE = False
    print("⚠️ BeautifulSoup nicht verfügbar. Installiere mit: pip install beautifulsoup4")
    # Fallback-Klasse
    class BeautifulSoup:
        def __init__(self, *args, **kwargs): pass

# Rich Console für schöne Ausgabe
try:
    from rich.console import Console
    from rich.table import Table
    from rich.progress import Progress
    from rich.panel import Panel
    from rich.text import Text
    RICH_AVAILABLE = True
    console = Console()
except ImportError:
    RICH_AVAILABLE = False
    console = None
    # Fallback-Klassen
    class Console:
        def print(self, *args, **kwargs): print(*args)
    class Table:
        def __init__(self, *args, **kwargs): pass
        def add_column(self, *args, **kwargs): pass
        def add_row(self, *args, **kwargs): pass


class TestStatus(Enum):
    """Status-Enumerierung für Tests"""
    PASSED = "✅ BESTANDEN"
    FAILED = "❌ FEHLGESCHLAGEN"
    WARNING = "⚠️ WARNUNG"
    SKIPPED = "⏭️ ÜBERSPRUNGEN"


@dataclass
class FormField:
    """Repräsentiert ein Formular-Feld mit allen Attributen"""
    name: str
    field_type: str
    selector: str
    label: str = ""
    placeholder: str = ""
    required: bool = False
    pattern: str = ""
    min_length: int = 0
    max_length: int = 0
    min_value: str = ""
    max_value: str = ""
    options: List[str] = None
    validation_message: str = ""
    
    def __post_init__(self):
        if self.options is None:
            self.options = []


@dataclass  
class FormStructure:
    """Repräsentiert die Struktur eines HTML-Formulars"""
    selector: str
    action: str
    method: str
    fields: List[FormField]
    submit_button: str = ""
    is_multi_step: bool = False
    csrf_token_field: str = ""
    enctype: str = "application/x-www-form-urlencoded"


@dataclass
class TestResult:
    """Ergebnis eines Formular-Tests"""
    form_selector: str
    test_type: str
    status: TestStatus
    message: str
    screenshot_path: str = ""
    execution_time: float = 0.0
    details: Dict[str, Any] = None
    
    def __post_init__(self):
        if self.details is None:
            self.details = {}


class FrontendTestDataGenerator:
    """
    Generiert realistische Test-Daten für HTML-Formulare basierend auf
    Feld-Attributen und semantischen Hinweisen.
    """
    
    def __init__(self, locale: str = 'de_DE'):
        self.fake = Faker(locale) if FAKER_AVAILABLE else None
        
        # Mapping von Input-Types zu Generatoren
        self.type_generators = {
            'email': self._generate_email,
            'password': self._generate_password, 
            'tel': self._generate_phone,
            'url': self._generate_url,
            'date': self._generate_date,
            'datetime-local': self._generate_datetime,
            'time': self._generate_time,
            'number': self._generate_number,
            'range': self._generate_range,
            'color': self._generate_color,
            'text': self._generate_text,
            'textarea': self._generate_text
        }
        
        # Pattern-basierte Generatoren
        self.pattern_generators = {
            r'[0-9]{5}': lambda: str(random.randint(10000, 99999)),  # PLZ
            r'[0-9]{3,4}': lambda: str(random.randint(100, 9999)),   # Kurze Zahlen
            r'[A-Za-z]+': lambda: self.fake.word() if self.fake else "TestWort",
            r'[A-Z]{2,3}': lambda: ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ', k=3))
        }
    
    def generate_for_field(self, field: FormField, scenario: str = 'valid') -> str:
        """
        Generiert Test-Daten für ein spezifisches Feld.
        
        Args:
            field: Das Formular-Feld
            scenario: 'valid', 'invalid', 'edge_case', 'empty'
        """
        if scenario == 'empty':
            return ""
        
        # Erst Pattern prüfen
        if field.pattern and scenario == 'valid':
            for pattern, generator in self.pattern_generators.items():
                if re.match(pattern, field.pattern):
                    return generator()
        
        # Dann Type-basierten Generator verwenden
        generator = self.type_generators.get(field.field_type, self._generate_text)
        
        if scenario == 'valid':
            return generator(field)
        elif scenario == 'invalid':
            return self._generate_invalid_data(field)
        elif scenario == 'edge_case':
            return self._generate_edge_case(field)
        
        return generator(field)
    
    def _generate_email(self, field: FormField = None) -> str:
        if self.fake:
            return self.fake.email()
        return f"test{random.randint(1000, 9999)}@example.com"
    
    def _generate_password(self, field: FormField = None) -> str:
        """Generiert sichere Passwörter"""
        if field and field.min_length > 0:
            length = max(field.min_length, 8)
        else:
            length = 12
        
        chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
        return ''.join(random.choices(chars, k=length))
    
    def _generate_phone(self, field: FormField = None) -> str:
        if self.fake:
            return self.fake.phone_number()
        return f"+49 {random.randint(100, 999)} {random.randint(1000000, 9999999)}"
    
    def _generate_url(self, field: FormField = None) -> str:
        if self.fake:
            return self.fake.url()
        return f"https://example{random.randint(1, 100)}.com"
    
    def _generate_date(self, field: FormField = None) -> str:
        if self.fake:
            return self.fake.date()
        return "2024-06-18"
    
    def _generate_datetime(self, field: FormField = None) -> str:
        return f"{self._generate_date()}T{self._generate_time()}"
    
    def _generate_time(self, field: FormField = None) -> str:
        return f"{random.randint(0, 23):02d}:{random.randint(0, 59):02d}"
    
    def _generate_number(self, field: FormField) -> str:
        if field.min_value and field.max_value:
            try:
                min_val = int(field.min_value)
                max_val = int(field.max_value)
                return str(random.randint(min_val, max_val))
            except ValueError:
                pass
        return str(random.randint(1, 1000))
    
    def _generate_range(self, field: FormField) -> str:
        return self._generate_number(field)
    
    def _generate_color(self, field: FormField = None) -> str:
        return f"#{random.randint(0, 0xFFFFFF):06x}"
    
    def _generate_text(self, field: FormField) -> str:
        """Generiert Text basierend auf Feld-Eigenschaften"""
        
        # Intelligente Generierung basierend auf Namen/Labels
        field_name_lower = field.name.lower()
        label_lower = field.label.lower() if field.label else ""
        
        if any(keyword in field_name_lower + label_lower for keyword in ['name', 'vorname', 'nachname', 'firma']):
            if self.fake:
                if 'vorname' in field_name_lower or 'first' in field_name_lower:
                    return self.fake.first_name()
                elif 'nachname' in field_name_lower or 'last' in field_name_lower:
                    return self.fake.last_name()
                elif 'firma' in field_name_lower or 'company' in field_name_lower:
                    return self.fake.company()
                else:
                    return self.fake.name()
        
        if any(keyword in field_name_lower + label_lower for keyword in ['stadt', 'city', 'ort']):
            return self.fake.city() if self.fake else "München"
        
        if any(keyword in field_name_lower + label_lower for keyword in ['straße', 'adresse', 'address']):
            return self.fake.street_address() if self.fake else "Teststraße 123"
        
        # Standard-Text basierend auf Länge
        if field.max_length > 0:
            if field.max_length <= 20:
                return "Kurzer Test"
            elif field.max_length <= 100:
                return "Dies ist ein mittellanger Testtext für das Formular."
            else:
                return self.fake.text(max_nb_chars=field.max_length) if self.fake else "Langer Testtext " * 10
        
        return "Test Eingabe"
    
    def _generate_invalid_data(self, field: FormField) -> str:
        """Generiert bewusst ungültige Daten für Validierungstests"""
        
        if field.field_type == 'email':
            return "ungueltige-email"
        elif field.field_type == 'url':
            return "keine-url"
        elif field.field_type == 'number':
            return "nicht-numerisch"
        elif field.pattern:
            return "passt-nicht-zum-pattern"
        elif field.max_length > 0:
            return "x" * (field.max_length + 10)  # Zu lang
        
        return "🚫 Ungültige Eingabe ñäöü"
    
    def _generate_edge_case(self, field: FormField) -> str:
        """Generiert Edge-Cases für robuste Tests"""
        
        edge_cases = [
            "' OR 1=1 --",  # SQL Injection
            "<script>alert('xss')</script>",  # XSS
            "../../etc/passwd",  # Path Traversal
            "NULL\x00",  # Null Byte
            "ñäöüßÀÁÂÃÄÅ",  # Unicode
            "👨‍💻🚀💻",  # Emojis
            "\n\r\t",  # Whitespace
            "   ",  # Nur Leerzeichen
        ]
        
        return random.choice(edge_cases)


class FormInteractionEngine:
    """
    Simuliert realistische Benutzer-Interaktionen mit HTML-Formularen.
    Verwendet menschliche Timing-Muster und natürliche Mausbewegungen.
    """
    
    def __init__(self, page: Page):
        self.page = page
        self.human_delay_min = 50  # Minimale Tipp-Verzögerung (ms)
        self.human_delay_max = 150  # Maximale Tipp-Verzögerung (ms)
        
    async def fill_form_like_human(self, form: FormStructure, test_data: Dict[str, str]) -> List[TestResult]:
        """
        Füllt ein Formular wie ein echter Mensch aus.
        
        Args:
            form: Die Formular-Struktur
            test_data: Die einzutragenden Daten
        """
        results = []
        
        try:
            # Formular in Sicht scrollen
            await self.page.locator(form.selector).scroll_into_view_if_needed()
            await self._human_pause()
            
            for field in form.fields:
                if field.name in test_data:
                    result = await self._fill_field_humanlike(field, test_data[field.name])
                    results.append(result)
            
            return results
            
        except Exception as e:
            return [TestResult(
                form_selector=form.selector,
                test_type="form_filling",
                status=TestStatus.FAILED,
                message=f"Fehler beim Ausfüllen: {str(e)}"
            )]
    
    async def _fill_field_humanlike(self, field: FormField, value: str) -> TestResult:
        """Füllt ein einzelnes Feld mit menschlichem Verhalten"""
        
        try:
            field_element = self.page.locator(field.selector)
            
            # Warten bis Feld sichtbar ist
            await field_element.wait_for(state="visible", timeout=5000)
            
            # Zu Feld scrollen
            await field_element.scroll_into_view_if_needed()
            await self._human_pause(100, 300)
            
            # Feld anklicken (nicht nur fokussieren)
            await field_element.click()
            await self._human_pause()
            
            # Existierenden Inhalt löschen
            await self.page.keyboard.press("Control+a")
            await self._human_pause(50, 100)
            
            # Spezielle Behandlung nach Feld-Typ
            if field.field_type in ['select', 'select-one']:
                await self._select_option_humanlike(field_element, value)
            elif field.field_type == 'checkbox':
                if value.lower() in ['true', '1', 'on', 'yes']:
                    await field_element.check()
            elif field.field_type == 'radio':
                await field_element.check()
            elif field.field_type == 'file':
                await field_element.set_input_files(value)
            else:
                # Text-Input mit menschlicher Geschwindigkeit
                await self._type_like_human(value)
            
            # Kurze Pause nach Eingabe
            await self._human_pause()
            
            # Tab zur nächsten Feld (menschliches Verhalten)
            await self.page.keyboard.press("Tab")
            
            return TestResult(
                form_selector=field.selector,
                test_type="field_filling",
                status=TestStatus.PASSED,
                message=f"Feld '{field.name}' erfolgreich ausgefüllt"
            )
            
        except Exception as e:
            return TestResult(
                form_selector=field.selector,
                test_type="field_filling", 
                status=TestStatus.FAILED,
                message=f"Fehler bei Feld '{field.name}': {str(e)}"
            )
    
    async def _select_option_humanlike(self, select_element, value: str):
        """Wählt Option in Select-Element wie ein Mensch"""
        
        # Dropdown öffnen
        await select_element.click()
        await self._human_pause(200, 400)
        
        # Option suchen und klicken
        option_selector = f"option[value='{value}'], option:has-text('{value}')"
        try:
            await self.page.click(option_selector)
        except:
            # Fallback: erste Option wählen
            await self.page.click("option:first-child")
    
    async def _type_like_human(self, text: str):
        """Tippt Text mit menschlicher Geschwindigkeit und gelegentlichen Fehlern"""
        
        for char in text:
            # Gelegentliche "Tippfehler" und Korrekturen (5% Chance)
            if random.random() < 0.05 and char.isalpha():
                # Falscher Buchstabe
                wrong_char = random.choice('abcdefghijklmnopqrstuvwxyz')
                await self.page.keyboard.type(wrong_char, delay=self._random_delay())
                await self._human_pause(100, 200)
                
                # Korrigieren
                await self.page.keyboard.press("Backspace")
                await self._human_pause(50, 150)
            
            # Richtiger Buchstabe
            await self.page.keyboard.type(char, delay=self._random_delay())
            
            # Gelegentliche längere Pausen (Nachdenken)
            if random.random() < 0.1:
                await self._human_pause(500, 1000)
    
    async def test_form_validations(self, form: FormStructure) -> List[TestResult]:
        """
        Testet alle visuellen Validierungen eines Formulars.
        """
        results = []
        
        # 1. Teste Required-Feld-Validierungen
        required_test = await self._test_required_fields(form)
        results.extend(required_test)
        
        # 2. Teste Pattern-Validierungen
        pattern_test = await self._test_pattern_validations(form)
        results.extend(pattern_test)
        
        # 3. Teste Längen-Validierungen
        length_test = await self._test_length_validations(form)
        results.extend(length_test)
        
        return results
    
    async def _test_required_fields(self, form: FormStructure) -> List[TestResult]:
        """Testet Required-Feld-Validierungen"""
        results = []
        
        try:
            # Versuche zu submitten ohne Required-Felder
            if form.submit_button:
                await self.page.click(form.submit_button)
                await self._human_pause(500, 1000)
                
                # Prüfe auf Validierungsmeldungen
                for field in form.fields:
                    if field.required:
                        validation_visible = await self._check_validation_message_visible(field)
                        
                        status = TestStatus.PASSED if validation_visible else TestStatus.FAILED
                        message = "Required-Validierung sichtbar" if validation_visible else "Keine Required-Validierung gefunden"
                        
                        results.append(TestResult(
                            form_selector=field.selector,
                            test_type="required_validation",
                            status=status,
                            message=message
                        ))
            
        except Exception as e:
            results.append(TestResult(
                form_selector=form.selector,
                test_type="required_validation",
                status=TestStatus.FAILED,
                message=f"Fehler bei Required-Test: {str(e)}"
            ))
        
        return results
    
    async def _test_pattern_validations(self, form: FormStructure) -> List[TestResult]:
        """Testet Pattern-basierte Validierungen"""
        results = []
        
        for field in form.fields:
            if field.pattern:
                try:
                    # Ungültiges Pattern eingeben
                    await self.page.fill(field.selector, "ungültiges-pattern")
                    await self.page.keyboard.press("Tab")  # Trigger Validation
                    await self._human_pause(300, 500)
                    
                    # Prüfe Validierungsmeldung
                    validation_visible = await self._check_validation_message_visible(field)
                    
                    status = TestStatus.PASSED if validation_visible else TestStatus.FAILED
                    message = f"Pattern-Validierung für '{field.pattern}' funktioniert" if validation_visible else f"Pattern-Validierung für '{field.pattern}' fehlt"
                    
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="pattern_validation",
                        status=status,
                        message=message
                    ))
                    
                except Exception as e:
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="pattern_validation",
                        status=TestStatus.FAILED,
                        message=f"Fehler bei Pattern-Test: {str(e)}"
                    ))
        
        return results
    
    async def _test_length_validations(self, form: FormStructure) -> List[TestResult]:
        """Testet Längen-Validierungen"""
        results = []
        
        for field in form.fields:
            if field.max_length > 0:
                try:
                    # Zu langen Text eingeben
                    long_text = "x" * (field.max_length + 10)
                    await self.page.fill(field.selector, long_text)
                    await self.page.keyboard.press("Tab")
                    await self._human_pause(300, 500)
                    
                    # Prüfe ob Text abgeschnitten wurde oder Validierung angezeigt wird
                    actual_value = await self.page.input_value(field.selector)
                    validation_visible = await self._check_validation_message_visible(field)
                    
                    if len(actual_value) <= field.max_length or validation_visible:
                        status = TestStatus.PASSED
                        message = f"Längen-Validierung (max: {field.max_length}) funktioniert"
                    else:
                        status = TestStatus.FAILED
                        message = f"Längen-Validierung (max: {field.max_length}) nicht wirksam"
                    
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="length_validation",
                        status=status,
                        message=message
                    ))
                    
                except Exception as e:
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="length_validation",
                        status=TestStatus.FAILED,
                        message=f"Fehler bei Längen-Test: {str(e)}"
                    ))
        
        return results
    
    async def _check_validation_message_visible(self, field: FormField) -> bool:
        """Prüft ob eine Validierungsmeldung sichtbar ist"""
        
        # Verschiedene Selektoren für Validierungsmeldungen
        validation_selectors = [
            f"{field.selector}:invalid",
            f"{field.selector} + .error",
            f"{field.selector} + .invalid-feedback",
            f"{field.selector} ~ .error-message",
            ".field-error",
            ".validation-error",
            "[role='alert']",
            ".alert-danger",
            ".text-danger"
        ]
        
        for selector in validation_selectors:
            try:
                element = self.page.locator(selector)
                if await element.count() > 0 and await element.is_visible():
                    return True
            except:
                continue
        
        # Prüfe auch HTML5-Validierungsmeldungen
        try:
            validation_message = await self.page.evaluate(f"""
                document.querySelector('{field.selector}').validationMessage
            """)
            return bool(validation_message)
        except:
            pass
        
        return False
    
    async def test_dynamic_form_behavior(self, form: FormStructure) -> List[TestResult]:
        """
        Testet dynamisches Formular-Verhalten wie Conditional Fields.
        """
        results = []
        
        # Teste JavaScript-basierte Feld-Anzeige/Verstecken
        initial_field_count = len([f for f in form.fields if await self.page.locator(f.selector).is_visible()])
        
        # Interagiere mit Feldern und prüfe Änderungen
        for field in form.fields:
            if field.field_type in ['select', 'radio', 'checkbox']:
                try:
                    # Zustand vor Änderung
                    visible_fields_before = await self._get_visible_field_count(form)
                    
                    # Feld ändern
                    if field.field_type == 'checkbox':
                        await self.page.locator(field.selector).check()
                    elif field.options:
                        await self.page.select_option(field.selector, field.options[0])
                    
                    await self._human_pause(500, 1000)  # Warten auf JavaScript
                    
                    # Zustand nach Änderung
                    visible_fields_after = await self._get_visible_field_count(form)
                    
                    if visible_fields_before != visible_fields_after:
                        results.append(TestResult(
                            form_selector=field.selector,
                            test_type="dynamic_behavior",
                            status=TestStatus.PASSED,
                            message=f"Dynamisches Verhalten erkannt: {visible_fields_before} → {visible_fields_after} Felder"
                        ))
                    
                except Exception as e:
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="dynamic_behavior",
                        status=TestStatus.FAILED,
                        message=f"Fehler bei Dynamic-Test: {str(e)}"
                    ))
        
        return results
    
    async def _get_visible_field_count(self, form: FormStructure) -> int:
        """Zählt sichtbare Felder in einem Formular"""
        count = 0
        for field in form.fields:
            try:
                if await self.page.locator(field.selector).is_visible():
                    count += 1
            except:
                pass
        return count
    
    async def _human_pause(self, min_ms: int = 100, max_ms: int = 300):
        """Simuliert menschliche Pausen"""
        delay = random.randint(min_ms, max_ms)
        await asyncio.sleep(delay / 1000)
    
    def _random_delay(self) -> int:
        """Zufällige Tipp-Verzögerung"""
        return random.randint(self.human_delay_min, self.human_delay_max)


class VisualFormValidator:
    """
    Validiert visuelle Aspekte von Formularen wie Accessibility,
    Responsive-Design und Benutzerfreundlichkeit.
    """
    
    def __init__(self, page: Page):
        self.page = page
    
    async def check_form_accessibility(self, form: FormStructure) -> List[TestResult]:
        """
        Prüft Accessibility-Aspekte eines Formulars.
        """
        results = []
        
        # 1. Label-Zuordnung prüfen
        label_results = await self._check_label_associations(form)
        results.extend(label_results)
        
        # 2. ARIA-Attribute prüfen
        aria_results = await self._check_aria_attributes(form)
        results.extend(aria_results)
        
        # 3. Keyboard-Navigation testen
        keyboard_results = await self._test_keyboard_navigation(form)
        results.extend(keyboard_results)
        
        # 4. Kontrast prüfen
        contrast_results = await self._check_color_contrast(form)
        results.extend(contrast_results)
        
        return results
    
    async def _check_label_associations(self, form: FormStructure) -> List[TestResult]:
        """Prüft ob alle Formular-Felder korrekte Labels haben"""
        results = []
        
        for field in form.fields:
            try:
                # Verschiedene Label-Zuordnungsmethoden prüfen
                has_label = await self.page.evaluate(f"""
                    (() => {{
                        const field = document.querySelector('{field.selector}');
                        if (!field) return false;
                        
                        // 1. Explizites Label mit for-Attribut
                        const labelByFor = document.querySelector(`label[for="${{field.id}}"]`);
                        if (labelByFor) return true;
                        
                        // 2. Umschließendes Label
                        const parentLabel = field.closest('label');
                        if (parentLabel) return true;
                        
                        // 3. ARIA-Label
                        if (field.getAttribute('aria-label')) return true;
                        
                        // 4. ARIA-Labelledby
                        if (field.getAttribute('aria-labelledby')) return true;
                        
                        return false;
                    }})()
                """)
                
                status = TestStatus.PASSED if has_label else TestStatus.FAILED
                message = "Label korrekt zugeordnet" if has_label else "Kein Label gefunden"
                
                results.append(TestResult(
                    form_selector=field.selector,
                    test_type="accessibility_labels",
                    status=status,
                    message=message
                ))
                
            except Exception as e:
                results.append(TestResult(
                    form_selector=field.selector,
                    test_type="accessibility_labels",
                    status=TestStatus.FAILED,
                    message=f"Fehler bei Label-Prüfung: {str(e)}"
                ))
        
        return results
    
    async def _check_aria_attributes(self, form: FormStructure) -> List[TestResult]:
        """Prüft ARIA-Attribute für bessere Accessibility"""
        results = []
        
        for field in form.fields:
            try:
                aria_info = await self.page.evaluate(f"""
                    (() => {{
                        const field = document.querySelector('{field.selector}');
                        if (!field) return {{}};
                        
                        return {{
                            hasAriaLabel: !!field.getAttribute('aria-label'),
                            hasAriaLabelledBy: !!field.getAttribute('aria-labelledby'),
                            hasAriaDescribedBy: !!field.getAttribute('aria-describedby'),
                            hasAriaRequired: !!field.getAttribute('aria-required'),
                            hasAriaInvalid: !!field.getAttribute('aria-invalid'),
                            role: field.getAttribute('role')
                        }};
                    }})()
                """)
                
                # Bewerte ARIA-Vollständigkeit
                aria_score = sum([
                    aria_info.get('hasAriaLabel', False),
                    aria_info.get('hasAriaLabelledBy', False),
                    aria_info.get('hasAriaDescribedBy', False),
                    aria_info.get('hasAriaRequired', False) if field.required else True,
                    True  # Basis-Punkt
                ])
                
                if aria_score >= 3:
                    status = TestStatus.PASSED
                    message = "ARIA-Attribute ausreichend vorhanden"
                elif aria_score >= 2:
                    status = TestStatus.WARNING
                    message = "ARIA-Attribute teilweise vorhanden"
                else:
                    status = TestStatus.FAILED
                    message = "ARIA-Attribute unzureichend"
                
                results.append(TestResult(
                    form_selector=field.selector,
                    test_type="accessibility_aria",
                    status=status,
                    message=message,
                    details=aria_info
                ))
                
            except Exception as e:
                results.append(TestResult(
                    form_selector=field.selector,
                    test_type="accessibility_aria",
                    status=TestStatus.FAILED,
                    message=f"Fehler bei ARIA-Prüfung: {str(e)}"
                ))
        
        return results
    
    async def _test_keyboard_navigation(self, form: FormStructure) -> List[TestResult]:
        """Testet Keyboard-Navigation durch das Formular"""
        results = []
        
        try:
            # Zum ersten Feld navigieren
            if form.fields:
                first_field = form.fields[0]
                await self.page.locator(first_field.selector).focus()
                
                # Durch alle Felder tabben
                focusable_count = 0
                for i, field in enumerate(form.fields):
                    try:
                        # Tab-Taste drücken
                        if i > 0:
                            await self.page.keyboard.press("Tab")
                            await asyncio.sleep(0.1)
                        
                        # Prüfen ob Feld fokussiert ist
                        is_focused = await self.page.evaluate(f"""
                            document.activeElement === document.querySelector('{field.selector}')
                        """)
                        
                        if is_focused:
                            focusable_count += 1
                    
                    except Exception:
                        pass
                
                # Bewertung
                expected_focusable = len([f for f in form.fields if f.field_type not in ['hidden']])
                focus_ratio = focusable_count / expected_focusable if expected_focusable > 0 else 0
                
                if focus_ratio >= 0.8:
                    status = TestStatus.PASSED
                    message = f"Keyboard-Navigation funktioniert ({focusable_count}/{expected_focusable} Felder erreichbar)"
                elif focus_ratio >= 0.5:
                    status = TestStatus.WARNING  
                    message = f"Keyboard-Navigation teilweise funktionsfähig ({focusable_count}/{expected_focusable} Felder)"
                else:
                    status = TestStatus.FAILED
                    message = f"Keyboard-Navigation problematisch ({focusable_count}/{expected_focusable} Felder)"
                
                results.append(TestResult(
                    form_selector=form.selector,
                    test_type="accessibility_keyboard",
                    status=status,
                    message=message
                ))
        
        except Exception as e:
            results.append(TestResult(
                form_selector=form.selector,
                test_type="accessibility_keyboard",
                status=TestStatus.FAILED,
                message=f"Fehler bei Keyboard-Test: {str(e)}"
            ))
        
        return results
    
    async def _check_color_contrast(self, form: FormStructure) -> List[TestResult]:
        """Prüft Farbkontrast für bessere Lesbarkeit"""
        results = []
        
        for field in form.fields:
            try:
                # Hole CSS-Eigenschaften
                styles = await self.page.evaluate(f"""
                    (() => {{
                        const field = document.querySelector('{field.selector}');
                        if (!field) return null;
                        
                        const computed = getComputedStyle(field);
                        return {{
                            color: computed.color,
                            backgroundColor: computed.backgroundColor,
                            borderColor: computed.borderColor
                        }};
                    }})()
                """)
                
                if styles:
                    # Vereinfachte Kontrast-Bewertung
                    # (Eine echte Implementierung würde WCAG-Kontrast-Algorithmus verwenden)
                    has_good_contrast = True  # Placeholder
                    
                    status = TestStatus.PASSED if has_good_contrast else TestStatus.WARNING
                    message = "Farbkontrast ausreichend" if has_good_contrast else "Farbkontrast möglicherweise unzureichend"
                    
                    results.append(TestResult(
                        form_selector=field.selector,
                        test_type="accessibility_contrast",
                        status=status,
                        message=message,
                        details=styles
                    ))
            
            except Exception as e:
                results.append(TestResult(
                    form_selector=field.selector,
                    test_type="accessibility_contrast",
                    status=TestStatus.FAILED,
                    message=f"Fehler bei Kontrast-Prüfung: {str(e)}"
                ))
        
        return results
    
    async def validate_error_display(self, form: FormStructure) -> List[TestResult]:
        """
        Prüft wie Fehlermeldungen angezeigt werden.
        """
        results = []
        
        # Trigger Validierungsfehler
        try:
            # Submit ohne ausgefüllte Required-Felder
            if form.submit_button:
                await self.page.click(form.submit_button)
                await asyncio.sleep(1)  # Warten auf Validierung
                
                # Prüfe Fehler-Display-Eigenschaften
                error_display_quality = await self._analyze_error_display()
                
                results.append(TestResult(
                    form_selector=form.selector,
                    test_type="error_display",
                    status=error_display_quality['status'],
                    message=error_display_quality['message'],
                    details=error_display_quality['details']
                ))
        
        except Exception as e:
            results.append(TestResult(
                form_selector=form.selector,
                test_type="error_display",
                status=TestStatus.FAILED,
                message=f"Fehler bei Error-Display-Test: {str(e)}"
            ))
        
        return results
    
    async def _analyze_error_display(self) -> Dict[str, Any]:
        """Analysiert die Qualität der Fehlerdarstellung"""
        
        error_analysis = await self.page.evaluate("""
            (() => {
                const errorElements = document.querySelectorAll(
                    '.error, .invalid-feedback, .text-danger, [role="alert"], .field-error'
                );
                
                let visibleErrors = 0;
                let totalErrors = errorElements.length;
                let errorTexts = [];
                
                errorElements.forEach(el => {
                    const isVisible = el.offsetWidth > 0 && el.offsetHeight > 0;
                    if (isVisible) {
                        visibleErrors++;
                        errorTexts.push(el.textContent.trim());
                    }
                });
                
                return {
                    totalErrors,
                    visibleErrors,
                    errorTexts,
                    hasErrors: totalErrors > 0
                };
            })()
        """)
        
        if error_analysis['hasErrors']:
            if error_analysis['visibleErrors'] > 0:
                status = TestStatus.PASSED
                message = f"Fehlermeldungen werden korrekt angezeigt ({error_analysis['visibleErrors']} sichtbar)"
            else:
                status = TestStatus.FAILED
                message = "Fehlermeldungen vorhanden aber nicht sichtbar"
        else:
            status = TestStatus.WARNING
            message = "Keine Fehlermeldungen gefunden (möglicherweise keine Validierung aktiv)"
        
        return {
            'status': status,
            'message': message,
            'details': error_analysis
        }
    
    async def test_responsive_behavior(self, form: FormStructure, viewports: List[Dict] = None) -> List[TestResult]:
        """
        Testet Formular auf verschiedenen Bildschirmgrößen.
        """
        if not viewports:
            viewports = [
                {'width': 375, 'height': 667, 'name': 'iPhone SE'},
                {'width': 768, 'height': 1024, 'name': 'iPad'},
                {'width': 1920, 'height': 1080, 'name': 'Desktop'}
            ]
        
        results = []
        original_viewport = self.page.viewport_size
        
        for viewport in viewports:
            try:
                # Viewport setzen
                await self.page.set_viewport_size(width=viewport['width'], height=viewport['height'])
                await asyncio.sleep(0.5)  # Layout stabilisieren
                
                # Formular-Sichtbarkeit prüfen
                form_visible = await self.page.locator(form.selector).is_visible()
                
                # Feld-Zugänglichkeit prüfen
                accessible_fields = 0
                for field in form.fields:
                    try:
                        field_element = self.page.locator(field.selector)
                        if await field_element.is_visible():
                            # Prüfe ob Feld bedienbar ist
                            bounding_box = await field_element.bounding_box()
                            if bounding_box and bounding_box['width'] > 0 and bounding_box['height'] > 0:
                                accessible_fields += 1
                    except:
                        pass
                
                # Bewertung
                accessibility_ratio = accessible_fields / len(form.fields) if form.fields else 0
                
                if form_visible and accessibility_ratio >= 0.9:
                    status = TestStatus.PASSED
                    message = f"Responsive Design funktioniert auf {viewport['name']}"
                elif form_visible and accessibility_ratio >= 0.7:
                    status = TestStatus.WARNING
                    message = f"Responsive Design teilweise funktional auf {viewport['name']}"
                else:
                    status = TestStatus.FAILED
                    message = f"Responsive Design problematisch auf {viewport['name']}"
                
                results.append(TestResult(
                    form_selector=form.selector,
                    test_type=f"responsive_{viewport['name'].lower().replace(' ', '_')}",
                    status=status,
                    message=message,
                    details={
                        'viewport': viewport,
                        'form_visible': form_visible,
                        'accessible_fields': accessible_fields,
                        'total_fields': len(form.fields),
                        'accessibility_ratio': accessibility_ratio
                    }
                ))
            
            except Exception as e:
                results.append(TestResult(
                    form_selector=form.selector,
                    test_type=f"responsive_{viewport['name'].lower().replace(' ', '_')}",
                    status=TestStatus.FAILED,
                    message=f"Fehler bei Responsive-Test auf {viewport['name']}: {str(e)}"
                ))
        
        # Ursprüngliches Viewport wiederherstellen
        if original_viewport:
            await self.page.set_viewport_size(
                width=original_viewport['width'], 
                height=original_viewport['height']
            )
        
        return results


class VisualTestReporter:
    """
    Erstellt umfassende Reports mit Screenshots, Videos und visuellen Beweisen.
    """
    
    def __init__(self, output_dir: Path = None):
        self.output_dir = output_dir or Path("form_test_reports")
        self.output_dir.mkdir(exist_ok=True)
        
        self.screenshots_dir = self.output_dir / "screenshots"
        self.videos_dir = self.output_dir / "videos"
        self.reports_dir = self.output_dir / "reports"
        
        for dir_path in [self.screenshots_dir, self.videos_dir, self.reports_dir]:
            dir_path.mkdir(exist_ok=True)
    
    async def capture_form_states(self, page: Page, form_selector: str, test_name: str) -> Dict[str, str]:
        """
        Dokumentiert verschiedene Formular-Zustände visuell.
        """
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        base_name = f"{test_name}_{timestamp}"
        
        screenshots = {}
        
        try:
            # 1. Initial State
            initial_path = self.screenshots_dir / f"{base_name}_initial.png"
            await page.screenshot(path=str(initial_path), full_page=True)
            screenshots['initial'] = str(initial_path)
            
            # 2. Form in Focus
            form_element = page.locator(form_selector)
            await form_element.scroll_into_view_if_needed()
            await asyncio.sleep(0.5)
            
            form_focus_path = self.screenshots_dir / f"{base_name}_form_focus.png"
            await page.screenshot(path=str(form_focus_path), full_page=True)
            screenshots['form_focus'] = str(form_focus_path)
            
            # 3. Form Element Only (wenn möglich)
            try:
                form_only_path = self.screenshots_dir / f"{base_name}_form_only.png"
                await form_element.screenshot(path=str(form_only_path))
                screenshots['form_only'] = str(form_only_path)
            except:
                pass
            
            return screenshots
            
        except Exception as e:
            print(f"Fehler beim Screenshot-Capturing: {e}")
            return {}
    
    async def capture_validation_errors(self, page: Page, test_name: str) -> str:
        """
        Erstellt Screenshots von Validierungsfehlern.
        """
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        error_screenshot_path = self.screenshots_dir / f"{test_name}_validation_errors_{timestamp}.png"
        
        try:
            await page.screenshot(path=str(error_screenshot_path), full_page=True)
            return str(error_screenshot_path)
        except Exception as e:
            print(f"Fehler beim Error-Screenshot: {e}")
            return ""
    
    async def start_video_recording(self, page: Page, test_name: str):
        """Startet Video-Aufzeichnung (falls unterstützt)"""
        try:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            video_path = self.videos_dir / f"{test_name}_{timestamp}.webm"
            
            # Playwright Video-Recording aktivieren (context-basiert)
            # Dies muss beim Context-Setup konfiguriert werden
            return str(video_path)
        except Exception as e:
            print(f"Video-Recording nicht verfügbar: {e}")
            return None
    
    def generate_visual_report(self, test_results: List[TestResult], report_name: str = "form_test_report") -> str:
        """
        Generiert einen HTML-Report mit visuellen Beweisen.
        """
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        report_path = self.reports_dir / f"{report_name}_{timestamp}.html"
        
        # Gruppiere Ergebnisse nach Form
        forms_results = {}
        for result in test_results:
            form_id = result.form_selector
            if form_id not in forms_results:
                forms_results[form_id] = []
            forms_results[form_id].append(result)
        
        # HTML-Report generieren
        html_content = self._generate_html_report(forms_results, report_name)
        
        try:
            with open(report_path, 'w', encoding='utf-8') as f:
                f.write(html_content)
            
            print(f"📊 HTML-Report erstellt: {report_path}")
            return str(report_path)
            
        except Exception as e:
            print(f"Fehler beim Report-Generieren: {e}")
            return ""
    
    def _generate_html_report(self, forms_results: Dict[str, List[TestResult]], report_name: str) -> str:
        """Generiert HTML-Inhalt für den Report"""
        
        # Statistiken berechnen
        total_tests = sum(len(results) for results in forms_results.values())
        passed_tests = sum(1 for results in forms_results.values() for r in results if r.status == TestStatus.PASSED)
        failed_tests = sum(1 for results in forms_results.values() for r in results if r.status == TestStatus.FAILED)
        warning_tests = sum(1 for results in forms_results.values() for r in results if r.status == TestStatus.WARNING)
        
        success_rate = (passed_tests / total_tests * 100) if total_tests > 0 else 0
        
        html = f"""
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{report_name} - Formular Test Report</title>
    <style>
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }}
        .container {{
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            overflow: hidden;
        }}
        .header {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }}
        .stats {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            padding: 30px;
            background: #f8f9fa;
        }}
        .stat-card {{
            background: white;
            padding: 20px;
            border-radius: 8px;
            text-align: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }}
        .stat-number {{
            font-size: 2.5em;
            font-weight: bold;
            margin-bottom: 10px;
        }}
        .passed {{ color: #28a745; }}
        .failed {{ color: #dc3545; }}
        .warning {{ color: #ffc107; }}
        .content {{
            padding: 30px;
        }}
        .form-section {{
            margin-bottom: 40px;
            border: 1px solid #dee2e6;
            border-radius: 8px;
            overflow: hidden;
        }}
        .form-header {{
            background: #e9ecef;
            padding: 15px 20px;
            border-bottom: 1px solid #dee2e6;
        }}
        .test-results {{
            padding: 20px;
        }}
        .test-item {{
            display: flex;
            align-items: center;
            padding: 10px 0;
            border-bottom: 1px solid #f1f3f4;
        }}
        .test-item:last-child {{
            border-bottom: none;
        }}
        .test-status {{
            width: 150px;
            font-weight: bold;
        }}
        .test-message {{
            flex: 1;
        }}
        .test-details {{
            background: #f8f9fa;
            padding: 10px;
            margin-top: 10px;
            border-radius: 4px;
            font-family: monospace;
            font-size: 0.9em;
        }}
        .screenshot {{
            max-width: 100%;
            border-radius: 4px;
            margin: 10px 0;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }}
        .footer {{
            background: #f8f9fa;
            padding: 20px;
            text-align: center;
            color: #6c757d;
            border-top: 1px solid #dee2e6;
        }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🧪 Formular Test Report</h1>
            <h2>{report_name}</h2>
            <p>Generiert am {datetime.now().strftime('%d.%m.%Y um %H:%M:%S')}</p>
        </div>
        
        <div class="stats">
            <div class="stat-card">
                <div class="stat-number">{total_tests}</div>
                <div>Gesamt Tests</div>
            </div>
            <div class="stat-card">
                <div class="stat-number passed">{passed_tests}</div>
                <div>Bestanden</div>
            </div>
            <div class="stat-card">
                <div class="stat-number failed">{failed_tests}</div>
                <div>Fehlgeschlagen</div>
            </div>
            <div class="stat-card">
                <div class="stat-number warning">{warning_tests}</div>
                <div>Warnungen</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" style="color: {'#28a745' if success_rate >= 80 else '#ffc107' if success_rate >= 60 else '#dc3545'}">{success_rate:.1f}%</div>
                <div>Erfolgsrate</div>
            </div>
        </div>
        
        <div class="content">
"""
        
        # Formular-spezifische Ergebnisse
        for form_selector, results in forms_results.items():
            html += f"""
            <div class="form-section">
                <div class="form-header">
                    <h3>📝 Formular: {form_selector}</h3>
                    <p>{len(results)} Tests durchgeführt</p>
                </div>
                <div class="test-results">
"""
            
            for result in results:
                status_class = result.status.value.split()[0].lower().replace('✅', 'passed').replace('❌', 'failed').replace('⚠️', 'warning')
                
                html += f"""
                    <div class="test-item">
                        <div class="test-status {status_class}">{result.status.value}</div>
                        <div class="test-message">
                            <strong>{result.test_type.replace('_', ' ').title()}</strong><br>
                            {result.message}
                            {f'<small> ({result.execution_time:.2f}s)</small>' if result.execution_time > 0 else ''}
                        </div>
                    </div>
"""
                
                # Details hinzufügen wenn vorhanden
                if result.details:
                    html += f"""
                    <div class="test-details">
                        <strong>Details:</strong><br>
                        <pre>{json.dumps(result.details, indent=2, ensure_ascii=False)}</pre>
                    </div>
"""
                
                # Screenshot hinzufügen wenn vorhanden
                if result.screenshot_path and Path(result.screenshot_path).exists():
                    rel_path = Path(result.screenshot_path).relative_to(self.output_dir)
                    html += f"""
                    <div>
                        <img src="{rel_path}" alt="Screenshot für {result.test_type}" class="screenshot">
                    </div>
"""
            
            html += """
                </div>
            </div>
"""
        
        html += f"""
        </div>
        
        <div class="footer">
            <p>🚀 Generiert mit Flask HTML-Formular Test Automator</p>
            <p>Mercedes-Benz Projektarbeit MYP - Till Tomczak</p>
        </div>
    </div>
</body>
</html>
"""
        
        return html
    
    def generate_json_report(self, test_results: List[TestResult], report_name: str = "form_test_report") -> str:
        """Generiert einen JSON-Report für maschinelle Weiterverarbeitung"""
        
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        json_path = self.reports_dir / f"{report_name}_{timestamp}.json"
        
        # Konvertiere Results zu Dict
        results_data = []
        for result in test_results:
            result_dict = asdict(result)
            result_dict['status'] = result.status.value  # Enum zu String
            results_data.append(result_dict)
        
        report_data = {
            'report_name': report_name,
            'generated_at': datetime.now().isoformat(),
            'summary': {
                'total_tests': len(test_results),
                'passed': len([r for r in test_results if r.status == TestStatus.PASSED]),
                'failed': len([r for r in test_results if r.status == TestStatus.FAILED]),
                'warnings': len([r for r in test_results if r.status == TestStatus.WARNING]),
                'skipped': len([r for r in test_results if r.status == TestStatus.SKIPPED])
            },
            'test_results': results_data
        }
        
        try:
            with open(json_path, 'w', encoding='utf-8') as f:
                json.dump(report_data, f, indent=2, ensure_ascii=False)
            
            print(f"📋 JSON-Report erstellt: {json_path}")
            return str(json_path)
            
        except Exception as e:
            print(f"Fehler beim JSON-Report: {e}")
            return ""


class HTMLFormTestAutomator:
    """
    Hauptklasse für automatisierte HTML-Formular-Tests.
    Koordiniert alle Test-Komponenten und Browser-Interaktionen.
    """
    
    def __init__(self, base_url: str, browser: str = 'chromium', headless: bool = True):
        self.base_url = base_url.rstrip('/')
        self.browser_type = browser
        self.headless = headless
        
        # Komponenten
        self.data_generator = FrontendTestDataGenerator()
        self.reporter = VisualTestReporter()
        
        # Browser-Instanzen (werden bei Bedarf initialisiert)
        self.playwright = None
        self.browser = None
        self.context = None
        self.page = None
        
        # Test-Ergebnisse
        self.test_results: List[TestResult] = []
        
        # Validiere Voraussetzungen
        if not PLAYWRIGHT_AVAILABLE:
            raise ImportError("Playwright ist erforderlich. Installiere mit: pip install playwright")
    
    async def __aenter__(self):
        """Async Context Manager - Setup"""
        await self._setup_browser()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """Async Context Manager - Cleanup"""
        await self._cleanup_browser()
    
    async def _setup_browser(self):
        """Initialisiert Browser und Kontext"""
        try:
            self.playwright = await async_playwright().start()
            
            # Browser starten
            if self.browser_type == 'chromium':
                self.browser = await self.playwright.chromium.launch(headless=self.headless)
            elif self.browser_type == 'firefox':
                self.browser = await self.playwright.firefox.launch(headless=self.headless)
            elif self.browser_type == 'webkit':
                self.browser = await self.playwright.webkit.launch(headless=self.headless)
            else:
                raise ValueError(f"Unbekannter Browser: {self.browser_type}")
            
            # Kontext erstellen mit optimalen Einstellungen
            self.context = await self.browser.new_context(
                viewport={'width': 1280, 'height': 720},
                ignore_https_errors=True,  # Für lokale Entwicklung
                record_video_dir=str(self.reporter.videos_dir) if not self.headless else None
            )
            
            # Seite erstellen
            self.page = await self.context.new_page()
            
            # Event-Handler für besseres Debugging
            self.page.on("pageerror", lambda error: print(f"🚨 Browser-Fehler: {error}"))
            self.page.on("console", lambda msg: print(f"🔍 Console: {msg.text}"))
            
            print(f"✅ Browser {self.browser_type} gestartet (headless: {self.headless})")
            
        except Exception as e:
            await self._cleanup_browser()
            raise Exception(f"Browser-Setup fehlgeschlagen: {str(e)}")
    
    async def _cleanup_browser(self):
        """Räumt Browser-Ressourcen auf"""
        try:
            if self.page:
                await self.page.close()
            if self.context:
                await self.context.close()
            if self.browser:
                await self.browser.close()
            if self.playwright:
                await self.playwright.stop()
        except Exception as e:
            print(f"⚠️ Cleanup-Fehler: {e}")
    
    async def scan_for_forms(self, page_url: str) -> List[FormStructure]:
        """
        Öffnet eine Seite und findet alle HTML-Formulare.
        
        Args:
            page_url: Relative oder absolute URL zur Seite
        """
        full_url = page_url if page_url.startswith('http') else f"{self.base_url}{page_url}"
        
        try:
            print(f"🔍 Scanne Formulare auf: {full_url}")
            
            # Seite laden
            response = await self.page.goto(full_url, wait_until="networkidle")
            if response.status >= 400:
                print(f"⚠️ HTTP {response.status}: {full_url}")
            
            # Warten auf JavaScript und dynamische Inhalte
            await asyncio.sleep(2)
            
            # Formulare finden und analysieren
            forms_data = await self.page.evaluate("""
                () => {
                    const forms = Array.from(document.querySelectorAll('form'));
                    
                    return forms.map((form, index) => {
                        const formId = form.id || form.className || `form-${index}`;
                        const selector = form.id ? `#${form.id}` : 
                                        form.className ? `.${form.className.split(' ')[0]}` :
                                        `form:nth-of-type(${index + 1})`;
                        
                        // Felder analysieren
                        const fields = Array.from(form.querySelectorAll(
                            'input, textarea, select, [contenteditable="true"]'
                        )).map(field => {
                            const label = field.labels?.[0]?.textContent || 
                                         field.getAttribute('aria-label') ||
                                         field.previousElementSibling?.textContent ||
                                         field.placeholder || 
                                         field.name || 
                                         field.id;
                            
                            const options = field.tagName === 'SELECT' ? 
                                          Array.from(field.options).map(opt => opt.value) : [];
                            
                            return {
                                name: field.name || field.id || `field-${Math.random().toString(36).substr(2, 9)}`,
                                field_type: field.type || field.tagName.toLowerCase(),
                                selector: field.id ? `#${field.id}` : 
                                         field.name ? `[name="${field.name}"]` :
                                         field.className ? `.${field.className.split(' ')[0]}` :
                                         `${field.tagName.toLowerCase()}:nth-of-type(${Array.from(form.querySelectorAll(field.tagName)).indexOf(field) + 1})`,
                                label: label?.trim() || '',
                                placeholder: field.placeholder || '',
                                required: field.required,
                                pattern: field.pattern || '',
                                min_length: parseInt(field.minLength) || 0,
                                max_length: parseInt(field.maxLength) || 0,
                                min_value: field.min || '',
                                max_value: field.max || '',
                                options: options
                            };
                        });
                        
                        // Submit-Button finden
                        const submitButton = form.querySelector('[type="submit"], button[type="submit"], button:not([type])');
                        const submitSelector = submitButton ? 
                                             (submitButton.id ? `#${submitButton.id}` : 
                                              submitButton.className ? `.${submitButton.className.split(' ')[0]}` :
                                              '[type="submit"]') : '';
                        
                        // CSRF-Token finden
                        const csrfField = form.querySelector('[name*="csrf"], [name*="token"], [name="_token"]');
                        const csrfSelector = csrfField ? `[name="${csrfField.name}"]` : '';
                        
                        return {
                            selector: selector,
                            action: form.action || window.location.href,
                            method: form.method || 'POST',
                            fields: fields,
                            submit_button: submitSelector,
                            is_multi_step: form.querySelectorAll('.step, .wizard-step, [data-step]').length > 1,
                            csrf_token_field: csrfSelector,
                            enctype: form.enctype || 'application/x-www-form-urlencoded'
                        };
                    });
                }
            """)
            
            # Konvertiere zu FormStructure-Objekten
            forms = []
            for form_data in forms_data:
                fields = [FormField(**field_data) for field_data in form_data['fields']]
                form = FormStructure(
                    selector=form_data['selector'],
                    action=form_data['action'],
                    method=form_data['method'],
                    fields=fields,
                    submit_button=form_data['submit_button'],
                    is_multi_step=form_data['is_multi_step'],
                    csrf_token_field=form_data['csrf_token_field'],
                    enctype=form_data['enctype']
                )
                forms.append(form)
            
            print(f"✅ {len(forms)} Formulare gefunden")
            for i, form in enumerate(forms):
                print(f"   📋 Form {i+1}: {form.selector} ({len(form.fields)} Felder)")
            
            return forms
            
        except Exception as e:
            print(f"❌ Fehler beim Formular-Scan: {str(e)}")
            return []
    
    async def test_all_forms_on_page(self, page_url: str, test_scenarios: List[str] = None) -> List[TestResult]:
        """
        Testet alle Formulare auf einer Seite mit verschiedenen Szenarien.
        
        Args:
            page_url: URL der zu testenden Seite
            test_scenarios: Liste der Test-Szenarien ['valid', 'invalid', 'edge_cases', 'accessibility']
        """
        if test_scenarios is None:
            test_scenarios = ['valid', 'invalid', 'accessibility']
        
        all_results = []
        
        # Formulare finden
        forms = await self.scan_for_forms(page_url)
        
        if not forms:
            return [TestResult(
                form_selector=page_url,
                test_type="form_discovery",
                status=TestStatus.WARNING,
                message="Keine Formulare auf der Seite gefunden"
            )]
        
        # Jedes Formular testen
        for form in forms:
            print(f"\n🧪 Teste Formular: {form.selector}")
            
            form_results = await self.test_form_comprehensive(form, test_scenarios)
            all_results.extend(form_results)
        
        self.test_results.extend(all_results)
        return all_results
    
    async def test_form_comprehensive(self, form: FormStructure, test_scenarios: List[str]) -> List[TestResult]:
        """
        Führt umfassende Tests für ein einzelnes Formular durch.
        """
        results = []
        
        # Test-Engines initialisieren
        interaction_engine = FormInteractionEngine(self.page)
        visual_validator = VisualFormValidator(self.page)
        
        # Screenshots für Dokumentation
        screenshots = await self.reporter.capture_form_states(
            self.page, form.selector, f"form_test_{form.selector.replace('#', '').replace('.', '')}"
        )
        
        try:
            # 1. Gültige Daten testen
            if 'valid' in test_scenarios:
                print("   ✅ Teste gültige Eingaben...")
                valid_results = await self._test_valid_form_submission(form, interaction_engine)
                results.extend(valid_results)
            
            # 2. Ungültige Daten testen  
            if 'invalid' in test_scenarios:
                print("   ❌ Teste ungültige Eingaben...")
                invalid_results = await self._test_invalid_form_submission(form, interaction_engine)
                results.extend(invalid_results)
            
            # 3. Edge Cases testen
            if 'edge_cases' in test_scenarios:
                print("   🔍 Teste Edge Cases...")
                edge_results = await self._test_edge_cases(form, interaction_engine)
                results.extend(edge_results)
            
            # 4. Accessibility testen
            if 'accessibility' in test_scenarios:
                print("   ♿ Teste Accessibility...")
                accessibility_results = await visual_validator.check_form_accessibility(form)
                results.extend(accessibility_results)
            
            # 5. Validierungen testen
            if 'validations' in test_scenarios:
                print("   🔧 Teste Validierungen...")
                validation_results = await interaction_engine.test_form_validations(form)
                results.extend(validation_results)
            
            # 6. Responsive Design testen
            if 'responsive' in test_scenarios:
                print("   📱 Teste Responsive Design...")
                responsive_results = await visual_validator.test_responsive_behavior(form)
                results.extend(responsive_results)
            
            # 7. Dynamisches Verhalten testen
            if 'dynamic' in test_scenarios:
                print("   ⚡ Teste dynamisches Verhalten...")
                dynamic_results = await interaction_engine.test_dynamic_form_behavior(form)
                results.extend(dynamic_results)
            
            # 8. Error Display testen
            if 'error_display' in test_scenarios:
                print("   🚨 Teste Error Display...")
                error_results = await visual_validator.validate_error_display(form)
                results.extend(error_results)
            
        except Exception as e:
            results.append(TestResult(
                form_selector=form.selector,
                test_type="comprehensive_test",
                status=TestStatus.FAILED,
                message=f"Fehler beim umfassenden Test: {str(e)}"
            ))
        
        # Screenshots zu Ergebnissen hinzufügen
        for result in results:
            if not result.screenshot_path and screenshots.get('form_focus'):
                result.screenshot_path = screenshots['form_focus']
        
        return results
    
    async def _test_valid_form_submission(self, form: FormStructure, interaction_engine: FormInteractionEngine) -> List[TestResult]:
        """Testet Formular mit gültigen Daten"""
        
        # Gültige Test-Daten generieren
        test_data = {}
        for field in form.fields:
            if field.field_type not in ['submit', 'button', 'hidden']:
                test_data[field.name] = self.data_generator.generate_for_field(field, 'valid')
        
        start_time = time.time()
        
        # Formular ausfüllen
        fill_results = await interaction_engine.fill_form_like_human(form, test_data)
        
        # Versuche zu submitten
        try:
            if form.submit_button:
                await self.page.click(form.submit_button)
                await asyncio.sleep(2)  # Warten auf Response
                
                # Prüfe Erfolg (Page-Change, Success-Message, etc.)
                success = await self._check_submission_success()
                
                execution_time = time.time() - start_time
                
                if success:
                    fill_results.append(TestResult(
                        form_selector=form.selector,
                        test_type="valid_submission",
                        status=TestStatus.PASSED,
                        message="Gültige Formular-Submission erfolgreich",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
                else:
                    fill_results.append(TestResult(
                        form_selector=form.selector,
                        test_type="valid_submission",
                        status=TestStatus.FAILED,
                        message="Gültige Submission wurde nicht akzeptiert",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
            
        except Exception as e:
            fill_results.append(TestResult(
                form_selector=form.selector,
                test_type="valid_submission",
                status=TestStatus.FAILED,
                message=f"Fehler bei gültiger Submission: {str(e)}",
                execution_time=time.time() - start_time
            ))
        
        return fill_results
    
    async def _test_invalid_form_submission(self, form: FormStructure, interaction_engine: FormInteractionEngine) -> List[TestResult]:
        """Testet Formular mit ungültigen Daten"""
        
        # Ungültige Test-Daten generieren
        test_data = {}
        for field in form.fields:
            if field.field_type not in ['submit', 'button', 'hidden']:
                test_data[field.name] = self.data_generator.generate_for_field(field, 'invalid')
        
        start_time = time.time()
        
        # Formular ausfüllen
        fill_results = await interaction_engine.fill_form_like_human(form, test_data)
        
        # Versuche zu submitten
        try:
            if form.submit_button:
                await self.page.click(form.submit_button)
                await asyncio.sleep(2)
                
                # Prüfe ob Validierung greift (Submission sollte fehlschlagen)
                validation_triggered = await self._check_validation_triggered()
                
                execution_time = time.time() - start_time
                
                if validation_triggered:
                    fill_results.append(TestResult(
                        form_selector=form.selector,
                        test_type="invalid_submission",
                        status=TestStatus.PASSED,
                        message="Ungültige Daten wurden korrekt abgewiesen",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
                else:
                    fill_results.append(TestResult(
                        form_selector=form.selector,
                        test_type="invalid_submission",
                        status=TestStatus.FAILED,
                        message="Ungültige Daten wurden fälschlicherweise akzeptiert",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
        
        except Exception as e:
            fill_results.append(TestResult(
                form_selector=form.selector,
                test_type="invalid_submission",
                status=TestStatus.FAILED,
                message=f"Fehler bei ungültiger Submission: {str(e)}",
                execution_time=time.time() - start_time
            ))
        
        return fill_results
    
    async def _test_edge_cases(self, form: FormStructure, interaction_engine: FormInteractionEngine) -> List[TestResult]:
        """Testet Edge Cases wie XSS, SQL Injection, etc."""
        
        results = []
        edge_test_cases = [
            "xss_injection",
            "sql_injection", 
            "unicode_characters",
            "extremely_long_input",
            "null_bytes",
            "whitespace_only"
        ]
        
        for test_case in edge_test_cases:
            # Edge-Case Test-Daten generieren
            test_data = {}
            for field in form.fields:
                if field.field_type not in ['submit', 'button', 'hidden']:
                    test_data[field.name] = self.data_generator.generate_for_field(field, 'edge_case')
            
            try:
                start_time = time.time()
                
                # Formular ausfüllen
                await interaction_engine.fill_form_like_human(form, test_data)
                
                # Submit versuchen
                if form.submit_button:
                    await self.page.click(form.submit_button)
                    await asyncio.sleep(1)
                
                # Prüfe ob System stabil bleibt
                page_crashed = await self._check_page_stability()
                
                execution_time = time.time() - start_time
                
                if not page_crashed:
                    results.append(TestResult(
                        form_selector=form.selector,
                        test_type=f"edge_case_{test_case}",
                        status=TestStatus.PASSED,
                        message=f"Edge Case '{test_case}' korrekt behandelt",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
                else:
                    results.append(TestResult(
                        form_selector=form.selector,
                        test_type=f"edge_case_{test_case}",
                        status=TestStatus.FAILED,
                        message=f"Edge Case '{test_case}' verursacht Probleme",
                        execution_time=execution_time,
                        details={'test_data': test_data}
                    ))
            
            except Exception as e:
                results.append(TestResult(
                    form_selector=form.selector,
                    test_type=f"edge_case_{test_case}",
                    status=TestStatus.FAILED,
                    message=f"Fehler bei Edge Case '{test_case}': {str(e)}"
                ))
        
        return results
    
    async def _check_submission_success(self) -> bool:
        """Prüft ob eine Formular-Submission erfolgreich war"""
        
        try:
            # Warten auf Navigation oder Änderungen
            await asyncio.sleep(1)
            
            success_indicators = await self.page.evaluate("""
                () => {
                    // Verschiedene Erfolgs-Indikatoren prüfen
                    const successElements = document.querySelectorAll(
                        '.success, .alert-success, .message-success, .notification-success, ' +
                        '[class*="success"], [role="alert"][class*="success"]'
                    );
                    
                    const errorElements = document.querySelectorAll(
                        '.error, .alert-error, .alert-danger, .message-error, ' +
                        '[class*="error"], [class*="danger"], [role="alert"][class*="error"]'
                    );
                    
                    const urlChanged = window.location.href !== document.referrer;
                    
                    return {
                        hasSuccessMessage: successElements.length > 0,
                        hasErrorMessage: errorElements.length > 0,
                        urlChanged: urlChanged,
                        currentUrl: window.location.href
                    };
                }
            """)
            
            # Success wenn: Success-Message ODER URL-Änderung UND keine Error-Message
            return ((success_indicators['hasSuccessMessage'] or success_indicators['urlChanged']) 
                   and not success_indicators['hasErrorMessage'])
            
        except Exception:
            return False
    
    async def _check_validation_triggered(self) -> bool:
        """Prüft ob Client-Side-Validierung ausgelöst wurde"""
        
        try:
            validation_info = await self.page.evaluate("""
                () => {
                    // HTML5 Validierung prüfen
                    const invalidFields = document.querySelectorAll(':invalid');
                    
                    // Custom Validierungs-Elemente
                    const errorElements = document.querySelectorAll(
                        '.error, .invalid-feedback, .field-error, .validation-error, ' +
                        '[role="alert"], .alert-danger, .text-danger'
                    );
                    
                    // Prüfe ob Submit verhindert wurde (URL ändert sich nicht)
                    const formElements = document.querySelectorAll('form');
                    
                    return {
                        invalidFieldsCount: invalidFields.length,
                        errorElementsCount: errorElements.length,
                        hasValidationMessages: errorElements.length > 0
                    };
                }
            """)
            
            return (validation_info['invalidFieldsCount'] > 0 or 
                   validation_info['hasValidationMessages'])
            
        except Exception:
            return False
    
    async def _check_page_stability(self) -> bool:
        """Prüft ob die Seite nach Edge-Case-Input stabil bleibt"""
        
        try:
            # Warte kurz und prüfe dann
            await asyncio.sleep(0.5)
            
            # Prüfe ob Page noch reagiert
            title = await self.page.title()
            
            # Prüfe auf JavaScript-Fehler
            errors = await self.page.evaluate("""
                () => {
                    return window.testErrors || [];
                }
            """)
            
            # Stabil wenn Title abgerufen werden kann und keine kritischen Fehler
            return title is not None and len(errors) == 0
            
        except Exception:
            return False  # Page crashed
    
    async def test_form(self, url: str, form_selector: str, test_data: Dict[str, str] = None, 
                       test_scenarios: List[str] = None) -> List[TestResult]:
        """
        Testet ein spezifisches Formular mit benutzerdefinierten Daten.
        
        Args:
            url: URL der Seite mit dem Formular
            form_selector: CSS-Selektor für das Formular
            test_data: Benutzerdefinierte Test-Daten
            test_scenarios: Test-Szenarien ['valid', 'invalid', 'edge_cases']
        """
        if test_scenarios is None:
            test_scenarios = ['valid', 'invalid']
        
        # Seite laden
        full_url = url if url.startswith('http') else f"{self.base_url}{url}"
        await self.page.goto(full_url, wait_until="networkidle")
        
        # Formular finden
        forms = await self.scan_for_forms(url)
        target_form = None
        
        for form in forms:
            if form.selector == form_selector:
                target_form = form
                break
        
        if not target_form:
            return [TestResult(
                form_selector=form_selector,
                test_type="form_discovery",
                status=TestStatus.FAILED,
                message=f"Formular mit Selektor '{form_selector}' nicht gefunden"
            )]
        
        # Mit benutzerdefinierten Daten überschreiben falls vorhanden
        if test_data:
            interaction_engine = FormInteractionEngine(self.page)
            
            start_time = time.time()
            results = await interaction_engine.fill_form_like_human(target_form, test_data)
            
            # Submit
            if target_form.submit_button:
                await self.page.click(target_form.submit_button)
                await asyncio.sleep(2)
                
                success = await self._check_submission_success()
                execution_time = time.time() - start_time
                
                results.append(TestResult(
                    form_selector=form_selector,
                    test_type="custom_data_submission",
                    status=TestStatus.PASSED if success else TestStatus.FAILED,
                    message="Custom Test-Daten submission " + ("erfolgreich" if success else "fehlgeschlagen"),
                    execution_time=execution_time,
                    details={'test_data': test_data}
                ))
            
            self.test_results.extend(results)
            return results
        
        # Standard-Tests durchführen
        return await self.test_form_comprehensive(target_form, test_scenarios)
    
    async def test_multi_step_form(self, start_url: str, steps: List[str]) -> List[TestResult]:
        """
        Testet mehrstufige Formulare.
        
        Args:
            start_url: URL des ersten Schritts
            steps: Liste der Schritt-Selektoren oder -URLs
        """
        results = []
        
        try:
            # Erster Schritt
            full_url = start_url if start_url.startswith('http') else f"{self.base_url}{start_url}"
            await self.page.goto(full_url, wait_until="networkidle")
            
            current_step = 1
            
            for step_identifier in steps:
                print(f"🔄 Teste Multi-Step Schritt {current_step}: {step_identifier}")
                
                # Formulare im aktuellen Schritt finden
                forms = await self.scan_for_forms(self.page.url)
                
                if forms:
                    # Erstes Formular im Schritt testen
                    step_form = forms[0]
                    
                    # Test-Daten generieren
                    test_data = {}
                    for field in step_form.fields:
                        if field.field_type not in ['submit', 'button', 'hidden']:
                            test_data[field.name] = self.data_generator.generate_for_field(field, 'valid')
                    
                    # Schritt ausfüllen
                    interaction_engine = FormInteractionEngine(self.page)
                    fill_results = await interaction_engine.fill_form_like_human(step_form, test_data)
                    results.extend(fill_results)
                    
                    # Zum nächsten Schritt
                    if step_form.submit_button:
                        await self.page.click(step_form.submit_button)
                        await asyncio.sleep(2)
                        
                        # Prüfe ob nächster Schritt erreicht
                        if current_step < len(steps):
                            # Warte auf Navigation/Update
                            await asyncio.sleep(1)
                            
                            results.append(TestResult(
                                form_selector=step_form.selector,
                                test_type=f"multi_step_navigation_{current_step}",
                                status=TestStatus.PASSED,
                                message=f"Navigation zu Schritt {current_step + 1} erfolgreich",
                                details={'step': current_step, 'test_data': test_data}
                            ))
                        else:
                            # Finaler Schritt - prüfe Erfolg
                            success = await self._check_submission_success()
                            
                            results.append(TestResult(
                                form_selector=step_form.selector,
                                test_type="multi_step_completion",
                                status=TestStatus.PASSED if success else TestStatus.FAILED,
                                message="Multi-Step Formular " + ("erfolgreich abgeschlossen" if success else "Abschluss fehlgeschlagen"),
                                details={'total_steps': len(steps)}
                            ))
                
                current_step += 1
        
        except Exception as e:
            results.append(TestResult(
                form_selector="multi_step_form",
                test_type="multi_step_error",
                status=TestStatus.FAILED,
                message=f"Fehler bei Multi-Step Test: {str(e)}"
            ))
        
        self.test_results.extend(results)
        return results
    
    async def test_form_on_devices(self, url: str, devices: List[str] = None) -> List[TestResult]:
        """
        Testet Formulare auf verschiedenen Geräte-Viewports.
        
        Args:
            url: URL der zu testenden Seite
            devices: Liste der Geräte-Namen ['iPhone 12', 'iPad', 'Desktop 1920x1080']
        """
        if devices is None:
            devices = ['iPhone SE', 'iPad', 'Desktop 1920x1080']
        
        device_viewports = {
            'iPhone SE': {'width': 375, 'height': 667},
            'iPhone 12': {'width': 390, 'height': 844},
            'iPad': {'width': 768, 'height': 1024},
            'Desktop 1920x1080': {'width': 1920, 'height': 1080},
            'Desktop 1280x720': {'width': 1280, 'height': 720}
        }
        
        all_results = []
        original_viewport = self.page.viewport_size
        
        for device in devices:
            if device in device_viewports:
                viewport = device_viewports[device]
                
                print(f"📱 Teste auf {device} ({viewport['width']}x{viewport['height']})")
                
                # Viewport setzen
                await self.page.set_viewport_size(width=viewport['width'], height=viewport['height'])
                await asyncio.sleep(1)
                
                # Seite neu laden für korrekte Responsive-Darstellung
                full_url = url if url.startswith('http') else f"{self.base_url}{url}"
                await self.page.goto(full_url, wait_until="networkidle")
                
                # Formulare testen
                forms = await self.scan_for_forms(url)
                
                for form in forms:
                    visual_validator = VisualFormValidator(self.page)
                    responsive_results = await visual_validator.test_responsive_behavior(
                        form, [{'width': viewport['width'], 'height': viewport['height'], 'name': device}]
                    )
                    
                    # Screenshots für Device-Tests
                    device_screenshots = await self.reporter.capture_form_states(
                        self.page, form.selector, f"device_test_{device.replace(' ', '_').lower()}"
                    )
                    
                    for result in responsive_results:
                        if device_screenshots.get('form_focus'):
                            result.screenshot_path = device_screenshots['form_focus']
                    
                    all_results.extend(responsive_results)
        
        # Ursprüngliches Viewport wiederherstellen
        if original_viewport:
            await self.page.set_viewport_size(
                width=original_viewport['width'], 
                height=original_viewport['height']
            )
        
        self.test_results.extend(all_results)
        return all_results
    
    def generate_report(self, report_name: str = "form_test_report") -> str:
        """
        Generiert einen umfassenden Test-Report.
        
        Args:
            report_name: Name des Reports
            
        Returns:
            Pfad zum generierten HTML-Report
        """
        if not self.test_results:
            print("⚠️ Keine Test-Ergebnisse vorhanden")
            return ""
        
        # HTML-Report generieren
        html_report_path = self.reporter.generate_visual_report(self.test_results, report_name)
        
        # JSON-Report für maschinelle Verarbeitung
        json_report_path = self.reporter.generate_json_report(self.test_results, report_name)
        
        # Zusammenfassung in Console
        self._print_test_summary()
        
        return html_report_path
    
    def _print_test_summary(self):
        """Druckt eine Zusammenfassung der Test-Ergebnisse"""
        
        if not self.test_results:
            return
        
        total = len(self.test_results)
        passed = len([r for r in self.test_results if r.status == TestStatus.PASSED])
        failed = len([r for r in self.test_results if r.status == TestStatus.FAILED])
        warnings = len([r for r in self.test_results if r.status == TestStatus.WARNING])
        skipped = len([r for r in self.test_results if r.status == TestStatus.SKIPPED])
        
        success_rate = (passed / total * 100) if total > 0 else 0
        
        if RICH_AVAILABLE and console:
            # Rich Table für schöne Ausgabe
            table = Table(title="🧪 Formular Test Zusammenfassung")
            table.add_column("Metrik", style="bold")
            table.add_column("Anzahl", justify="right")
            table.add_column("Prozent", justify="right")
            
            table.add_row("Gesamt Tests", str(total), "100.0%")
            table.add_row("✅ Bestanden", str(passed), f"{passed/total*100:.1f}%", style="green")
            table.add_row("❌ Fehlgeschlagen", str(failed), f"{failed/total*100:.1f}%", style="red")
            table.add_row("⚠️ Warnungen", str(warnings), f"{warnings/total*100:.1f}%", style="yellow")
            table.add_row("⏭️ Übersprungen", str(skipped), f"{skipped/total*100:.1f}%", style="blue")
            table.add_row("", "", "", style="dim")
            table.add_row("🎯 Erfolgsrate", f"{success_rate:.1f}%", "", 
                         style="green" if success_rate >= 80 else "yellow" if success_rate >= 60 else "red")
            
            console.print("\n")
            console.print(table)
            console.print("\n")
            
            # Status-basierte Ausgabe
            if success_rate >= 90:
                console.print("🎉 Exzellente Test-Ergebnisse!", style="bold green")
            elif success_rate >= 80:
                console.print("✅ Gute Test-Ergebnisse!", style="bold yellow")
            elif success_rate >= 60:
                console.print("⚠️ Verbesserungsbedarf bei den Formularen", style="bold orange")
            else:
                console.print("❌ Kritische Probleme gefunden!", style="bold red")
        else:
            # Einfache Text-Ausgabe
            print(f"""
{'='*60}
🧪 FORMULAR TEST ZUSAMMENFASSUNG
{'='*60}

📊 STATISTIKEN:
   Gesamt Tests:        {total}
   ✅ Bestanden:        {passed} ({passed/total*100:.1f}%)
   ❌ Fehlgeschlagen:   {failed} ({failed/total*100:.1f}%)
   ⚠️ Warnungen:        {warnings} ({warnings/total*100:.1f}%)
   ⏭️ Übersprungen:     {skipped} ({skipped/total*100:.1f}%)
   
🎯 ERFOLGSRATE:         {success_rate:.1f}%

{'='*60}
""")


# CLI-Interface für den Form Test Automator
async def main():
    """Haupt-CLI-Interface für das Tool"""
    
    import argparse
    
    parser = argparse.ArgumentParser(
        description="Flask HTML-Formular Test Automator",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
BEISPIELE:
    # Alle Formulare auf einer Seite testen
    python form_test_automator.py --url http://localhost:5000/register --test-all
    
    # Spezifisches Formular testen
    python form_test_automator.py --url http://localhost:5000/contact --form "#contact-form"
    
    # Multi-Step Formular testen
    python form_test_automator.py --url http://localhost:5000/signup --multi-step --steps "step1,step2,step3"
    
    # Responsive Testing
    python form_test_automator.py --url http://localhost:5000/order --responsive --devices "iPhone 12,iPad,Desktop"
    
    # Umfassende Tests mit allen Szenarien
    python form_test_automator.py --url http://localhost:5000/application --comprehensive
        """
    )
    
    parser.add_argument('--url', required=True, help='Basis-URL der Flask-Anwendung')
    parser.add_argument('--form', help='CSS-Selektor für spezifisches Formular')
    parser.add_argument('--test-all', action='store_true', help='Teste alle Formulare auf der Seite')
    parser.add_argument('--multi-step', action='store_true', help='Multi-Step Formular testen')
    parser.add_argument('--steps', help='Komma-getrennte Liste der Schritte (für Multi-Step)')
    parser.add_argument('--responsive', action='store_true', help='Responsive Design testen')
    parser.add_argument('--devices', help='Komma-getrennte Liste der Test-Devices')
    parser.add_argument('--comprehensive', action='store_true', help='Umfassende Tests mit allen Szenarien')
    parser.add_argument('--scenarios', help='Komma-getrennte Test-Szenarien (valid,invalid,edge_cases,accessibility,etc.)')
    parser.add_argument('--browser', choices=['chromium', 'firefox', 'webkit'], default='chromium', help='Browser-Engine')
    parser.add_argument('--headless', action='store_true', default=True, help='Headless-Modus (Standard: True)')
    parser.add_argument('--headed', action='store_true', help='Browser-Fenster anzeigen (Gegenteil von headless)')
    parser.add_argument('--output', help='Ausgabeverzeichnis für Reports')
    parser.add_argument('--report-name', default='form_test_report', help='Name des generierten Reports')
    
    args = parser.parse_args()
    
    # Headless-Modus bestimmen
    headless = args.headless and not args.headed
    
    # Output-Verzeichnis
    output_dir = Path(args.output) if args.output else None
    
    # Test-Szenarien
    if args.comprehensive:
        test_scenarios = ['valid', 'invalid', 'edge_cases', 'accessibility', 'validations', 'responsive', 'dynamic', 'error_display']
    elif args.scenarios:
        test_scenarios = [s.strip() for s in args.scenarios.split(',')]
    else:
        test_scenarios = ['valid', 'invalid', 'accessibility']
    
    print(f"""
{'='*70}
🧪 FLASK HTML-FORMULAR TEST AUTOMATOR
{'='*70}

🎯 Target URL:      {args.url}
🌐 Browser:         {args.browser} ({'headless' if headless else 'headed'})
📋 Test-Szenarien: {', '.join(test_scenarios)}
📁 Output:          {output_dir or 'form_test_reports/'}

{'='*70}
""")
    
    try:
        # Test Automator initialisieren
        async with HTMLFormTestAutomator(
            base_url=args.url,
            browser=args.browser,
            headless=headless
        ) as automator:
            
            if output_dir:
                automator.reporter.output_dir = output_dir
            
            if args.test_all:
                # Alle Formulare auf der Seite testen
                results = await automator.test_all_forms_on_page('/', test_scenarios)
                
            elif args.form:
                # Spezifisches Formular testen
                results = await automator.test_form('/', args.form, test_scenarios=test_scenarios)
                
            elif args.multi_step and args.steps:
                # Multi-Step Formular testen
                steps = [s.strip() for s in args.steps.split(',')]
                results = await automator.test_multi_step_form('/', steps)
                
            elif args.responsive:
                # Responsive Testing
                devices = ['iPhone 12', 'iPad', 'Desktop 1920x1080']
                if args.devices:
                    devices = [d.strip() for d in args.devices.split(',')]
                
                results = await automator.test_form_on_devices('/', devices)
                
            else:
                # Standard: Alle Formulare mit Standard-Szenarien
                results = await automator.test_all_forms_on_page('/', test_scenarios)
            
            # Report generieren
            report_path = automator.generate_report(args.report_name)
            
            if report_path:
                print(f"\n🎉 Test abgeschlossen! Report verfügbar: {report_path}")
            else:
                print("\n⚠️ Test abgeschlossen, aber Report-Generierung fehlgeschlagen")
    
    except KeyboardInterrupt:
        print("\n⚠️ Test durch Benutzer abgebrochen")
    except Exception as e:
        print(f"\n❌ Fehler beim Test: {str(e)}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    if not PLAYWRIGHT_AVAILABLE:
        print("""
❌ PLAYWRIGHT NICHT VERFÜGBAR

Installiere Playwright mit:
    pip install playwright
    playwright install chromium

Oder installiere alle Dependencies:
    pip install playwright faker beautifulsoup4 rich
    playwright install
        """)
        exit(1)
    
    asyncio.run(main())