# social_networks/facebook/facebook_registration.py """ Facebook-Registrierung - Klasse für die Registrierungsfunktionalität bei Facebook """ import logging import time import re from typing import Dict, List, Any, Optional, Tuple from .facebook_selectors import FacebookSelectors from .facebook_workflow import FacebookWorkflow from utils.logger import setup_logger # Konfiguriere Logger logger = setup_logger("facebook_registration") class FacebookRegistration: """ Klasse für die Registrierung neuer Facebook-Konten. Enthält alle Methoden für den Registrierungsprozess. """ def __init__(self, automation): """ Initialisiert die Facebook-Registrierungs-Funktionalität. Args: automation: Referenz auf die Hauptautomatisierungsklasse """ self.automation = automation self.selectors = FacebookSelectors() self.workflow = FacebookWorkflow.get_registration_workflow() logger.debug("Facebook-Registrierung initialisiert") def register_account(self, account_data: Dict[str, Any]) -> Dict[str, Any]: """ Führt den Registrierungsprozess für einen neuen Facebook-Account durch. Args: account_data: Dictionary mit Account-Daten Returns: Dict[str, Any]: Ergebnis der Registrierung """ logger.info(f"Starte Facebook-Registrierung für {account_data['first_name']} {account_data['last_name']}") try: # 1. Zur Facebook-Hauptseite navigieren self.automation._send_status_update("Öffne Facebook-Webseite") self.automation._send_log_update("Navigiere zu Facebook...") if not self._navigate_to_facebook(): return { "success": False, "error": "Konnte nicht zu Facebook navigieren", "stage": "navigation" } # 2. Cookie-Consent behandeln self.automation._send_status_update("Behandle Cookie-Einstellungen") self.automation._send_log_update("Lehne optionale Cookies ab...") if not self._handle_cookie_consent(): logger.warning("Cookie-Consent konnte nicht behandelt werden, fahre trotzdem fort") # 3. Registrierungsformular öffnen self.automation._send_status_update("Öffne Registrierungsformular") self.automation._send_log_update("Klicke auf 'Neues Konto erstellen'...") if not self._open_registration_form(): return { "success": False, "error": "Konnte Registrierungsformular nicht öffnen", "stage": "open_form" } # 4. Registrierungsformular ausfüllen self.automation._send_status_update("Fülle Registrierungsformular aus") self.automation._send_log_update("Gebe persönliche Daten ein...") if not self._fill_registration_form(account_data): return { "success": False, "error": "Fehler beim Ausfüllen des Registrierungsformulars", "stage": "fill_form" } # 5. Formular absenden self.automation._send_status_update("Sende Registrierung ab") self.automation._send_log_update("Klicke auf 'Registrieren'...") if not self._submit_registration(): return { "success": False, "error": "Fehler beim Absenden der Registrierung", "stage": "submit" } # 6. E-Mail-Verifikation behandeln needs_verification = self._check_needs_verification() if needs_verification: self.automation._send_status_update("E-Mail-Verifikation erforderlich") self.automation._send_log_update("Warte auf Verifikationscode...") # Warte auf Verifikationscode verification_code = self._wait_for_verification_code(account_data.get("email")) if verification_code: if not self._enter_verification_code(verification_code): return { "success": False, "error": "Fehler bei der E-Mail-Verifikation", "stage": "verification" } else: return { "success": False, "error": "Verifikationscode nicht erhalten", "stage": "verification_timeout" } # 7. Erfolgreiche Registrierung überprüfen if not self._check_registration_success(): return { "success": False, "error": "Registrierung fehlgeschlagen", "stage": "final_check" } # Registrierung erfolgreich logger.info(f"Facebook-Account erfolgreich erstellt") self.automation._send_status_update("Registrierung erfolgreich!") self.automation._send_log_update("Account wurde erfolgreich erstellt") # Account-Daten für Rückgabe vorbereiten account_data["platform"] = "facebook" account_data["created_at"] = time.time() return { "success": True, "stage": "completed", "account_data": account_data } except Exception as e: error_msg = f"Unerwarteter Fehler bei der Facebook-Registrierung: {str(e)}" logger.error(error_msg, exc_info=True) return { "success": False, "error": error_msg, "stage": "exception", "account_data": account_data } def _navigate_to_facebook(self) -> bool: """ Navigiert zur Facebook-Hauptseite. Returns: bool: True bei Erfolg """ try: logger.info(f"Navigiere zu {self.automation.base_url}") # Navigiere zur Facebook-Seite navigation_success = self.automation.browser.navigate_to(self.automation.base_url) if not navigation_success: logger.error(f"Navigation zu {self.automation.base_url} fehlgeschlagen") return False # Warte auf Seitenladung self.automation.human_behavior.wait_for_page_load(multiplier=1.5) # Screenshot self.automation._take_screenshot("facebook_homepage") # Prüfe ob wir auf Facebook sind current_url = self.automation.browser.page.url logger.info(f"Aktuelle URL nach Navigation: {current_url}") # Debug: Prüfe sichtbare Elemente logger.debug(f"Sichtbare Buttons: {self.automation.browser.page.locator('button').count()}") logger.debug(f"Sichtbare Links: {self.automation.browser.page.locator('a').count()}") if "facebook.com" in current_url: logger.info("Erfolgreich zu Facebook navigiert") return True else: logger.error(f"Nicht auf Facebook gelandet: {current_url}") # Zusätzliche Debug-Info page_title = self.automation.browser.page.title() logger.debug(f"Seiten-Titel: {page_title}") return False except Exception as e: logger.error(f"Fehler bei Navigation zu Facebook: {e}") return False def _handle_cookie_consent(self) -> bool: """ Behandelt den Cookie-Consent-Dialog. Returns: bool: True wenn behandelt """ try: logger.info("Prüfe auf Cookie-Consent-Dialog") # Warte kurz auf möglichen Cookie-Dialog self.automation.human_behavior.random_delay(1.0, 2.0) # Versuche "Optionale Cookies ablehnen" zu klicken decline_clicked = False # Methode 1: Direkter Selektor if self.automation.browser.is_element_visible(self.selectors.COOKIE_DECLINE_BUTTON, timeout=2000): if self.automation.browser.click_element(self.selectors.COOKIE_DECLINE_BUTTON): logger.info("Cookie-Consent abgelehnt (Methode 1)") decline_clicked = True # Methode 2: Alternative Selektoren if not decline_clicked: for selector in [self.selectors.COOKIE_DECLINE_BUTTON_ALT, "button:has-text('Optionale Cookies ablehnen')", "//button[contains(., 'Optionale Cookies ablehnen')]"]: try: if self.automation.browser.click_element(selector, timeout=1000): logger.info(f"Cookie-Consent abgelehnt mit Selektor: {selector}") decline_clicked = True break except: continue # Methode 3: Fuzzy Button Click if not decline_clicked: if self.automation.ui_helper.click_button_fuzzy( self.selectors.get_button_texts("decline_cookies"), fallback_selector="button" ): logger.info("Cookie-Consent abgelehnt (Fuzzy Match)") decline_clicked = True if decline_clicked: # Warte auf Dialog-Schließung self.automation.human_behavior.random_delay(1.0, 2.0) self.automation._take_screenshot("after_cookie_consent") return True else: logger.debug("Kein Cookie-Consent-Dialog gefunden oder bereits behandelt") return False except Exception as e: logger.error(f"Fehler bei Cookie-Consent-Behandlung: {e}") return False def _open_registration_form(self) -> bool: """ Öffnet das Registrierungsformular. Returns: bool: True bei Erfolg """ try: logger.info("Öffne Registrierungsformular") # Versuche "Neues Konto erstellen" zu klicken button_clicked = False # Methode 1: data-testid Selektor if self.automation.browser.is_element_visible(self.selectors.CREATE_ACCOUNT_BUTTON, timeout=3000): if self.automation.browser.click_element(self.selectors.CREATE_ACCOUNT_BUTTON): logger.info("Registrierungsformular geöffnet (data-testid)") button_clicked = True # Methode 2: Alternative Selektoren if not button_clicked: for selector in [self.selectors.CREATE_ACCOUNT_BUTTON_ALT, "a:has-text('Neues Konto erstellen')", "a[href*='/r.php']"]: try: if self.automation.browser.click_element(selector, timeout=2000): logger.info(f"Registrierungsformular geöffnet mit: {selector}") button_clicked = True break except: continue # Methode 3: Fuzzy Button Click if not button_clicked: if self.automation.ui_helper.click_button_fuzzy( self.selectors.get_button_texts("create_account") ): logger.info("Registrierungsformular geöffnet (Fuzzy Match)") button_clicked = True if button_clicked: # Warte auf Formular-Ladung mit längerer Wartezeit self.automation.human_behavior.wait_for_page_load(multiplier=2.0) # Extra Wartezeit für Facebook's React-Rendering self.automation.human_behavior.random_delay(2.0, 3.0) # Prüfe ob Browser noch aktiv ist if not self.automation.browser or not self.automation.browser.page: logger.error("Browser wurde unerwartet geschlossen") return False try: self.automation._take_screenshot("registration_form") except Exception as e: logger.warning(f"Screenshot fehlgeschlagen: {e}") # Prüfe ob wir auf der Registrierungsseite sind try: current_url = self.automation.browser.page.url if "/r.php" in current_url or "registration" in current_url: logger.info("Registrierungsformular erfolgreich geöffnet") return True except Exception as e: logger.error(f"Fehler beim Abrufen der URL: {e}") return False logger.error("Konnte Registrierungsformular nicht öffnen") return False except Exception as e: logger.error(f"Fehler beim Öffnen des Registrierungsformulars: {e}") return False def _fill_registration_form(self, account_data: Dict[str, Any]) -> bool: """ Füllt das Registrierungsformular aus. Verbesserte Version mit Fallback-Selektoren und robusterem Handling. Args: account_data: Account-Daten Returns: bool: True bei Erfolg """ try: logger.info("Fülle Registrierungsformular aus") # Prüfe ob Browser noch aktiv ist if not self.automation.browser or not self.automation.browser.page: logger.error("Browser ist nicht mehr aktiv vor Formular-Ausfüllung") return False # Debug: Prüfe welche Input-Felder sichtbar sind try: visible_inputs = self.automation.browser.page.locator("input[type='text']").count() logger.debug(f"Anzahl sichtbarer Text-Input-Felder: {visible_inputs}") # Liste alle sichtbaren Inputs mit Namen auf all_inputs = self.automation.browser.page.locator("input").all() for idx, inp in enumerate(all_inputs[:10]): # Nur erste 10 zur Sicherheit try: name = inp.get_attribute("name") placeholder = inp.get_attribute("placeholder") aria_label = inp.get_attribute("aria-label") logger.debug(f"Input {idx}: name='{name}', placeholder='{placeholder}', aria-label='{aria_label}'") except: pass except Exception as e: logger.warning(f"Debug-Ausgabe fehlgeschlagen: {e}") # Vorname mit Fallback firstname_selectors = [ self.selectors.REG_FIRSTNAME_FIELD, self.selectors.REG_FIRSTNAME_FIELD_ALT, "input[placeholder*='Vorname']", "input[name='firstname']", # Direkter Name-Selektor "input[aria-label*='Vorname' i]" # Case-insensitive aria-label ] firstname_filled = False for selector in firstname_selectors: logger.debug(f"Versuche Vorname-Selektor: {selector}") try: if self.automation.browser.is_element_visible(selector, timeout=1000): logger.debug(f"Selektor {selector} ist sichtbar") if self.automation.ui_helper.type_text_human_like(selector, account_data["first_name"]): logger.info(f"Vorname eingegeben mit: {selector}") firstname_filled = True break else: logger.debug(f"Selektor {selector} nicht sichtbar") except Exception as e: logger.debug(f"Fehler bei Selektor {selector}: {e}") if not firstname_filled: logger.error(f"Fehler beim Eingeben des Vornamens. Getestete Selektoren: {firstname_selectors}") # Zusätzliche Debug-Info try: current_url = self.automation.browser.page.url logger.error(f"Aktuelle URL beim Fehler: {current_url}") except: pass return False # Nachname mit Fallback lastname_selectors = [ self.selectors.REG_LASTNAME_FIELD, self.selectors.REG_LASTNAME_FIELD_ALT, "input[placeholder*='Nachname']" ] lastname_filled = False for selector in lastname_selectors: if self.automation.browser.is_element_visible(selector, timeout=1000): if self.automation.ui_helper.type_text_human_like(selector, account_data["last_name"]): logger.info(f"Nachname eingegeben mit: {selector}") lastname_filled = True break if not lastname_filled: logger.error("Fehler beim Eingeben des Nachnamens") return False # Geburtsdatum - Verbesserte Dropdown-Behandlung birth_date = account_data["birth_date"] # Tag auswählen mit Fallback day_selectors = [ self.selectors.REG_BIRTHDAY_DAY, self.selectors.REG_BIRTHDAY_DAY_ALT, "select[aria-label='Tag']", "select[title='Tag']" ] day_selected = False for selector in day_selectors: try: if self.automation.browser.select_option(selector, str(birth_date["day"])): logger.info(f"Tag {birth_date['day']} ausgewählt mit: {selector}") day_selected = True break except: continue if not day_selected: logger.error("Fehler beim Auswählen des Geburtstags") return False self.automation.human_behavior.random_delay(0.3, 0.5) # Monat auswählen mit Fallback month_selectors = [ self.selectors.REG_BIRTHDAY_MONTH, self.selectors.REG_BIRTHDAY_MONTH_ALT, "select[aria-label='Monat']", "select[title='Monat']" ] month_selected = False for selector in month_selectors: try: if self.automation.browser.select_option(selector, str(birth_date["month"])): logger.info(f"Monat {birth_date['month']} ausgewählt mit: {selector}") month_selected = True break except: continue if not month_selected: logger.error("Fehler beim Auswählen des Geburtsmonats") return False self.automation.human_behavior.random_delay(0.3, 0.5) # Jahr auswählen mit Fallback year_selectors = [ self.selectors.REG_BIRTHDAY_YEAR, self.selectors.REG_BIRTHDAY_YEAR_ALT, "select[aria-label='Jahr']", "select[title='Jahr']" ] year_selected = False for selector in year_selectors: try: if self.automation.browser.select_option(selector, str(birth_date["year"])): logger.info(f"Jahr {birth_date['year']} ausgewählt mit: {selector}") year_selected = True break except: continue if not year_selected: logger.error("Fehler beim Auswählen des Geburtsjahrs") return False self.automation.human_behavior.random_delay(0.5, 1.0) # Geschlecht auswählen - Verbesserte Radio-Button Behandlung gender_selector = self.selectors.get_gender_selector(account_data["gender"]) gender_selected = False # Versuche erst direkten Click auf das Input-Element if self.automation.browser.click_element(gender_selector): logger.info(f"Geschlecht direkt ausgewählt: {account_data['gender']}") gender_selected = True else: # Fallback: Klicke auf das Label label_selectors = [ f"label:has-text('{'Weiblich' if account_data['gender'] == 'female' else 'Männlich' if account_data['gender'] == 'male' else 'Divers'}')", f"label._58mt:has(input[value='{'1' if account_data['gender'] == 'female' else '2' if account_data['gender'] == 'male' else '-1'}'])" ] for selector in label_selectors: try: if self.automation.browser.click_element(selector): logger.info(f"Geschlecht über Label ausgewählt: {account_data['gender']}") gender_selected = True break except: continue if not gender_selected: logger.error(f"Fehler beim Auswählen des Geschlechts: {account_data['gender']}") return False self.automation.human_behavior.random_delay(0.5, 1.0) # E-Mail eingeben mit Fallback email_field = account_data.get("email") if not email_field: logger.error("Keine E-Mail-Adresse angegeben") return False email_selectors = [ self.selectors.REG_EMAIL_OR_PHONE, self.selectors.REG_EMAIL_OR_PHONE_ALT, "input[placeholder*='E-Mail']", "input[placeholder*='Handynummer oder E-Mail']" ] email_filled = False for selector in email_selectors: if self.automation.browser.is_element_visible(selector, timeout=1000): if self.automation.ui_helper.type_text_human_like(selector, email_field): logger.info(f"E-Mail eingegeben mit: {selector}") email_filled = True break if not email_filled: logger.error("Fehler beim Eingeben der E-Mail") return False # Warte auf mögliches E-Mail-Bestätigungsfeld self.automation.human_behavior.random_delay(1.0, 2.0) # E-Mail-Bestätigung falls erforderlich if self.automation.browser.is_element_visible(self.selectors.REG_EMAIL_CONFIRM, timeout=2000): logger.info("E-Mail-Bestätigungsfeld erkannt") if not self.automation.ui_helper.type_text_human_like( self.selectors.REG_EMAIL_CONFIRM, email_field ): logger.warning("Fehler beim Bestätigen der E-Mail") # Passwort mit Fallback password_selectors = [ self.selectors.REG_PASSWORD, self.selectors.REG_PASSWORD_ALT, self.selectors.REG_PASSWORD_ALT2, "input[type='password']", "input[autocomplete='new-password']" ] password_filled = False for selector in password_selectors: if self.automation.browser.is_element_visible(selector, timeout=1000): if self.automation.ui_helper.type_text_human_like(selector, account_data["password"]): logger.info(f"Passwort eingegeben mit: {selector}") password_filled = True break if not password_filled: logger.error("Fehler beim Eingeben des Passworts") return False # Screenshot des ausgefüllten Formulars self.automation._take_screenshot("filled_registration_form") logger.info("Registrierungsformular erfolgreich ausgefüllt") return True except Exception as e: logger.error(f"Fehler beim Ausfüllen des Registrierungsformulars: {e}") return False def _submit_registration(self) -> bool: """ Sendet das Registrierungsformular ab. Returns: bool: True bei Erfolg """ try: logger.info("Sende Registrierungsformular ab") # Versuche Submit-Button zu klicken submit_clicked = False # Methode 1: Name-Attribut if self.automation.browser.is_element_visible(self.selectors.REG_SUBMIT_BUTTON, timeout=2000): if self.automation.browser.click_element(self.selectors.REG_SUBMIT_BUTTON): logger.info("Registrierung abgesendet (name-Attribut)") submit_clicked = True # Methode 2: Text-basiert if not submit_clicked: for text in self.selectors.get_button_texts("register"): selector = f"button:has-text('{text}')" try: if self.automation.browser.click_element(selector, timeout=1000): logger.info(f"Registrierung abgesendet mit: {selector}") submit_clicked = True break except: continue # Methode 3: Fuzzy Match if not submit_clicked: if self.automation.ui_helper.click_button_fuzzy( self.selectors.get_button_texts("register") ): logger.info("Registrierung abgesendet (Fuzzy Match)") submit_clicked = True if submit_clicked: # Warte auf Navigation self.automation.human_behavior.wait_for_page_load(multiplier=2.0) self.automation._take_screenshot("after_submit") return True else: logger.error("Konnte Registrierung nicht absenden") return False except Exception as e: logger.error(f"Fehler beim Absenden der Registrierung: {e}") return False def _check_needs_verification(self) -> bool: """ Prüft ob eine E-Mail-Verifikation erforderlich ist. Returns: bool: True wenn Verifikation erforderlich """ try: # Warte kurz self.automation.human_behavior.random_delay(2.0, 3.0) # Prüfe URL current_url = self.automation.browser.page.url if "confirmemail" in current_url or "confirm" in current_url: logger.info("E-Mail-Verifikation erforderlich (URL-Check)") return True # Prüfe auf Verifikations-Input if self.automation.browser.is_element_visible(self.selectors.VERIFICATION_CODE_INPUT, timeout=2000): logger.info("E-Mail-Verifikation erforderlich (Input-Field)") return True # Prüfe auf Verifikations-Text page_content = self.automation.browser.page.content().lower() verification_keywords = ["bestätigungscode", "verification code", "confirm email", "code eingeben"] for keyword in verification_keywords: if keyword in page_content: logger.info(f"E-Mail-Verifikation erforderlich (Keyword: {keyword})") return True logger.info("Keine E-Mail-Verifikation erforderlich") return False except Exception as e: logger.error(f"Fehler bei Verifikations-Check: {e}") return False def _wait_for_verification_code(self, email: str) -> Optional[str]: """ Wartet auf den Verifikationscode aus der E-Mail. Args: email: E-Mail-Adresse Returns: Optional[str]: Verifikationscode oder None """ logger.info(f"Warte auf Verifikationscode für {email}") # Delegiere an Verification-Klasse return self.automation.verification.wait_for_email_code(email, timeout=120) def _enter_verification_code(self, code: str) -> bool: """ Gibt den Verifikationscode ein. Verbesserte Version für 5-stelligen Code mit Fallback-Selektoren. Args: code: Verifikationscode (5-stellig, nur Zahlen) Returns: bool: True bei Erfolg """ try: # Extrahiere nur Zahlen aus dem Code (falls FB- prefix vorhanden) import re code_digits = re.sub(r'\D', '', code) if len(code_digits) == 5: code = code_digits logger.info(f"Gebe Verifikationscode ein: {code}") # Versuche verschiedene Selektoren für das Code-Eingabefeld code_selectors = [ self.selectors.VERIFICATION_CODE_INPUT, # input#code_in_cliff self.selectors.VERIFICATION_CODE_INPUT_ALT, # input[name='code'] self.selectors.VERIFICATION_CODE_INPUT_ALT2, # input[maxlength='5'] "input[size='5']", # 5-stelliges Feld "input[type='text'][maxlength='5']", # Text-Input mit 5 Zeichen "input[placeholder*='Code']", # Placeholder mit 'Code' ] code_entered = False for selector in code_selectors: try: if self.automation.browser.is_element_visible(selector, timeout=1000): # Stelle sicher, dass das Feld leer ist self.automation.browser.page.locator(selector).first.clear() self.automation.human_behavior.random_delay(0.2, 0.4) # Gebe Code ein if self.automation.ui_helper.type_text_human_like(selector, code): logger.info(f"Verifikationscode eingegeben mit: {selector}") code_entered = True break except: continue if not code_entered: logger.error("Fehler beim Eingeben des Verifikationscodes - kein Eingabefeld gefunden") return False self.automation.human_behavior.random_delay(0.5, 1.0) # Weiter-Button klicken continue_clicked = False # Versuche verschiedene Button-Selektoren continue_selectors = [ self.selectors.VERIFICATION_CONTINUE_BUTTON, # button:has-text('Weiter') self.selectors.VERIFICATION_CONTINUE_BUTTON_EN, # button:has-text('Continue') "button[type='submit']", # Submit-Button "button:has-text('Bestätigen')", # Bestätigen "button:has-text('Confirm')", # Englisch "button:has-text('OK')", # OK ] for selector in continue_selectors: try: if self.automation.browser.click_element(selector, timeout=1000): logger.info(f"Verifikation fortgesetzt mit: {selector}") continue_clicked = True break except: continue # Fallback: Enter drücken if not continue_clicked: self.automation.browser.page.keyboard.press("Enter") logger.info("Verifikation mit Enter fortgesetzt") continue_clicked = True if not continue_clicked: logger.error("Konnte Verifikation nicht fortsetzen") return False # Warte auf Navigation/Verarbeitung self.automation.human_behavior.wait_for_page_load(multiplier=1.5) # Prüfe auf OK-Button (Popup nach erfolgreicher Verifikation) ok_selectors = [ self.selectors.VERIFICATION_OK_BUTTON, self.selectors.VERIFICATION_OK_BUTTON_ALT, "a:has-text('OK')", "button:has-text('OK')" ] for selector in ok_selectors: try: if self.automation.browser.is_element_visible(selector, timeout=2000): self.automation.browser.click_element(selector) logger.info(f"OK-Button nach Verifikation geklickt: {selector}") break except: continue return True except Exception as e: logger.error(f"Fehler beim Eingeben des Verifikationscodes: {e}") return False def _check_registration_success(self) -> bool: """ Überprüft ob die Registrierung erfolgreich war. Returns: bool: True bei Erfolg """ try: # Warte auf finale Navigation self.automation.human_behavior.wait_for_page_load(multiplier=2.0) # Screenshot self.automation._take_screenshot("registration_final") # Prüfe URL current_url = self.automation.browser.page.url logger.info(f"Finale URL: {current_url}") # Erfolgs-URLs success_patterns = [ "facebook.com/?", "facebook.com/home", "facebook.com/feed", "welcome", "onboarding" ] for pattern in success_patterns: if pattern in current_url: logger.info(f"Registrierung erfolgreich (URL-Pattern: {pattern})") return True # Prüfe auf Erfolgs-Indikatoren for indicator in self.selectors.SUCCESS_INDICATORS: if self.automation.browser.is_element_visible(indicator, timeout=2000): logger.info(f"Registrierung erfolgreich (Indikator: {indicator})") return True # Prüfe auf Fehler if self.automation.browser.is_element_visible(self.selectors.ERROR_MESSAGE, timeout=1000): error_text = self.automation.browser.get_text(self.selectors.ERROR_MESSAGE) logger.error(f"Registrierungsfehler: {error_text}") return False # Bei Unsicherheit als erfolgreich werten wenn keine Login-Form mehr da ist if not self.automation.browser.is_element_visible(self.selectors.REG_FIRSTNAME_FIELD, timeout=1000): logger.info("Registrierung wahrscheinlich erfolgreich (kein Formular mehr sichtbar)") return True logger.warning("Registrierungsstatus unklar") return False except Exception as e: logger.error(f"Fehler bei Erfolgs-Check: {e}") return False