178 Zeilen
6.3 KiB
Python
178 Zeilen
6.3 KiB
Python
# 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(), {}) |