Files
AccountForger-neuerUpload/social_networks/facebook/facebook_registration.py
2025-10-11 23:19:27 +02:00

878 Zeilen
37 KiB
Python

# 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.
Wartet auf Navigation zur Verifikationsseite falls nötig.
Returns:
bool: True wenn Verifikation erforderlich
"""
try:
# Warte auf Page-Load nach Submit
self.automation.human_behavior.wait_for_page_load(multiplier=1.5)
# Warte zusätzlich auf mögliche Navigation zur Verifikationsseite
# Versuche bis zu 10 Sekunden lang die URL zu prüfen
max_wait_time = 10 # Sekunden
check_interval = 0.5 # Sekunden
attempts = int(max_wait_time / check_interval)
for attempt in range(attempts):
current_url = self.automation.browser.page.url
logger.debug(f"Prüfe URL (Versuch {attempt + 1}/{attempts}): {current_url}")
# Prüfe URL auf Verifikations-Pattern
if "confirmemail" in current_url or "confirm" in current_url:
logger.info(f"E-Mail-Verifikation erforderlich (URL-Check): {current_url}")
return True
# Prüfe auf Verifikations-Input
if self.automation.browser.is_element_visible(self.selectors.VERIFICATION_CODE_INPUT, timeout=500):
logger.info("E-Mail-Verifikation erforderlich (Input-Field gefunden)")
return True
# Prüfe auf Erfolgs-Indikatoren (dann keine Verifikation nötig)
for indicator in self.selectors.SUCCESS_INDICATORS:
if self.automation.browser.is_element_visible(indicator, timeout=500):
logger.info(f"Keine Verifikation nötig (Erfolgs-Indikator gefunden: {indicator})")
return False
# Kurze Pause vor nächstem Versuch
time.sleep(check_interval)
# Nach max_wait_time: Finale Prüfung mit Keywords
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