Rollbackpunkt, alles außer TikTok geht, die wollen wieder so eine extra locke bei Login
Dieser Commit ist enthalten in:
@ -520,16 +520,21 @@ class FacebookAutomation(BaseAutomation):
|
||||
bool: True bei Erfolg, False bei Fehler
|
||||
"""
|
||||
try:
|
||||
# Lade gespeicherten Fingerprint für Account
|
||||
saved_fingerprint = self.fingerprint_service.get_fingerprint_for_account(account_id, "facebook")
|
||||
|
||||
if saved_fingerprint:
|
||||
fingerprint = self.fingerprint_service.get_account_fingerprint(account_id)
|
||||
|
||||
if fingerprint:
|
||||
logger.info(f"Verwende gespeicherten Fingerprint für Account {account_id}")
|
||||
self.provided_fingerprint = saved_fingerprint
|
||||
else:
|
||||
logger.info(f"Kein gespeicherter Fingerprint für Account {account_id}, generiere neuen")
|
||||
self.provided_fingerprint = self.fingerprint_service.generate_fingerprint("facebook")
|
||||
|
||||
fingerprint = self.fingerprint_service.create_account_fingerprint(
|
||||
account_id=account_id,
|
||||
profile_type="desktop",
|
||||
platform="facebook"
|
||||
)
|
||||
|
||||
self.provided_fingerprint = fingerprint.to_dict() if hasattr(fingerprint, 'to_dict') else fingerprint
|
||||
self.account_fingerprint = fingerprint
|
||||
|
||||
# Browser mit Fingerprint initialisieren
|
||||
return self._initialize_browser()
|
||||
|
||||
@ -569,4 +574,4 @@ class FacebookAutomation(BaseAutomation):
|
||||
base_email += str(random.randint(1, 999))
|
||||
|
||||
# Füge Domain hinzu
|
||||
return f"{base_email}@{self.email_domain}"
|
||||
return f"{base_email}@{self.email_domain}"
|
||||
|
||||
@ -6,8 +6,11 @@ Placeholder für zukünftige Implementierung.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
|
||||
|
||||
from .facebook_selectors import FacebookSelectors
|
||||
from .facebook_workflow import FacebookWorkflow
|
||||
@ -47,12 +50,205 @@ class FacebookLogin:
|
||||
Dict[str, Any]: Ergebnis des Logins
|
||||
"""
|
||||
logger.info(f"Starte Facebook-Login für {email_or_phone}")
|
||||
|
||||
# TODO: Implementierung sobald Login-Details verfügbar
|
||||
logger.warning("Facebook-Login noch nicht vollständig implementiert")
|
||||
|
||||
|
||||
automation = self.automation
|
||||
browser_manager = automation.browser
|
||||
|
||||
if browser_manager is None or not getattr(browser_manager, "page", None):
|
||||
if not automation._initialize_browser():
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Browser konnte nicht initialisiert werden",
|
||||
"stage": "browser_init"
|
||||
}
|
||||
browser_manager = automation.browser
|
||||
|
||||
page = browser_manager.page
|
||||
|
||||
raw_account_data = kwargs.get("raw_account_data") or {}
|
||||
target_email = raw_account_data.get("email")
|
||||
if not target_email and email_or_phone and "@" in email_or_phone:
|
||||
target_email = email_or_phone
|
||||
|
||||
login_url = "https://www.facebook.com/?locale=de_DE"
|
||||
|
||||
automation._send_status_update("Öffne Facebook")
|
||||
automation._send_log_update("Navigiere zur Facebook-Startseite...")
|
||||
|
||||
if not browser_manager.navigate_to(login_url):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Konnte Facebook nicht öffnen",
|
||||
"stage": "navigation_failed"
|
||||
}
|
||||
|
||||
self._reject_optional_cookies(browser_manager)
|
||||
|
||||
automation._send_status_update("Fülle Login-Formular aus")
|
||||
automation._send_log_update("Gebe Zugangsdaten ein...")
|
||||
|
||||
if not browser_manager.fill_form_field("#email", email_or_phone):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "E-Mail/Telefon-Feld konnte nicht ausgefüllt werden",
|
||||
"stage": "fill_email"
|
||||
}
|
||||
|
||||
if not browser_manager.fill_form_field("#pass", password):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Passwortfeld konnte nicht ausgefüllt werden",
|
||||
"stage": "fill_password"
|
||||
}
|
||||
|
||||
automation._send_status_update("Sende Login-Daten")
|
||||
if not browser_manager.click_element("button[data-testid='royal-login-button']"):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Login-Button konnte nicht geklickt werden",
|
||||
"stage": "click_login"
|
||||
}
|
||||
|
||||
try:
|
||||
page.wait_for_load_state("networkidle", timeout=15000)
|
||||
except PlaywrightTimeoutError:
|
||||
logger.debug("Warten auf Netzwerk-Leerlauf nach Login abgelaufen")
|
||||
|
||||
# Prüfe auf Zwei-Faktor-Authentifizierung
|
||||
if "auth_platform/codesubmit" in page.url:
|
||||
automation._send_status_update("Zwei-Faktor-Verifizierung erforderlich")
|
||||
automation._send_log_update("Warte auf E-Mail mit Sicherheitscode...")
|
||||
|
||||
if not target_email:
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Zwei-Faktor-Code erforderlich, aber keine E-Mail für den Account vorhanden",
|
||||
"stage": "two_factor_missing_email"
|
||||
}
|
||||
|
||||
if not self._handle_two_factor(page, browser_manager, target_email):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Zwei-Faktor-Verifizierung fehlgeschlagen",
|
||||
"stage": "two_factor_failed"
|
||||
}
|
||||
|
||||
try:
|
||||
page.wait_for_load_state("networkidle", timeout=15000)
|
||||
except PlaywrightTimeoutError:
|
||||
logger.debug("Warten nach 2FA auf Netzwerk-Leerlauf abgelaufen")
|
||||
|
||||
# Prüfe auf Login-Erfolg oder Fehler
|
||||
if self._detect_login_error(browser_manager):
|
||||
error_message = self._extract_error_message(browser_manager)
|
||||
return {
|
||||
"success": False,
|
||||
"error": error_message or "Login fehlgeschlagen",
|
||||
"stage": "login_failed"
|
||||
}
|
||||
|
||||
if not self._await_login_success(page):
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Login konnte nicht bestätigt werden",
|
||||
"stage": "login_unknown"
|
||||
}
|
||||
|
||||
self._dismiss_post_login_dialog(page)
|
||||
|
||||
automation._send_status_update("Login erfolgreich")
|
||||
automation._send_log_update("Facebook-Login abgeschlossen")
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Login-Funktion noch nicht implementiert",
|
||||
"stage": "not_implemented"
|
||||
}
|
||||
"success": True,
|
||||
"stage": "completed",
|
||||
"username": email_or_phone
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Hilfsmethoden
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _reject_optional_cookies(self, browser_manager) -> None:
|
||||
"""Klickt den Button "Optionale Cookies ablehnen", falls vorhanden."""
|
||||
page = browser_manager.page
|
||||
try:
|
||||
button = page.locator("text=Optionale Cookies ablehnen").first
|
||||
button.wait_for(state="visible", timeout=5000)
|
||||
button.click()
|
||||
logger.info("Optionale Cookies abgelehnt")
|
||||
except PlaywrightTimeoutError:
|
||||
logger.debug("Cookie-Banner nicht gefunden oder bereits geschlossen")
|
||||
except Exception as e:
|
||||
logger.warning(f"Konnte Cookie-Banner nicht schließen: {e}")
|
||||
|
||||
def _handle_two_factor(self, page, browser_manager, target_email: str) -> bool:
|
||||
"""Handhabt die Eingabe des Zwei-Faktor-Codes."""
|
||||
self.automation._send_log_update("Versuche Sicherheitscode aus E-Mail zu lesen...")
|
||||
|
||||
code = self.automation.email_handler.get_verification_code(
|
||||
target_email=target_email,
|
||||
platform="facebook",
|
||||
max_attempts=60,
|
||||
delay_seconds=5
|
||||
)
|
||||
|
||||
if not code:
|
||||
logger.error("Kein Zwei-Faktor-Code gefunden")
|
||||
return False
|
||||
|
||||
logger.info("Trage Zwei-Faktor-Code ein")
|
||||
self.automation._send_log_update("Zwei-Faktor-Code gefunden – trage ihn ein...")
|
||||
if not browser_manager.fill_form_field("input[name='email']", code):
|
||||
logger.error("Zwei-Faktor-Eingabefeld konnte nicht gefüllt werden")
|
||||
return False
|
||||
|
||||
try:
|
||||
page.locator("text=Weiter").first.click()
|
||||
self.automation._send_log_update("Weiter mit Zwei-Faktor-Verifizierung...")
|
||||
except PlaywrightTimeoutError:
|
||||
logger.error("Weiter-Button nach Zwei-Faktor-Eingabe nicht gefunden")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Klicken auf den Weiter-Button: {e}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _detect_login_error(self, browser_manager) -> bool:
|
||||
"""Überprüft, ob ein Fehler nach dem Login angezeigt wird."""
|
||||
error_selector = "div[data-testid='error_box'], div._9ay7"
|
||||
element = browser_manager.wait_for_selector(error_selector, timeout=2000)
|
||||
return bool(element)
|
||||
|
||||
def _extract_error_message(self, browser_manager) -> Optional[str]:
|
||||
element = browser_manager.wait_for_selector("div[data-testid='error_box'], div._9ay7", timeout=2000)
|
||||
if not element:
|
||||
return None
|
||||
try:
|
||||
text = element.inner_text().strip()
|
||||
logger.error(f"Facebook-Login-Fehler: {text}")
|
||||
return text
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _await_login_success(self, page) -> bool:
|
||||
"""Wartet auf eine Seite, die einen erfolgreichen Login vermuten lässt."""
|
||||
target_pattern = re.compile(r"https://www\.facebook\.com/(?!login|checkpoint).*")
|
||||
try:
|
||||
page.wait_for_url(target_pattern, timeout=15000)
|
||||
return True
|
||||
except PlaywrightTimeoutError:
|
||||
logger.debug(f"Aktuelle URL nach Login: {page.url}")
|
||||
return bool(target_pattern.match(page.url))
|
||||
|
||||
def _dismiss_post_login_dialog(self, page) -> None:
|
||||
"""Schließt nach dem Login auftauchende Dialoge."""
|
||||
try:
|
||||
close_button = page.locator("button:has-text('Schließen')").first
|
||||
close_button.click(timeout=3000)
|
||||
logger.info("Post-Login-Dialog geschlossen")
|
||||
except PlaywrightTimeoutError:
|
||||
logger.debug("Kein Post-Login-Dialog zum Schließen gefunden")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -124,22 +124,69 @@ class FacebookRegistration:
|
||||
}
|
||||
|
||||
# 7. Erfolgreiche Registrierung überprüfen
|
||||
if not self._check_registration_success():
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Registrierung fehlgeschlagen",
|
||||
"stage": "final_check"
|
||||
}
|
||||
|
||||
success_check = self._check_registration_success()
|
||||
|
||||
# 8. Wenn nicht erfolgreich: Prüfe auf Cookie-Consent oder andere Zwischen-Schritte
|
||||
if not success_check:
|
||||
current_url = self.automation.browser.page.url
|
||||
logger.info(f"Success-Check fehlgeschlagen, prüfe Zwischen-Schritte: {current_url}")
|
||||
|
||||
# Behandle Cookie-Consent falls vorhanden
|
||||
if "privacy/consent" in current_url or "user_cookie_choice" in current_url:
|
||||
logger.info("Cookie-Consent Dialog erkannt (nach Verifikation)")
|
||||
self.automation._send_log_update("Behandle Cookie-Einstellungen...")
|
||||
|
||||
if self._handle_cookie_consent():
|
||||
logger.info("Cookie-Consent erfolgreich behandelt")
|
||||
# Warte nach Cookie-Ablehnung
|
||||
self.automation.human_behavior.wait_for_page_load(multiplier=1.5)
|
||||
|
||||
# Prüfe auf finalen Dialog/Layer mit "Schließen"-Button
|
||||
if self._handle_final_dialogs():
|
||||
logger.info("Finale Dialogs behandelt")
|
||||
|
||||
# Erneuter Success-Check
|
||||
success_check = self._check_registration_success()
|
||||
|
||||
if not success_check:
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Registrierung fehlgeschlagen (nach Zwischen-Schritten)",
|
||||
"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()
|
||||
|
||||
|
||||
# Username generieren falls nicht vorhanden (Facebook gibt keinen zurück)
|
||||
if not account_data.get("username"):
|
||||
username = self._generate_username_from_email(
|
||||
account_data.get("email", ""),
|
||||
account_data.get("first_name", ""),
|
||||
account_data.get("last_name", "")
|
||||
)
|
||||
# Username ist GARANTIERT vorhanden (Fallback-Strategien)
|
||||
account_data["username"] = username
|
||||
logger.info(f"Username generiert: {username}")
|
||||
|
||||
# KRITISCHE VALIDIERUNG: Stelle sicher dass Username vorhanden ist
|
||||
if not account_data.get("username") or account_data["username"] == "":
|
||||
error_msg = "KRITISCHER FEHLER: Username konnte nicht generiert werden"
|
||||
logger.error(error_msg)
|
||||
logger.error(f"Account-Daten: {account_data}")
|
||||
return {
|
||||
"success": False,
|
||||
"error": error_msg,
|
||||
"stage": "username_validation_failed",
|
||||
"account_data": account_data
|
||||
}
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"stage": "completed",
|
||||
@ -672,11 +719,15 @@ class FacebookRegistration:
|
||||
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
|
||||
# Prüfe auf Erfolgs-Indikatoren NUR wenn URL eindeutig KEINE Verifikations-URL ist
|
||||
# WICHTIG: Verifikationsseiten haben auch div[role='navigation'], deshalb URL-Check zuerst!
|
||||
if "privacy/consent" not in current_url and "user_cookie_choice" not in current_url:
|
||||
for indicator in self.selectors.SUCCESS_INDICATORS:
|
||||
if self.automation.browser.is_element_visible(indicator, timeout=500):
|
||||
# Finale Prüfung: Ist es wirklich eine Erfolgsseite?
|
||||
if "facebook.com/?" in current_url or "facebook.com/home" in current_url or "feed" in current_url:
|
||||
logger.info(f"Keine Verifikation nötig (Erfolgs-Indikator gefunden: {indicator})")
|
||||
return False
|
||||
|
||||
# Kurze Pause vor nächstem Versuch
|
||||
time.sleep(check_interval)
|
||||
@ -797,48 +848,182 @@ class FacebookRegistration:
|
||||
|
||||
# Warte auf Navigation/Verarbeitung
|
||||
self.automation.human_behavior.wait_for_page_load(multiplier=1.5)
|
||||
|
||||
|
||||
# Prüfe auf OK-Button (Popup nach erfolgreicher Verifikation)
|
||||
# Warte länger, da das Popup verzögert erscheinen kann
|
||||
self.automation.human_behavior.random_delay(1.0, 2.0)
|
||||
|
||||
ok_selectors = [
|
||||
self.selectors.VERIFICATION_OK_BUTTON,
|
||||
self.selectors.VERIFICATION_OK_BUTTON_ALT,
|
||||
"a:has-text('OK')",
|
||||
"button:has-text('OK')"
|
||||
self.selectors.VERIFICATION_OK_BUTTON, # a.layerCancel:has-text('OK')
|
||||
self.selectors.VERIFICATION_OK_BUTTON_ALT, # a[role='button']:has-text('OK')
|
||||
"a.layerCancel", # Nur Klasse (falls Text-Match fehlschlägt)
|
||||
"a[role='button']._42ft._42fu.layerCancel", # Spezifische Klassen
|
||||
"a:has-text('OK')", # Allgemeiner Link
|
||||
"button:has-text('OK')" # Button-Fallback
|
||||
]
|
||||
|
||||
|
||||
ok_button_clicked = False
|
||||
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:
|
||||
if self.automation.browser.is_element_visible(selector, timeout=5000):
|
||||
logger.info(f"OK-Button gefunden mit: {selector}")
|
||||
if self.automation.browser.click_element(selector, timeout=2000):
|
||||
logger.info(f"OK-Button nach Verifikation erfolgreich geklickt: {selector}")
|
||||
ok_button_clicked = True
|
||||
break
|
||||
else:
|
||||
logger.warning(f"OK-Button Click fehlgeschlagen für: {selector}")
|
||||
except Exception as e:
|
||||
logger.debug(f"Fehler beim OK-Button Click mit {selector}: {e}")
|
||||
continue
|
||||
|
||||
|
||||
if ok_button_clicked:
|
||||
# Warte nach OK-Click auf finale Navigation
|
||||
self.automation.human_behavior.wait_for_page_load(multiplier=1.5)
|
||||
else:
|
||||
logger.warning("OK-Button nach Verifikation nicht gefunden oder Click fehlgeschlagen")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Eingeben des Verifikationscodes: {e}")
|
||||
return False
|
||||
|
||||
def _handle_final_dialogs(self) -> bool:
|
||||
"""
|
||||
Behandelt finale Dialogs/Layer nach Cookie-Consent.
|
||||
Z.B. "Schließen"-Button.
|
||||
|
||||
Returns:
|
||||
bool: True wenn Dialog behandelt wurde
|
||||
"""
|
||||
try:
|
||||
self.automation.human_behavior.random_delay(0.5, 1.0)
|
||||
|
||||
close_button_selectors = [
|
||||
"button:has-text('Schließen')",
|
||||
"button:has-text('Close')",
|
||||
self.selectors.DIALOG_CLOSE_BUTTON, # div[aria-label='Schließen']
|
||||
self.selectors.DIALOG_CLOSE_BUTTON_EN, # div[aria-label='Close']
|
||||
"div[role='button']:has-text('Schließen')",
|
||||
"div[role='button']:has-text('Close')",
|
||||
"a[role='button']:has-text('Schließen')",
|
||||
"a[role='button']:has-text('Close')"
|
||||
]
|
||||
|
||||
for selector in close_button_selectors:
|
||||
try:
|
||||
if self.automation.browser.is_element_visible(selector, timeout=2000):
|
||||
if self.automation.browser.click_element(selector, timeout=1000):
|
||||
logger.info(f"Finaler Dialog geschlossen mit: {selector}")
|
||||
self.automation._send_log_update("Schließe Dialog...")
|
||||
# Kurze Pause nach Schließen
|
||||
self.automation.human_behavior.random_delay(0.5, 1.0)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug(f"Fehler beim Schließen-Button mit {selector}: {e}")
|
||||
continue
|
||||
|
||||
logger.debug("Kein finaler Dialog gefunden")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Behandeln finaler Dialogs: {e}")
|
||||
return False
|
||||
|
||||
def _generate_username_from_email(self, email: str, first_name: str = "", last_name: str = "") -> str:
|
||||
"""
|
||||
Generiert einen Username aus der E-Mail-Adresse.
|
||||
Facebook gibt keinen Username während der Registrierung zurück.
|
||||
Mit Fallback-Strategien falls E-Mail ungültig ist.
|
||||
|
||||
Args:
|
||||
email: E-Mail-Adresse
|
||||
first_name: Vorname als Fallback
|
||||
last_name: Nachname als Fallback
|
||||
|
||||
Returns:
|
||||
str: Generierter Username (GARANTIERT nicht leer!)
|
||||
"""
|
||||
try:
|
||||
# Strategie 1: Aus E-Mail generieren
|
||||
if email and "@" in email:
|
||||
# Extrahiere Teil vor @
|
||||
username_part = email.split("@")[0]
|
||||
|
||||
# Ersetze Punkte durch Underscores
|
||||
username = username_part.replace(".", "_")
|
||||
|
||||
# Stelle sicher, dass es gültige Zeichen sind
|
||||
import re
|
||||
username = re.sub(r'[^a-zA-Z0-9_]', '_', username)
|
||||
|
||||
if username and len(username) >= 3: # Mindestens 3 Zeichen
|
||||
logger.debug(f"Username aus E-Mail generiert: {email} -> {username}")
|
||||
return username
|
||||
|
||||
# Strategie 2: Aus Vor- und Nachnamen generieren
|
||||
if first_name and last_name:
|
||||
import re
|
||||
clean_first = re.sub(r'[^a-zA-Z0-9]', '', first_name.lower())
|
||||
clean_last = re.sub(r'[^a-zA-Z0-9]', '', last_name.lower())
|
||||
|
||||
if clean_first and clean_last:
|
||||
import random
|
||||
username = f"{clean_first}_{clean_last}_{random.randint(100, 999)}"
|
||||
logger.info(f"Username aus Namen generiert (Fallback): {username}")
|
||||
return username
|
||||
|
||||
# Strategie 3: Timestamp-basierter Name (letzter Fallback)
|
||||
import time
|
||||
import random
|
||||
timestamp = int(time.time() * 1000) % 1000000 # Letzte 6 Stellen
|
||||
random_suffix = random.randint(100, 999)
|
||||
username = f"fb_user_{timestamp}_{random_suffix}"
|
||||
logger.warning(f"Username mit Timestamp generiert (Notfall-Fallback): {username}")
|
||||
return username
|
||||
|
||||
except Exception as e:
|
||||
# ABSOLUTER NOTFALL: Garantiere IMMER einen Username
|
||||
import time
|
||||
import random
|
||||
timestamp = int(time.time() * 1000) % 1000000
|
||||
random_suffix = random.randint(100, 999)
|
||||
emergency_username = f"fb_emergency_{timestamp}_{random_suffix}"
|
||||
logger.error(f"Fehler beim Generieren des Usernames: {e}")
|
||||
logger.error(f"Notfall-Username generiert: {emergency_username}")
|
||||
return emergency_username
|
||||
|
||||
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}")
|
||||
|
||||
|
||||
# WICHTIG: Prüfe ZUERST auf Zwischen-Schritte die KEINE Erfolgs-Indikatoren sind
|
||||
intermediate_patterns = [
|
||||
"privacy/consent",
|
||||
"user_cookie_choice",
|
||||
"confirmemail"
|
||||
]
|
||||
|
||||
for pattern in intermediate_patterns:
|
||||
if pattern in current_url:
|
||||
logger.info(f"Zwischen-Schritt erkannt (noch nicht fertig): {pattern}")
|
||||
return False # Noch nicht erfolgreich, weitere Schritte nötig
|
||||
|
||||
# Erfolgs-URLs
|
||||
success_patterns = [
|
||||
"facebook.com/?",
|
||||
@ -847,12 +1032,12 @@ class FacebookRegistration:
|
||||
"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):
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren