CP_AUTOMATION/pages/age_verification_modal.py
2025-12-12 19:54:54 +05:30

278 lines
12 KiB
Python

"""
Age Verification Modal Page Object Model
Handles the age verification modal that appears when DOB doesn't match school records.
Scope: age_verification
"""
from selenium.webdriver.common.by import By
from pages.base_page import BasePage
class AgeVerificationModal(BasePage):
"""Page Object for Age Verification Modal"""
# Locators - Need to verify with actual DOM
MODAL = (By.CSS_SELECTOR, "[data-testid='age_verification__modal']")
TITLE = (By.CSS_SELECTOR, "[data-testid='age_verification__title']")
WARNING_BANNER = (By.CSS_SELECTOR, "[data-testid='age_verification__warning_banner']")
VERIFIED_AGE = (By.CSS_SELECTOR, "[data-testid='age_verification__verified_age']")
NEW_AGE = (By.CSS_SELECTOR, "[data-testid='age_verification__new_age']")
DIFFERENCE = (By.CSS_SELECTOR, "[data-testid='age_verification__difference']")
CONFIRM_CHECKBOX = (By.CSS_SELECTOR, "[data-testid='age_verification__confirm_checkbox']")
CANCEL_BUTTON = (By.CSS_SELECTOR, "[data-testid='age_verification__cancel_button']")
CONFIRM_BUTTON = (By.CSS_SELECTOR, "[data-testid='age_verification__confirm_button']")
CLOSE_BUTTON = (By.CSS_SELECTOR, "[data-testid='age_verification__close_button']")
def __init__(self, driver):
"""Initialize Age Verification Modal"""
super().__init__(driver)
def is_modal_present(self):
"""
Check if age verification modal is present.
Uses multiple detection strategies:
1. Check for modal by data-testid
2. Check for modal by title text "Age Verification Required"
3. Check for modal overlay structure
"""
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from config.config import SHORT_WAIT
# Strategy 1: Check by data-testid
try:
if self.is_element_visible(self.MODAL, timeout=2):
return True
except:
pass
# Strategy 2: Check for title text
try:
title_elements = self.driver.find_elements(By.XPATH,
"//*[contains(text(), 'Age Verification Required') or contains(text(), 'Age Verification')]")
if title_elements:
# Check if it's in a modal structure
for element in title_elements:
# Check if parent is a modal (has overlay or modal classes)
parent = self.driver.execute_script("return arguments[0].closest('[class*=\"modal\"], [class*=\"overlay\"], [role=\"dialog\"]');", element)
if parent:
return True
except:
pass
# Strategy 3: Check page source for age verification text
try:
page_text = self.driver.page_source.lower()
if "age verification required" in page_text or "date of birth verification" in page_text:
# Check if modal overlay is visible
overlays = self.driver.find_elements(By.CSS_SELECTOR,
"div[class*='fixed'][class*='inset-0'][class*='bg-black']")
for overlay in overlays:
if overlay.is_displayed():
return True
except:
pass
return False
def get_verified_age(self):
"""Get verified age from school records"""
try:
# Try to find verified age text
elements = self.driver.find_elements(By.XPATH,
"//*[contains(text(), 'Verified Age') or contains(text(), 'from school')]")
for element in elements:
text = element.text
# Extract age number
import re
numbers = re.findall(r'\d+', text)
if numbers:
return int(numbers[0])
except:
pass
return None
def get_new_age(self):
"""Get new age from entered DOB"""
try:
# Try to find new age text
elements = self.driver.find_elements(By.XPATH,
"//*[contains(text(), 'New Age') or contains(text(), 'from your DOB')]")
for element in elements:
text = element.text
# Extract age number
import re
numbers = re.findall(r'\d+', text)
if numbers:
return int(numbers[1]) if len(numbers) > 1 else int(numbers[0])
except:
pass
return None
def confirm_age(self):
"""
Confirm age verification by checking checkbox and clicking OK.
This handles the age verification modal that appears when DOB doesn't match.
"""
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from config.config import SHORT_WAIT
if not self.is_modal_present():
print("✅ Age verification modal not present - no action needed")
return True
print("🔍 Age verification modal detected - handling...")
# Wait for modal to be fully visible
time.sleep(1)
# Strategy 1: Try to find confirm checkbox by ID (most reliable)
# The checkbox has id="age-confirmation-checkbox" in the UI code
checkbox_found = False
try:
checkbox = WebDriverWait(self.driver, SHORT_WAIT).until(
EC.presence_of_element_located((By.ID, "age-confirmation-checkbox"))
)
if not checkbox.is_selected():
# Scroll into view
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", checkbox)
time.sleep(0.3)
# Try regular click first
try:
checkbox.click()
print("✅ Age confirmation checkbox checked (by ID)")
checkbox_found = True
except:
# Fallback to JavaScript click
self.driver.execute_script("arguments[0].click();", checkbox)
print("✅ Age confirmation checkbox checked (by ID, JavaScript click)")
checkbox_found = True
except Exception as e:
print(f"⚠️ Could not find checkbox by ID: {e}")
# Strategy 2: Try to find by label text if ID failed
if not checkbox_found:
try:
# Find checkbox with label containing "I confirm that the date of birth"
checkbox_xpath = (
"//label[contains(text(), 'I confirm that the date of birth')]//input[@type='checkbox'] | "
"//input[@type='checkbox'][following-sibling::label[contains(text(), 'I confirm that the date of birth')]]"
)
checkbox = WebDriverWait(self.driver, SHORT_WAIT).until(
EC.presence_of_element_located((By.XPATH, checkbox_xpath))
)
if not checkbox.is_selected():
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", checkbox)
time.sleep(0.3)
self.driver.execute_script("arguments[0].click();", checkbox)
print("✅ Age confirmation checkbox checked (by label text)")
checkbox_found = True
except Exception as e:
print(f"⚠️ Could not find checkbox by label: {e}")
# Strategy 3: Find any checkbox in modal (fallback)
if not checkbox_found:
try:
# Find modal container first
modal = self.driver.find_element(By.XPATH,
"//*[contains(text(), 'Age Verification Required')]/ancestor::div[contains(@class, 'bg-white') or contains(@class, 'rounded-2xl')]")
checkbox = modal.find_element(By.XPATH, ".//input[@type='checkbox']")
if not checkbox.is_selected():
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", checkbox)
time.sleep(0.3)
self.driver.execute_script("arguments[0].click();", checkbox)
print("✅ Age confirmation checkbox checked (fallback)")
checkbox_found = True
except Exception as e:
print(f"⚠️ Could not find checkbox in modal: {e}")
if not checkbox_found:
print("⚠️ Warning: Could not find/check confirmation checkbox - button may be disabled")
# Click OK/Confirm button
# The button text is "OK - Confirm Update"
try:
# Find button with text "OK", "Confirm", or "OK - Confirm Update"
confirm_button_xpath = (
"//button[contains(text(), 'OK - Confirm Update')] | "
"//button[contains(text(), 'OK') and contains(text(), 'Confirm')] | "
"//button[contains(text(), 'Confirm Update')]"
)
confirm_button = WebDriverWait(self.driver, SHORT_WAIT).until(
EC.element_to_be_clickable((By.XPATH, confirm_button_xpath))
)
# Scroll into view
self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", confirm_button)
time.sleep(0.3)
# Try regular click first
try:
confirm_button.click()
print("✅ Age verification confirmed - clicked OK button")
except:
# Fallback to JavaScript click
self.driver.execute_script("arguments[0].click();", confirm_button)
print("✅ Age verification confirmed (JavaScript click)")
except Exception as e:
print(f"⚠️ Could not find confirm button by text: {e}")
# Try alternative: find by data-testid
try:
confirm_button = self.wait.wait_for_element_clickable(self.CONFIRM_BUTTON, timeout=2)
confirm_button.click()
print("✅ Age verification confirmed (by data-testid)")
except:
# Try JavaScript click on any button in modal
try:
# Find modal container first
modal = self.driver.find_element(By.XPATH,
"//*[contains(text(), 'Age Verification Required')]/ancestor::div[contains(@class, 'bg-white') or contains(@class, 'modal')]")
buttons = modal.find_elements(By.XPATH, ".//button[contains(text(), 'OK') or contains(text(), 'Confirm')]")
for button in buttons:
if button.is_displayed() and "Cancel" not in button.text:
self.driver.execute_script("arguments[0].click();", button)
print("✅ Age verification confirmed (fallback JavaScript click)")
break
except Exception as e2:
print(f"⚠️ Could not click confirm button: {e2}")
raise Exception(f"Failed to confirm age verification: {e}, {e2}")
# Wait for modal to close
time.sleep(2)
# Verify modal is closed
if not self.is_modal_present():
print("✅ Age verification modal closed successfully")
return True
else:
print("⚠️ Age verification modal still present after confirmation")
return False
def cancel_age_verification(self):
"""Cancel age verification (closes modal without confirming)"""
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from config.config import SHORT_WAIT
if not self.is_modal_present():
return True
try:
# Find Cancel button
cancel_button = WebDriverWait(self.driver, SHORT_WAIT).until(
EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Cancel')]"))
)
cancel_button.click()
time.sleep(1)
print("✅ Age verification cancelled")
return True
except:
return False