#!/usr/bin/env python3 """ End-to-End Script: Complete Profile to Assessment Ready State This script performs the complete student journey: 1. Login (with smart password handling) 2. Password Reset (if needed) 3. Profile Completion (to 100%) 4. Navigate to Assessments Page Usage: python scripts/complete_profile_to_assessment.py --cpid --password [--profile-data ] Example: python scripts/complete_profile_to_assessment.py --cpid BATBAT311A --password Admin@123 python scripts/complete_profile_to_assessment.py --cpid DESDES29BB --password Admin@123 --profile-data profile_data.json """ import argparse import json import sys import time from pathlib import Path # Add project root to path project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) 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 pages.dashboard_page import DashboardPage from pages.assessments_page import AssessmentsPage from utils.driver_manager import DriverManager from utils.password_tracker import password_tracker from config.config import TEST_NEW_PASSWORD, BASE_URL def load_profile_data(json_file=None): """ Load profile data from JSON file or return default data Args: json_file: Path to JSON file with profile data (optional) Returns: dict: Profile data dictionary """ default_data = { "personal_information": { "first_name": "Test", "last_name": "Student", "gender": "Male", "dob": "2005-01-15", "roll_number": "12345", "nationality": "Indian" }, "contact_information": { "email": "test.student@example.com", "phone": "9876543210", "address": "123 Test Street, Test Area", "city": "Mumbai", "state": "Maharashtra", "zip_code": "400001", "native_state": "Maharashtra" }, "parent_guardian": { "father_name": "Father Test", "father_age_range": "41-50", "father_occupation": "Engineer", "father_email": "father@example.com", "mother_name": "Mother Test", "mother_age_range": "30-40", "mother_occupation": "Teacher", "mother_email": "mother@example.com" }, "education_details": { "full_name": "Test Student", "current_grade": "10", "section": "A", "board_stream": "CBSE" }, "focus_areas": { "short_term": ["01. Academics", "02. Family", "03. Health"], "long_term": ["01. Academics", "09. Future Aspiration", "06. Personal Growth"] }, "self_assessment": { "strengths": ["1. Quick Learning", "3. Problem-Solving", "12. Communication"], "improvements": ["2. Curiosity", "6. Risk Taking", "10. Leadership"] }, "hobbies_clubs": { "hobbies": ["01. Reading", "03. Sports", "02. Playing Musical Instruments"], "clubs": ["1. Science Club", "3. Quiz Club", "4. Literary Club"] }, "achievements": { "academics": "School topper in 9th grade", "sports": "Won district level cricket tournament", "cultural": "Participated in school annual day", "others": "Volunteer work at local NGO" }, "expectations": [ "1. Self-Understanding: Gain deeper insights into their personality, strengths, and areas for growth.", "2. Career Guidance: Clear recommendations on suitable career paths or college majors based on their interests and abilities, backed by scientific tool.", "3. Academic Support: Help in identifying their learning styles, study habits, or cognitive strengths to improve performance." ] } if json_file: json_path = Path(json_file) if json_path.exists(): with open(json_path, 'r') as f: custom_data = json.load(f) # Merge custom data with defaults (custom takes precedence) merged_data = default_data.copy() for key, value in custom_data.items(): if isinstance(value, dict) and key in merged_data: merged_data[key].update(value) else: merged_data[key] = value return merged_data else: print(f"⚠️ JSON file not found: {json_file}. Using default data.") return default_data def complete_profile_with_data(profile_editor, profile_data): """ Complete profile using provided data Args: profile_editor: ProfileEditorPage instance profile_data: Dictionary with profile data """ print("\nπŸš€ Starting profile completion with provided data...") # Step 1: Personal Information print("\nπŸ“ Step 1/9: Personal Information") profile_editor.navigate_to_tab(0) time.sleep(0.5) personal = profile_data.get("personal_information", {}) profile_editor.fill_personal_information( first_name=personal.get("first_name"), last_name=personal.get("last_name"), gender=personal.get("gender"), dob=personal.get("dob"), roll_number=personal.get("roll_number"), nationality=personal.get("nationality") ) print("βœ… Personal Information filled") # Step 2: Contact Information print("\nπŸ“ Step 2/9: Contact Information") profile_editor.navigate_to_tab(1) time.sleep(0.5) contact = profile_data.get("contact_information", {}) profile_editor.fill_contact_information( email=contact.get("email"), phone=contact.get("phone"), address=contact.get("address"), city=contact.get("city"), state=contact.get("state"), zip_code=contact.get("zip_code"), native_state=contact.get("native_state") ) print("βœ… Contact Information filled") # Step 3: Parent/Guardian print("\nπŸ“ Step 3/9: Parent/Guardian") profile_editor.navigate_to_tab(2) time.sleep(0.5) parent = profile_data.get("parent_guardian", {}) profile_editor.fill_parent_guardian( father_name=parent.get("father_name"), father_age_range=parent.get("father_age_range"), father_occupation=parent.get("father_occupation"), father_email=parent.get("father_email"), mother_name=parent.get("mother_name"), mother_age_range=parent.get("mother_age_range"), mother_occupation=parent.get("mother_occupation"), mother_email=parent.get("mother_email") ) print("βœ… Parent/Guardian filled") # Step 4: Education Details print("\nπŸ“ Step 4/9: Education Details") profile_editor.navigate_to_tab(3) time.sleep(0.5) education = profile_data.get("education_details", {}) profile_editor.fill_education_details( full_name=education.get("full_name"), current_grade=education.get("current_grade"), section=education.get("section"), board_stream=education.get("board_stream") ) print("βœ… Education Details filled") # Step 5: Focus Areas print("\nπŸ“ Step 5/9: Focus Areas") profile_editor.navigate_to_tab(4) time.sleep(0.5) focus = profile_data.get("focus_areas", {}) profile_editor.select_focus_areas( short_term=focus.get("short_term"), long_term=focus.get("long_term") ) print("βœ… Focus Areas selected") # Step 6: Self-Assessment print("\nπŸ“ Step 6/9: Self-Assessment") profile_editor.navigate_to_tab(5) time.sleep(0.5) assessment = profile_data.get("self_assessment", {}) profile_editor.select_strengths(assessment.get("strengths", [])) profile_editor.select_improvements(assessment.get("improvements", [])) print("βœ… Self-Assessment completed") # Step 7: Hobbies & Clubs print("\nπŸ“ Step 7/9: Hobbies & Clubs") profile_editor.navigate_to_tab(6) time.sleep(0.5) hobbies_clubs = profile_data.get("hobbies_clubs", {}) profile_editor.select_hobbies(hobbies_clubs.get("hobbies", [])) profile_editor.select_clubs(hobbies_clubs.get("clubs", [])) print("βœ… Hobbies & Clubs selected") # Step 8: Achievements print("\nπŸ“ Step 8/9: Achievements") profile_editor.navigate_to_tab(7) time.sleep(0.5) achievements = profile_data.get("achievements", {}) profile_editor.fill_achievements( academics=achievements.get("academics"), sports=achievements.get("sports"), cultural=achievements.get("cultural"), others=achievements.get("others") ) print("βœ… Achievements filled") # Step 9: Expectations print("\nπŸ“ Step 9/9: Expectations") profile_editor.navigate_to_tab(8) time.sleep(0.5) expectations = profile_data.get("expectations", []) profile_editor.select_expectations(expectations) print("βœ… Expectations selected") # Save profile print("\nπŸ’Ύ Saving profile...") progress_before = profile_editor.get_progress_value() print(f"πŸ“Š Progress before save: {progress_before}") profile_editor.click_save() time.sleep(2) progress_after = profile_editor.get_progress_value() print(f"πŸ“Š Progress after save: {progress_after}") if "100%" in progress_after or progress_after == "100": print("βœ… Profile completed to 100%!") return True else: print(f"⚠️ Profile not at 100% yet. Current: {progress_after}") # Try saving again profile_editor.click_save() time.sleep(2) progress_final = profile_editor.get_progress_value() print(f"πŸ“Š Final progress: {progress_final}") return "100%" in progress_final or progress_final == "100" def main(): """Main execution function""" parser = argparse.ArgumentParser( description="Complete student profile to 100% and navigate to assessments", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: # Basic usage with default data python scripts/complete_profile_to_assessment.py --cpid BATBAT311A --password Admin@123 # With custom profile data python scripts/complete_profile_to_assessment.py --cpid DESDES29BB --password Admin@123 --profile-data profile_data.json """ ) parser.add_argument( "--cpid", required=True, help="Student CPID (e.g., BATBAT311A)" ) parser.add_argument( "--password", required=True, help="Student password (will try this first, then Admin@123 if needed)" ) parser.add_argument( "--profile-data", help="Path to JSON file with custom profile data (optional)" ) parser.add_argument( "--headless", action="store_true", help="Run in headless mode (no browser window)" ) args = parser.parse_args() # Load profile data profile_data = load_profile_data(args.profile_data) # Initialize driver driver = None try: print("=" * 80) print("πŸš€ COMPLETE PROFILE TO ASSESSMENT - END-TO-END SCRIPT") print("=" * 80) print(f"\nπŸ“‹ Configuration:") print(f" CPID: {args.cpid}") print(f" Password: {'*' * len(args.password)}") print(f" Profile Data: {'Custom' if args.profile_data else 'Default'}") print(f" Headless: {args.headless}") print(f" Base URL: {BASE_URL}") print() # Get driver driver = DriverManager.get_driver(headless=args.headless) # Step 1: Login print("\n" + "=" * 80) print("STEP 1: LOGIN") print("=" * 80) login_page = LoginPage(driver) login_page.login(identifier=args.cpid, password=args.password) print(f"βœ… Login successful for {args.cpid}") # Step 2: Handle Password Reset (if needed) print("\n" + "=" * 80) print("STEP 2: PASSWORD RESET (if needed)") print("=" * 80) reset_page = MandatoryResetPage(driver) if reset_page.is_modal_present(): print("πŸ” Password reset modal detected - resetting password...") current_password = password_tracker.get_password(args.cpid, args.password) reset_page.reset_password( current_password=current_password, new_password=TEST_NEW_PASSWORD, confirm_password=TEST_NEW_PASSWORD, student_cpid=args.cpid ) print(f"βœ… Password reset to {TEST_NEW_PASSWORD}") else: print("βœ… No password reset needed") # Step 3: Handle Profile Incomplete Modal (if needed) print("\n" + "=" * 80) print("STEP 3: PROFILE INCOMPLETE MODAL (if needed)") print("=" * 80) profile_incomplete = ProfileIncompletePage(driver) if profile_incomplete.is_modal_present(): progress = profile_incomplete.get_progress_value() print(f"πŸ“Š Current profile progress: {progress}") print("πŸ“ Clicking 'Complete Profile Now' button...") profile_incomplete.click_complete() print("βœ… Navigated to profile editor") else: print("βœ… Profile incomplete modal not present") # Step 4: Complete Profile to 100% print("\n" + "=" * 80) print("STEP 4: COMPLETE PROFILE TO 100%") print("=" * 80) profile_editor = ProfileEditorPage(driver) profile_editor.wait_for_page_load() initial_progress = profile_editor.get_progress_value() print(f"πŸ“Š Initial profile progress: {initial_progress}") if "100%" in initial_progress or initial_progress == "100": print("βœ… Profile is already 100% complete!") else: # Complete profile with provided data success = complete_profile_with_data(profile_editor, profile_data) if not success: print("❌ Failed to complete profile to 100%") return 1 # Step 5: Navigate to Assessments print("\n" + "=" * 80) print("STEP 5: NAVIGATE TO ASSESSMENTS") print("=" * 80) # Navigate to dashboard first dashboard = DashboardPage(driver) dashboard.navigate() time.sleep(1) # Click Assessments link dashboard.click_assessments() time.sleep(2) # Verify we're on assessments page assessments = AssessmentsPage(driver) assessments.wait_for_page_load() current_url = driver.current_url if "/assessments" in current_url: print("βœ… Successfully navigated to Assessments page!") print(f" URL: {current_url}") else: print(f"⚠️ Unexpected URL: {current_url}") # Final summary print("\n" + "=" * 80) print("βœ… SUCCESS - STUDENT IS NOW ASSESSMENT READY!") print("=" * 80) print(f"\nπŸ“‹ Summary:") print(f" CPID: {args.cpid}") print(f" Profile Status: 100% Complete") print(f" Current Page: Assessments") print(f" URL: {driver.current_url}") print("\nπŸŽ‰ Student can now access and take assessments!") # Keep browser open for inspection (if not headless) if not args.headless: print("\n⏸️ Browser will remain open for 30 seconds for inspection...") print(" Press Ctrl+C to close immediately") try: time.sleep(30) except KeyboardInterrupt: print("\nπŸ‘‹ Closing browser...") return 0 except Exception as e: print(f"\n❌ ERROR: {e}") import traceback traceback.print_exc() return 1 finally: if driver: driver.quit() print("\nπŸ‘‹ Browser closed") if __name__ == "__main__": sys.exit(main())