Dieser Commit ist enthalten in:
Claude Project Manager
2025-08-01 23:50:28 +02:00
Commit 04585e95b6
290 geänderte Dateien mit 64086 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,178 @@
# social_networks/x/x_selectors.py
"""
X (Twitter) Selektoren - Zentrale Sammlung aller CSS-Selektoren für X
"""
class XSelectors:
"""
Zentrale Klasse für alle X-spezifischen CSS-Selektoren.
Organisiert nach Funktionsbereichen.
"""
# === ALLGEMEINE SELEKTOREN ===
COOKIE_ACCEPT_BUTTONS = [
"button:has-text('Accept all')",
"button:has-text('Alle akzeptieren')",
"button:has-text('Accept')",
"button:has-text('Akzeptieren')"
]
# === REGISTRIERUNG ===
REGISTRATION = {
# Hauptseite
"create_account_button": 'text="Account erstellen"', # Robustester Selektor
"create_account_button_en": 'text="Create account"', # Englische Version
"create_account_button_alt": 'span:has-text("Account erstellen")', # Alternative
"create_account_button_div": 'div[dir="ltr"] >> text="Account erstellen"', # Spezifischer
# Formularfelder
"name_input": 'input[name="name"]',
"email_input": 'input[name="email"]',
"phone_input": 'input[name="phone"]',
# Geburtsdatum Dropdowns
"month_select": 'select#SELECTOR_1',
"day_select": 'select#SELECTOR_2',
"year_select": 'select#SELECTOR_3',
# Buttons
"next_button_birthday": 'button[data-testid="ocfSignupNextLink"]',
"next_button_settings": 'button[data-testid="ocfSettingsListNextButton"]',
"register_button": 'button[data-testid="LoginForm_Login_Button"]',
# Verifizierung
"verification_code_input": 'input[autocomplete="one-time-code"]',
"verification_code_label": 'div:has-text("Verifizierungscode")',
# Passwort
"password_input": 'input[type="password"]',
"password_label": 'div:has-text("Passwort")',
# Skip-Buttons
"skip_profile_picture": 'button[data-testid="ocfSelectAvatarSkipForNowButton"]',
"skip_username": 'button[data-testid="ocfEnterUsernameSkipButton"]',
"skip_notifications": 'button:has-text("Vorerst überspringen")',
"skip_for_now": 'button:has-text("Nicht jetzt")'
}
# === LOGIN ===
LOGIN = {
# Login-Buttons
"login_button": 'a[href="/login"]',
"login_button_alt": 'div:has-text("Anmelden")',
# Formularfelder
"username_input": 'input[autocomplete="username"]',
"email_or_username_input": 'input[name="text"]',
"password_input": 'input[type="password"]',
"password_input_alt": 'input[name="password"]',
# Submit-Buttons
"next_button": 'div[role="button"]:has-text("Weiter")',
"next_button_en": 'div[role="button"]:has-text("Next")',
"login_submit": 'div[role="button"]:has-text("Anmelden")',
"login_submit_en": 'div[role="button"]:has-text("Log in")'
}
# === NAVIGATION ===
NAVIGATION = {
# Hauptnavigation
"home_link": 'a[href="/home"]',
"explore_link": 'a[href="/explore"]',
"notifications_link": 'a[href="/notifications"]',
"messages_link": 'a[href="/messages"]',
"profile_link": 'a[data-testid="AppTabBar_Profile_Link"]',
# Tweet/Post-Buttons
"tweet_button": 'a[data-testid="SideNav_NewTweet_Button"]',
"tweet_button_inline": 'button[data-testid="tweetButtonInline"]',
# Navigation Container
"primary_nav": 'nav[aria-label="Primary"]',
"sidebar": 'div[data-testid="sidebarColumn"]'
}
# === PROFIL ===
PROFILE = {
# Profilbearbeitung
"edit_profile_button": 'button:has-text("Profil bearbeiten")',
"edit_profile_button_en": 'button:has-text("Edit profile")',
# Formularfelder
"display_name_input": 'input[name="displayName"]',
"bio_textarea": 'textarea[name="description"]',
"location_input": 'input[name="location"]',
"website_input": 'input[name="url"]',
# Speichern
"save_button": 'button:has-text("Speichern")',
"save_button_en": 'button:has-text("Save")'
}
# === VERIFIZIERUNG ===
VERIFICATION = {
# Challenge/Captcha
"challenge_frame": 'iframe[title="arkose-challenge"]',
"captcha_frame": 'iframe[src*="recaptcha"]',
# Telefonnummer-Verifizierung
"phone_verification_input": 'input[name="phone_number"]',
"send_code_button": 'button:has-text("Code senden")',
"verification_code_input": 'input[name="verification_code"]'
}
# === FEHLER UND WARNUNGEN ===
ERRORS = {
# Fehlermeldungen
"error_message": 'div[data-testid="toast"]',
"error_alert": 'div[role="alert"]',
"rate_limit_message": 'span:has-text("versuchen Sie es später")',
"suspended_message": 'span:has-text("gesperrt")',
# Spezifische Fehler
"email_taken": 'span:has-text("E-Mail-Adresse wird bereits verwendet")',
"invalid_credentials": 'span:has-text("Falscher Benutzername oder falsches Passwort")'
}
# === MODALE DIALOGE ===
MODALS = {
# Allgemeine Modale
"modal_container": 'div[role="dialog"]',
"modal_close_button": 'div[aria-label="Schließen"]',
"modal_close_button_en": 'div[aria-label="Close"]',
# Bestätigungsdialoge
"confirm_button": 'button:has-text("Bestätigen")',
"cancel_button": 'button:has-text("Abbrechen")'
}
@classmethod
def get_selector(cls, category: str, key: str) -> str:
"""
Holt einen spezifischen Selektor.
Args:
category: Kategorie (z.B. "REGISTRATION", "LOGIN")
key: Schlüssel innerhalb der Kategorie
Returns:
str: CSS-Selektor oder None
"""
category_dict = getattr(cls, category.upper(), {})
if isinstance(category_dict, dict):
return category_dict.get(key)
return None
@classmethod
def get_all_selectors(cls, category: str) -> dict:
"""
Holt alle Selektoren einer Kategorie.
Args:
category: Kategorie
Returns:
dict: Alle Selektoren der Kategorie
"""
return getattr(cls, category.upper(), {})