324 lines
13 KiB
Python
324 lines
13 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Complete Student Journey Test
|
|
|
|
Systematic end-to-end test covering the entire student flow:
|
|
1. Login
|
|
2. Password Reset (if new student) → Admin@123
|
|
3. Profile Completion (if not 100%)
|
|
4. Start Assessment
|
|
5. Complete All Domains/Phases
|
|
6. Provide All Feedbacks
|
|
7. Complete Assessment
|
|
|
|
This is a comprehensive, systematic test following best practices.
|
|
"""
|
|
import sys
|
|
import time
|
|
import pytest
|
|
from pathlib import 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.student_nav_page import StudentNavPage
|
|
from pages.assessments_page import AssessmentsPage
|
|
from pages.domains_page import DomainsPage
|
|
from pages.domain_assessment_page import DomainAssessmentPage
|
|
from pages.domain_feedback_page import DomainFeedbackPage
|
|
from pages.feedback_survey_page import FeedbackSurveyPage
|
|
from utils.driver_manager import DriverManager
|
|
from config.config import BASE_URL, TEST_NEW_PASSWORD
|
|
|
|
|
|
class TestCompleteStudentJourney:
|
|
"""Complete systematic test for student journey"""
|
|
|
|
@pytest.fixture(scope="class")
|
|
def driver(self):
|
|
"""Setup WebDriver"""
|
|
driver_manager = DriverManager()
|
|
driver = driver_manager.get_driver(headless=False) # Visible for debugging
|
|
yield driver
|
|
driver.quit()
|
|
|
|
def test_complete_journey(self, driver, student_cpid, student_password):
|
|
"""
|
|
Complete student journey test
|
|
|
|
Args:
|
|
driver: WebDriver instance
|
|
student_cpid: Student CPID
|
|
student_password: Student password
|
|
"""
|
|
print(f"\n{'='*80}")
|
|
print(f"COMPLETE STUDENT JOURNEY TEST")
|
|
print(f"{'='*80}")
|
|
print(f"Student: {student_cpid}")
|
|
print(f"{'='*80}\n")
|
|
|
|
# STEP 1: LOGIN
|
|
print("[STEP 1] LOGIN")
|
|
print("-" * 80)
|
|
login_page = LoginPage(driver)
|
|
login_page.login(identifier=student_cpid, password=student_password)
|
|
time.sleep(2)
|
|
print(f"✅ Login successful - URL: {driver.current_url}\n")
|
|
|
|
# STEP 2: PASSWORD RESET (if new student)
|
|
print("[STEP 2] PASSWORD RESET CHECK")
|
|
print("-" * 80)
|
|
reset_page = MandatoryResetPage(driver)
|
|
if reset_page.is_modal_present():
|
|
print(" ✅ Password reset modal found (new student)")
|
|
print(f" Resetting password to: {TEST_NEW_PASSWORD}")
|
|
reset_page.reset_password(
|
|
current_password=student_password,
|
|
new_password=TEST_NEW_PASSWORD,
|
|
confirm_password=TEST_NEW_PASSWORD
|
|
)
|
|
print(" ✅ Password reset completed")
|
|
student_password = TEST_NEW_PASSWORD # Update for future use
|
|
else:
|
|
print(" ✅ No password reset required (existing student)")
|
|
print()
|
|
|
|
# STEP 3: PROFILE COMPLETION (if not 100%)
|
|
print("[STEP 3] PROFILE COMPLETION CHECK")
|
|
print("-" * 80)
|
|
profile_incomplete = ProfileIncompletePage(driver)
|
|
if profile_incomplete.is_modal_present():
|
|
progress = profile_incomplete.get_progress_value()
|
|
print(f" Profile incomplete - Current Progress: {progress}")
|
|
print(" Clicking Complete Profile button...")
|
|
profile_incomplete.click_complete()
|
|
time.sleep(3)
|
|
print(f" Navigated to: {driver.current_url}")
|
|
|
|
# Complete profile to 100%
|
|
print("\n [STEP 3.1] Completing Profile to 100%...")
|
|
profile_editor = ProfileEditorPage(driver)
|
|
profile_editor.wait_for_page_load()
|
|
|
|
# TODO: Fill profile with student data
|
|
# For now, we'll note that profile completion automation needs student data
|
|
print(" ⚠️ Profile completion automation requires student data")
|
|
print(" Note: Profile can be completed manually or with data from Excel")
|
|
|
|
# Check progress
|
|
progress = profile_editor.get_progress_value()
|
|
print(f" Current Profile Progress: {progress}")
|
|
|
|
if "100%" in progress:
|
|
print(" ✅ Profile is 100% complete!")
|
|
else:
|
|
print(f" ⚠️ Profile is {progress} complete - needs completion")
|
|
else:
|
|
print(" ✅ Profile already complete or modal not present")
|
|
print()
|
|
|
|
# STEP 4: NAVIGATE TO ASSESSMENTS
|
|
print("[STEP 4] NAVIGATE TO ASSESSMENTS")
|
|
print("-" * 80)
|
|
nav = StudentNavPage(driver)
|
|
nav.click_assessments()
|
|
time.sleep(2)
|
|
print(f"✅ Navigated to Assessments - URL: {driver.current_url}\n")
|
|
|
|
# STEP 5: START ASSESSMENT
|
|
print("[STEP 5] START ASSESSMENT")
|
|
print("-" * 80)
|
|
assessments_page = AssessmentsPage(driver)
|
|
assessments_page.wait_for_page_load()
|
|
|
|
# Get available assessments
|
|
assessments = assessments_page.get_available_assessments()
|
|
print(f" Found {len(assessments)} assessment(s)")
|
|
|
|
if not assessments:
|
|
print(" ⚠️ No assessments available")
|
|
return
|
|
|
|
# Start first available assessment
|
|
first_assessment_id = assessments[0]
|
|
print(f" Starting assessment ID: {first_assessment_id}")
|
|
assessments_page.click_begin_assessment(first_assessment_id)
|
|
time.sleep(3)
|
|
print(f"✅ Assessment started - URL: {driver.current_url}\n")
|
|
|
|
# STEP 6: COMPLETE ALL DOMAINS
|
|
print("[STEP 6] COMPLETE ALL DOMAINS")
|
|
print("-" * 80)
|
|
domains_page = DomainsPage(driver)
|
|
domains_page.wait_for_page_load()
|
|
|
|
# Get all domains
|
|
domains = domains_page.get_available_domains()
|
|
print(f" Found {len(domains)} domain(s)")
|
|
|
|
for idx, domain_id in enumerate(domains, 1):
|
|
print(f"\n [DOMAIN {idx}/{len(domains)}] Domain ID: {domain_id}")
|
|
print(" " + "-" * 76)
|
|
|
|
# Check if domain is unlocked
|
|
if not domains_page.is_domain_unlocked(domain_id):
|
|
print(f" ⚠️ Domain {domain_id} is locked - skipping")
|
|
continue
|
|
|
|
# Start domain assessment
|
|
print(f" Starting domain assessment...")
|
|
domains_page.click_start_domain(domain_id)
|
|
time.sleep(3)
|
|
|
|
# STEP 6.1: COMPLETE DOMAIN ASSESSMENT
|
|
print(f" [STEP 6.1] Completing Domain Assessment...")
|
|
domain_assessment = DomainAssessmentPage(driver)
|
|
domain_assessment.wait_for_page_load()
|
|
|
|
# Get all questions in this domain
|
|
questions = domain_assessment.get_all_questions()
|
|
print(f" Found {len(questions)} question(s) in this domain")
|
|
|
|
# Answer all questions
|
|
for q_idx, question_id in enumerate(questions, 1):
|
|
print(f" [Q{q_idx}/{len(questions)}] Answering question {question_id}...")
|
|
|
|
# Get question type and answer accordingly
|
|
question_type = domain_assessment.get_question_type(question_id)
|
|
print(f" Question type: {question_type}")
|
|
|
|
# Answer based on type
|
|
if question_type == "multiple_choice":
|
|
# Select first option
|
|
options = domain_assessment.get_question_options(question_id)
|
|
if options:
|
|
domain_assessment.select_option(question_id, options[0])
|
|
print(f" Selected option: {options[0]}")
|
|
elif question_type == "true_false":
|
|
# Select True
|
|
domain_assessment.select_true_false(question_id, True)
|
|
print(f" Selected: True")
|
|
elif question_type == "rating":
|
|
# Select middle rating (3 out of 5)
|
|
domain_assessment.select_rating(question_id, 3)
|
|
print(f" Selected rating: 3")
|
|
elif question_type == "open_ended":
|
|
# Enter sample text
|
|
domain_assessment.enter_open_ended(question_id, "Sample response for automation testing")
|
|
print(f" Entered text response")
|
|
elif question_type == "matrix":
|
|
# Fill matrix cells
|
|
rows, cols = domain_assessment.get_matrix_dimensions(question_id)
|
|
for r in range(min(rows, 3)): # Fill first 3 rows
|
|
for c in range(min(cols, 3)): # Fill first 3 cols
|
|
domain_assessment.select_matrix_cell(question_id, r, c, True)
|
|
print(f" Filled matrix cells")
|
|
|
|
time.sleep(0.5) # Small delay between questions
|
|
|
|
# Submit domain assessment
|
|
print(f" Submitting domain assessment...")
|
|
domain_assessment.click_submit()
|
|
time.sleep(2)
|
|
|
|
# Handle submit confirmation modal if present
|
|
if domain_assessment.is_submit_modal_present():
|
|
domain_assessment.confirm_submit()
|
|
time.sleep(2)
|
|
|
|
# Wait for success modal
|
|
if domain_assessment.is_success_modal_present():
|
|
print(f" ✅ Domain assessment submitted successfully")
|
|
domain_assessment.close_success_modal()
|
|
time.sleep(2)
|
|
|
|
# STEP 6.2: PROVIDE DOMAIN FEEDBACK
|
|
print(f" [STEP 6.2] Providing Domain Feedback...")
|
|
domain_feedback = DomainFeedbackPage(driver)
|
|
|
|
if domain_feedback.is_modal_present():
|
|
print(f" Domain feedback modal found")
|
|
|
|
# Answer feedback questions
|
|
# Question 1: Yes/No
|
|
if domain_feedback.has_question1_yes_no():
|
|
domain_feedback.select_question1_yes()
|
|
print(f" Selected: Yes for question 1")
|
|
|
|
# Question 1: Reason (if Yes selected)
|
|
if domain_feedback.has_question1_reason():
|
|
domain_feedback.enter_question1_reason("Automated feedback response")
|
|
print(f" Entered reason")
|
|
|
|
# Question 2: Textarea
|
|
if domain_feedback.has_question2_textarea():
|
|
domain_feedback.enter_question2_text("This is automated feedback for testing purposes.")
|
|
print(f" Entered feedback text")
|
|
|
|
# Submit feedback
|
|
domain_feedback.click_submit()
|
|
time.sleep(2)
|
|
print(f" ✅ Domain feedback submitted")
|
|
else:
|
|
print(f" ⚠️ No domain feedback modal found")
|
|
|
|
# Navigate back to domains page
|
|
print(f" Returning to domains page...")
|
|
driver.back()
|
|
time.sleep(2)
|
|
domains_page = DomainsPage(driver)
|
|
domains_page.wait_for_page_load()
|
|
|
|
print(f"\n✅ All domains completed!\n")
|
|
|
|
# STEP 7: FINAL FEEDBACK
|
|
print("[STEP 7] FINAL FEEDBACK")
|
|
print("-" * 80)
|
|
|
|
# Check if final feedback modal is available
|
|
feedback_survey = FeedbackSurveyPage(driver)
|
|
|
|
if feedback_survey.is_final_feedback_available():
|
|
print(" Final feedback modal found")
|
|
|
|
# Provide overall rating
|
|
feedback_survey.select_overall_rating(4) # 4 out of 5
|
|
print(" Selected overall rating: 4")
|
|
|
|
# Answer per-question feedback if present
|
|
questions = feedback_survey.get_feedback_questions()
|
|
for q_id in questions:
|
|
feedback_survey.select_question_rating(q_id, 4)
|
|
feedback_survey.enter_question_comment(q_id, "Automated feedback comment")
|
|
print(f" Provided feedback for question {q_id}")
|
|
|
|
# Submit final feedback
|
|
feedback_survey.click_submit()
|
|
time.sleep(2)
|
|
print(" ✅ Final feedback submitted")
|
|
else:
|
|
print(" ⚠️ Final feedback modal not available")
|
|
|
|
print(f"\n{'='*80}")
|
|
print("COMPLETE JOURNEY TEST FINISHED SUCCESSFULLY!")
|
|
print(f"{'='*80}\n")
|
|
|
|
# Keep browser open for inspection
|
|
print("Keeping browser open for 60 seconds for inspection...")
|
|
time.sleep(60)
|
|
|
|
|
|
@pytest.mark.parametrize("student_cpid,student_password", [
|
|
("BARBAR110A", "48Rx98pCco*A"),
|
|
# Add more students here as needed
|
|
])
|
|
def test_student_journey(driver, student_cpid, student_password):
|
|
"""Parametrized test for multiple students"""
|
|
test_instance = TestCompleteStudentJourney()
|
|
test_instance.test_complete_journey(driver, student_cpid, student_password)
|
|
|