662 lines
25 KiB
Python
Executable File
662 lines
25 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Comprehensive DOM Verification Script
|
|
|
|
Systematically verifies ALL data-testid attributes by:
|
|
1. Logging in
|
|
2. Navigating through each tab of profile editor
|
|
3. Waiting for elements to load
|
|
4. Scrolling to make elements visible
|
|
5. Checking all attributes in each step
|
|
6. Reporting detailed findings
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
import json
|
|
import time
|
|
|
|
project_root = Path(__file__).parent.parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
from pages.login_page import LoginPage
|
|
from pages.mandatory_reset_page import MandatoryResetPage
|
|
from pages.profile_incomplete_page import ProfileIncompletePage
|
|
from pages.profile_editor_page import ProfileEditorPage
|
|
from utils.driver_manager import DriverManager
|
|
from config.config import TEST_NEW_PASSWORD, BASE_URL
|
|
|
|
|
|
def get_all_data_testids(driver, scroll_into_view=True):
|
|
"""Get all data-testid attributes from DOM, optionally scrolling elements into view"""
|
|
elements = driver.find_elements(By.CSS_SELECTOR, "[data-testid]")
|
|
testids = {}
|
|
|
|
for elem in elements:
|
|
try:
|
|
testid = elem.get_attribute("data-testid")
|
|
if testid:
|
|
# Scroll into view if requested
|
|
if scroll_into_view:
|
|
try:
|
|
driver.execute_script("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", elem)
|
|
time.sleep(0.1) # Brief wait for scroll
|
|
except:
|
|
pass
|
|
|
|
testids[testid] = {
|
|
"tag": elem.tag_name,
|
|
"type": elem.get_attribute("type") or elem.tag_name,
|
|
"visible": elem.is_displayed(),
|
|
"enabled": elem.is_enabled() if hasattr(elem, 'is_enabled') else True,
|
|
"text": elem.text[:50] if elem.text else "",
|
|
"value": elem.get_attribute("value")[:50] if elem.get_attribute("value") else ""
|
|
}
|
|
except Exception as e:
|
|
# Element might have been removed from DOM
|
|
continue
|
|
|
|
return testids
|
|
|
|
|
|
def wait_for_tab_to_load(driver, tab_name, timeout=10):
|
|
"""Wait for a specific tab to be fully loaded"""
|
|
try:
|
|
# Wait for tab to be active/visible
|
|
tab_locator = (By.CSS_SELECTOR, f"[data-testid='profile_editor__tab_{tab_name}']")
|
|
WebDriverWait(driver, timeout).until(
|
|
EC.presence_of_element_located(tab_locator)
|
|
)
|
|
|
|
# Wait a bit more for content to render
|
|
time.sleep(1)
|
|
|
|
# Scroll to top of form
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(0.5)
|
|
|
|
return True
|
|
except Exception as e:
|
|
print(f"⚠️ Warning: Could not verify tab {tab_name} loaded: {e}")
|
|
return False
|
|
|
|
|
|
def navigate_to_tab_and_check(driver, tab_index, tab_name, expected_attributes):
|
|
"""Navigate to a specific tab and check for expected attributes"""
|
|
print(f"\n{'='*80}")
|
|
print(f"TAB {tab_index + 1}: {tab_name.upper().replace('_', ' ')}")
|
|
print(f"{'='*80}")
|
|
|
|
try:
|
|
# Navigate to tab
|
|
profile_editor = ProfileEditorPage(driver)
|
|
profile_editor.navigate_to_tab(tab_index)
|
|
time.sleep(2) # Wait for tab content to load
|
|
|
|
# Scroll through the tab to trigger lazy loading
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(0.5)
|
|
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
time.sleep(1)
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(0.5)
|
|
|
|
# Get all testids in this tab
|
|
all_testids = get_all_data_testids(driver, scroll_into_view=True)
|
|
|
|
# Filter for profile_editor testids
|
|
profile_testids = {tid: info for tid, info in all_testids.items() if tid.startswith("profile_editor__")}
|
|
|
|
print(f"📋 Found {len(profile_testids)} profile_editor attributes in this tab")
|
|
|
|
# Check expected attributes
|
|
found = []
|
|
missing = []
|
|
|
|
for attr in expected_attributes:
|
|
if attr in profile_testids:
|
|
info = profile_testids[attr]
|
|
status = "✅" if info["visible"] else "⚠️ (hidden)"
|
|
print(f"{status} {attr}")
|
|
found.append(attr)
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
missing.append(attr)
|
|
|
|
# Check for unexpected attributes
|
|
unexpected = [tid for tid in profile_testids if tid not in expected_attributes]
|
|
if unexpected:
|
|
print(f"\n⚠️ UNEXPECTED attributes found ({len(unexpected)}):")
|
|
for tid in sorted(unexpected)[:10]:
|
|
print(f" - {tid}")
|
|
if len(unexpected) > 10:
|
|
print(f" ... and {len(unexpected) - 10} more")
|
|
|
|
return {
|
|
"tab_name": tab_name,
|
|
"found": found,
|
|
"missing": missing,
|
|
"unexpected": unexpected,
|
|
"all_testids": list(profile_testids.keys())
|
|
}
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error checking tab {tab_name}: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return {
|
|
"tab_name": tab_name,
|
|
"found": [],
|
|
"missing": expected_attributes,
|
|
"unexpected": [],
|
|
"all_testids": [],
|
|
"error": str(e)
|
|
}
|
|
|
|
|
|
def check_dynamic_checkboxes(driver, pattern_prefix, expected_count=None):
|
|
"""Check for dynamic checkboxes matching a pattern"""
|
|
try:
|
|
# Scroll through page to load all checkboxes
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(0.3)
|
|
|
|
# Find all checkboxes with matching pattern
|
|
checkboxes = driver.find_elements(
|
|
By.CSS_SELECTOR,
|
|
f"input[type='checkbox'][data-testid^='{pattern_prefix}']"
|
|
)
|
|
|
|
found_testids = []
|
|
for cb in checkboxes:
|
|
try:
|
|
# Scroll checkbox into view
|
|
driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", cb)
|
|
time.sleep(0.1)
|
|
|
|
testid = cb.get_attribute("data-testid")
|
|
if testid and testid.startswith(pattern_prefix):
|
|
found_testids.append(testid)
|
|
except:
|
|
continue
|
|
|
|
# Also try finding by CSS selector with wildcard
|
|
all_elements = driver.find_elements(By.CSS_SELECTOR, "[data-testid]")
|
|
for elem in all_elements:
|
|
testid = elem.get_attribute("data-testid")
|
|
if testid and testid.startswith(pattern_prefix) and testid not in found_testids:
|
|
found_testids.append(testid)
|
|
|
|
found_count = len(found_testids)
|
|
status = "✅" if found_count > 0 else "❌"
|
|
|
|
if expected_count:
|
|
status = "✅" if found_count >= expected_count else "⚠️"
|
|
print(f"{status} {pattern_prefix}: {found_count}/{expected_count} found")
|
|
else:
|
|
print(f"{status} {pattern_prefix}: {found_count} found")
|
|
|
|
if found_testids:
|
|
for tid in sorted(found_testids)[:5]:
|
|
print(f" - {tid}")
|
|
if len(found_testids) > 5:
|
|
print(f" ... and {len(found_testids) - 5} more")
|
|
|
|
return found_testids
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error checking {pattern_prefix}: {e}")
|
|
return []
|
|
|
|
|
|
def main():
|
|
driver = None
|
|
try:
|
|
print("🚀 COMPREHENSIVE DOM VERIFICATION")
|
|
print("="*80)
|
|
print(f"🌐 Environment: {BASE_URL}")
|
|
print(f"🔑 Credentials: BATBAT311A")
|
|
print("="*80)
|
|
|
|
# Initialize driver
|
|
driver_manager = DriverManager()
|
|
driver = driver_manager.get_driver(headless=False)
|
|
driver.maximize_window()
|
|
|
|
results = {
|
|
"login": {},
|
|
"dashboard": {},
|
|
"student_nav": {},
|
|
"password_reset": {},
|
|
"profile_editor": {
|
|
"tabs": {},
|
|
"dynamic_checkboxes": {},
|
|
"summary": {}
|
|
}
|
|
}
|
|
|
|
# ============================================================
|
|
# STEP 1: LOGIN
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("STEP 1: LOGIN")
|
|
print("="*80)
|
|
|
|
login_page = LoginPage(driver)
|
|
login_page.login(identifier="BATBAT311A", password="17k*o@yReCUA")
|
|
time.sleep(3)
|
|
|
|
# Check login page attributes (if still on login)
|
|
if "/login" in driver.current_url or driver.current_url.rstrip("/") == BASE_URL.rstrip("/"):
|
|
login_testids = get_all_data_testids(driver)
|
|
login_expected = [
|
|
"student_login__form",
|
|
"student_login__identifier_input",
|
|
"student_login__password_input",
|
|
"student_login__remember_checkbox",
|
|
"student_login__error_banner",
|
|
"student_login__submit_button"
|
|
]
|
|
|
|
found = [tid for tid in login_expected if tid in login_testids]
|
|
print(f"📊 Login Page: {len(found)}/{len(login_expected)} found")
|
|
results["login"] = {"found": found, "missing": [tid for tid in login_expected if tid not in found]}
|
|
else:
|
|
print("✅ Login successful - redirected to dashboard")
|
|
results["login"] = {"status": "success"}
|
|
|
|
# ============================================================
|
|
# STEP 2: PASSWORD RESET (if needed)
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("STEP 2: PASSWORD RESET CHECK")
|
|
print("="*80)
|
|
|
|
reset_page = MandatoryResetPage(driver)
|
|
if reset_page.is_modal_present():
|
|
print("🔄 Password reset modal present - resetting...")
|
|
reset_page.reset_password("17k*o@yReCUA", TEST_NEW_PASSWORD, TEST_NEW_PASSWORD, "BATBAT311A")
|
|
time.sleep(3)
|
|
results["password_reset"] = {"status": "completed"}
|
|
else:
|
|
print("✅ No password reset required")
|
|
results["password_reset"] = {"status": "not_required"}
|
|
|
|
# ============================================================
|
|
# STEP 3: NAVIGATE TO PROFILE EDITOR
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("STEP 3: NAVIGATING TO PROFILE EDITOR")
|
|
print("="*80)
|
|
|
|
# Handle profile incomplete modal
|
|
profile_incomplete = ProfileIncompletePage(driver)
|
|
if profile_incomplete.is_modal_present():
|
|
print("⚠️ Profile incomplete modal present - clicking Complete Profile...")
|
|
profile_incomplete.click_complete()
|
|
time.sleep(3)
|
|
else:
|
|
profile_editor = ProfileEditorPage(driver)
|
|
profile_editor.navigate()
|
|
time.sleep(3)
|
|
|
|
# Wait for profile editor to fully load
|
|
profile_editor = ProfileEditorPage(driver)
|
|
profile_editor.wait_for_page_load()
|
|
time.sleep(2)
|
|
|
|
# ============================================================
|
|
# STEP 4: CHECK PAGE-LEVEL ATTRIBUTES
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("STEP 4: PAGE-LEVEL ATTRIBUTES")
|
|
print("="*80)
|
|
|
|
all_testids = get_all_data_testids(driver)
|
|
page_level_expected = [
|
|
"profile_editor__page",
|
|
"profile_editor__progress_value",
|
|
"profile_editor__missing_fields_toggle",
|
|
"profile_editor__prev_button",
|
|
"profile_editor__next_button",
|
|
"profile_editor__cancel_button",
|
|
"profile_editor__save_button"
|
|
]
|
|
|
|
page_level_found = []
|
|
for attr in page_level_expected:
|
|
if attr in all_testids:
|
|
print(f"✅ {attr}")
|
|
page_level_found.append(attr)
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
print(f"\n📊 Page-Level: {len(page_level_found)}/{len(page_level_expected)} found")
|
|
|
|
# ============================================================
|
|
# STEP 5: CHECK TAB NAVIGATION
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("STEP 5: TAB NAVIGATION")
|
|
print("="*80)
|
|
|
|
tab_expected = [
|
|
"profile_editor__tab_personal_information",
|
|
"profile_editor__tab_contact_information",
|
|
"profile_editor__tab_parent_guardian",
|
|
"profile_editor__tab_education_details",
|
|
"profile_editor__tab_focus_areas",
|
|
"profile_editor__tab_self_assessment",
|
|
"profile_editor__tab_hobbies_clubs",
|
|
"profile_editor__tab_achievements",
|
|
"profile_editor__tab_expectations",
|
|
"profile_editor__tabs_scroll_left_button",
|
|
"profile_editor__tabs_scroll_right_button"
|
|
]
|
|
|
|
tab_found = []
|
|
for attr in tab_expected:
|
|
if attr in all_testids:
|
|
print(f"✅ {attr}")
|
|
tab_found.append(attr)
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
print(f"\n📊 Tab Navigation: {len(tab_found)}/{len(tab_expected)} found")
|
|
|
|
# ============================================================
|
|
# STEP 6: SYSTEMATICALLY CHECK EACH TAB
|
|
# ============================================================
|
|
|
|
# Tab 0: Personal Information
|
|
tab0_result = navigate_to_tab_and_check(driver, 0, "personal_information", [
|
|
"profile_editor__first_name_input",
|
|
"profile_editor__last_name_input",
|
|
"profile_editor__gender_select",
|
|
"profile_editor__dob_input",
|
|
"profile_editor__roll_number_input",
|
|
"profile_editor__nationality_input",
|
|
"profile_editor__language_input",
|
|
"profile_editor__student_id_input",
|
|
"profile_editor__student_cpid_input",
|
|
"profile_editor__specially_abled_checkbox",
|
|
"profile_editor__specially_abled_details_textarea"
|
|
])
|
|
results["profile_editor"]["tabs"]["personal_information"] = tab0_result
|
|
|
|
# Tab 1: Contact Information
|
|
tab1_result = navigate_to_tab_and_check(driver, 1, "contact_information", [
|
|
"profile_editor__email_input",
|
|
"profile_editor__phone_input",
|
|
"profile_editor__address_input",
|
|
"profile_editor__city_input",
|
|
"profile_editor__state_input",
|
|
"profile_editor__zip_code_input",
|
|
"profile_editor__native_state_input"
|
|
])
|
|
results["profile_editor"]["tabs"]["contact_information"] = tab1_result
|
|
|
|
# Tab 2: Parent/Guardian
|
|
tab2_result = navigate_to_tab_and_check(driver, 2, "parent_guardian", [
|
|
"profile_editor__father_full_name_input",
|
|
"profile_editor__father_age_range_select",
|
|
"profile_editor__father_occupation_input",
|
|
"profile_editor__father_email_input",
|
|
"profile_editor__mother_full_name_input",
|
|
"profile_editor__mother_age_range_select",
|
|
"profile_editor__mother_occupation_input",
|
|
"profile_editor__mother_email_input",
|
|
"profile_editor__guardian_different_checkbox",
|
|
"profile_editor__guardian_full_name_input",
|
|
"profile_editor__guardian_relationship_input",
|
|
"profile_editor__guardian_phone_input",
|
|
"profile_editor__guardian_email_input",
|
|
"profile_editor__guardian_address_input"
|
|
])
|
|
results["profile_editor"]["tabs"]["parent_guardian"] = tab2_result
|
|
|
|
# Tab 3: Education Details
|
|
tab3_result = navigate_to_tab_and_check(driver, 3, "education_details", [
|
|
"profile_editor__full_name_input",
|
|
"profile_editor__current_grade_input",
|
|
"profile_editor__section_input",
|
|
"profile_editor__board_stream_select"
|
|
])
|
|
results["profile_editor"]["tabs"]["education_details"] = tab3_result
|
|
|
|
# Tab 4: Focus Areas (with dynamic checkboxes)
|
|
print("\n" + "="*80)
|
|
print("TAB 5: FOCUS AREAS")
|
|
print("="*80)
|
|
profile_editor.navigate_to_tab(4)
|
|
time.sleep(2)
|
|
|
|
# Scroll to load all checkboxes
|
|
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
time.sleep(1)
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(1)
|
|
|
|
# Check dynamic checkboxes
|
|
print("\n🔍 Checking Short-term Focus Areas...")
|
|
short_term = check_dynamic_checkboxes(driver, "profile_editor__short_term_focus__", expected_count=11)
|
|
|
|
print("\n🔍 Checking Long-term Focus Areas...")
|
|
long_term = check_dynamic_checkboxes(driver, "profile_editor__long_term_focus__", expected_count=11)
|
|
|
|
# Check "Others" text inputs
|
|
others_expected = [
|
|
"profile_editor__short_term_focus_others_text",
|
|
"profile_editor__long_term_focus_others_text"
|
|
]
|
|
all_testids_tab4 = get_all_data_testids(driver)
|
|
for attr in others_expected:
|
|
if attr in all_testids_tab4:
|
|
print(f"✅ {attr}")
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
results["profile_editor"]["tabs"]["focus_areas"] = {
|
|
"short_term_focus": short_term,
|
|
"long_term_focus": long_term,
|
|
"others_text": [tid for tid in others_expected if tid in all_testids_tab4]
|
|
}
|
|
|
|
# Tab 5: Self-Assessment (with dynamic checkboxes)
|
|
print("\n" + "="*80)
|
|
print("TAB 6: SELF-ASSESSMENT")
|
|
print("="*80)
|
|
profile_editor.navigate_to_tab(5)
|
|
time.sleep(2)
|
|
|
|
# Scroll to load all checkboxes
|
|
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
time.sleep(1)
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(1)
|
|
|
|
print("\n🔍 Checking Strengths...")
|
|
strengths = check_dynamic_checkboxes(driver, "profile_editor__strength__", expected_count=19)
|
|
|
|
print("\n🔍 Checking Areas of Improvement...")
|
|
improvements = check_dynamic_checkboxes(driver, "profile_editor__improvement__", expected_count=19)
|
|
|
|
# Check "Others" text inputs
|
|
others_expected = [
|
|
"profile_editor__strength_others_text",
|
|
"profile_editor__improvement_others_text"
|
|
]
|
|
all_testids_tab5 = get_all_data_testids(driver)
|
|
for attr in others_expected:
|
|
if attr in all_testids_tab5:
|
|
print(f"✅ {attr}")
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
results["profile_editor"]["tabs"]["self_assessment"] = {
|
|
"strengths": strengths,
|
|
"improvements": improvements,
|
|
"others_text": [tid for tid in others_expected if tid in all_testids_tab5]
|
|
}
|
|
|
|
# Tab 6: Hobbies & Clubs (with dynamic checkboxes)
|
|
print("\n" + "="*80)
|
|
print("TAB 7: HOBBIES & CLUBS")
|
|
print("="*80)
|
|
profile_editor.navigate_to_tab(6)
|
|
time.sleep(2)
|
|
|
|
# Scroll to load all checkboxes
|
|
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
time.sleep(1)
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(1)
|
|
|
|
print("\n🔍 Checking Hobbies...")
|
|
hobbies = check_dynamic_checkboxes(driver, "profile_editor__hobby__", expected_count=12)
|
|
|
|
print("\n🔍 Checking Clubs...")
|
|
clubs = check_dynamic_checkboxes(driver, "profile_editor__club_", expected_count=12) # Single underscore
|
|
|
|
# Check "Others" text inputs
|
|
others_expected = [
|
|
"profile_editor__hobby_other_text",
|
|
"profile_editor__club_other_text"
|
|
]
|
|
all_testids_tab6 = get_all_data_testids(driver)
|
|
for attr in others_expected:
|
|
if attr in all_testids_tab6:
|
|
print(f"✅ {attr}")
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
results["profile_editor"]["tabs"]["hobbies_clubs"] = {
|
|
"hobbies": hobbies,
|
|
"clubs": clubs,
|
|
"others_text": [tid for tid in others_expected if tid in all_testids_tab6]
|
|
}
|
|
|
|
# Tab 7: Achievements
|
|
tab7_result = navigate_to_tab_and_check(driver, 7, "achievements", [
|
|
"profile_editor__achievement_academics_textarea",
|
|
"profile_editor__achievement_sports_textarea",
|
|
"profile_editor__achievement_cultural_textarea",
|
|
"profile_editor__achievement_trained_textarea",
|
|
"profile_editor__achievement_others_textarea"
|
|
])
|
|
results["profile_editor"]["tabs"]["achievements"] = tab7_result
|
|
|
|
# Tab 8: Expectations (with dynamic checkboxes)
|
|
print("\n" + "="*80)
|
|
print("TAB 9: EXPECTATIONS")
|
|
print("="*80)
|
|
profile_editor.navigate_to_tab(8)
|
|
time.sleep(2)
|
|
|
|
# Scroll to load all checkboxes
|
|
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
time.sleep(1)
|
|
driver.execute_script("window.scrollTo(0, 0);")
|
|
time.sleep(1)
|
|
|
|
print("\n🔍 Checking Expectations...")
|
|
expectations = check_dynamic_checkboxes(driver, "profile_editor__expectation__", expected_count=10)
|
|
|
|
# Check "Others" text input
|
|
others_expected = ["profile_editor__expectation_others_text"]
|
|
all_testids_tab8 = get_all_data_testids(driver)
|
|
for attr in others_expected:
|
|
if attr in all_testids_tab8:
|
|
print(f"✅ {attr}")
|
|
else:
|
|
print(f"❌ MISSING: {attr}")
|
|
|
|
results["profile_editor"]["tabs"]["expectations"] = {
|
|
"expectations": expectations,
|
|
"others_text": [tid for tid in others_expected if tid in all_testids_tab8]
|
|
}
|
|
|
|
# ============================================================
|
|
# FINAL SUMMARY
|
|
# ============================================================
|
|
print("\n" + "="*80)
|
|
print("FINAL VERIFICATION SUMMARY")
|
|
print("="*80)
|
|
|
|
# Count all found attributes
|
|
total_found = 0
|
|
total_expected = 0
|
|
|
|
# Page-level
|
|
total_found += len(page_level_found)
|
|
total_expected += len(page_level_expected)
|
|
|
|
# Tab navigation
|
|
total_found += len(tab_found)
|
|
total_expected += len(tab_expected)
|
|
|
|
# Tab-specific attributes
|
|
for tab_name, tab_result in results["profile_editor"]["tabs"].items():
|
|
if "found" in tab_result:
|
|
total_found += len(tab_result["found"])
|
|
total_expected += len(tab_result.get("missing", [])) + len(tab_result["found"])
|
|
if "short_term_focus" in tab_result:
|
|
total_found += len(tab_result["short_term_focus"])
|
|
if "long_term_focus" in tab_result:
|
|
total_found += len(tab_result["long_term_focus"])
|
|
if "strengths" in tab_result:
|
|
total_found += len(tab_result["strengths"])
|
|
if "improvements" in tab_result:
|
|
total_found += len(tab_result["improvements"])
|
|
if "hobbies" in tab_result:
|
|
total_found += len(tab_result["hobbies"])
|
|
if "clubs" in tab_result:
|
|
total_found += len(tab_result["clubs"])
|
|
if "expectations" in tab_result:
|
|
total_found += len(tab_result["expectations"])
|
|
|
|
print(f"\n📊 TOTAL ATTRIBUTES FOUND: {total_found}")
|
|
print(f"📊 TOTAL ATTRIBUTES EXPECTED: ~250+")
|
|
print(f"📊 COVERAGE: {(total_found/250)*100:.1f}%")
|
|
|
|
# Save results
|
|
results["profile_editor"]["summary"] = {
|
|
"total_found": total_found,
|
|
"total_expected": total_expected,
|
|
"page_level_found": len(page_level_found),
|
|
"tab_navigation_found": len(tab_found)
|
|
}
|
|
|
|
results_file = project_root / "analysis" / "comprehensive_dom_verification_results.json"
|
|
with open(results_file, 'w') as f:
|
|
json.dump(results, f, indent=2, default=str)
|
|
|
|
print(f"\n📄 Detailed results saved to: {results_file}")
|
|
print("\n⏸️ Browser will remain open for 120 seconds for manual inspection...")
|
|
print(" Press Ctrl+C to close early\n")
|
|
time.sleep(120)
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n\n⚠️ Verification interrupted by user")
|
|
except Exception as e:
|
|
print(f"\n\n❌ Error during verification: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
finally:
|
|
if driver:
|
|
driver.quit()
|
|
print("\n✅ Browser closed")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|