171 lines
8.3 KiB
Python
171 lines
8.3 KiB
Python
"""
|
|
Logout Test Cases
|
|
|
|
Tests logout functionality for students.
|
|
|
|
IMPORTANT: Password reset must be completed before logout tests,
|
|
otherwise the mandatory reset popup will block logout.
|
|
"""
|
|
import pytest
|
|
from pages.login_page import LoginPage
|
|
from pages.dashboard_page import DashboardPage
|
|
from pages.mandatory_reset_page import MandatoryResetPage
|
|
from pages.profile_incomplete_page import ProfileIncompletePage
|
|
from config.config import TEST_USERNAME, TEST_PASSWORD, TEST_NEW_PASSWORD, BASE_URL
|
|
|
|
|
|
@pytest.mark.authentication
|
|
@pytest.mark.logout
|
|
class TestLogout:
|
|
"""Test cases for logout functionality"""
|
|
|
|
def test_logout_from_dashboard(self, driver):
|
|
"""
|
|
Test logout from dashboard
|
|
|
|
IMPORTANT: Password reset is handled FIRST to prevent blocker.
|
|
"""
|
|
# Step 1: Login (use tracked password if available)
|
|
from utils.password_tracker import password_tracker
|
|
password = password_tracker.get_password(TEST_USERNAME, TEST_PASSWORD)
|
|
login_page = LoginPage(driver)
|
|
login_page.login(identifier=TEST_USERNAME, password=password)
|
|
|
|
# Step 2: Handle password reset FIRST (prevents blocker)
|
|
# Smart login already handled password, but check if reset modal appeared
|
|
reset_page = MandatoryResetPage(driver)
|
|
if reset_page.is_modal_present():
|
|
print("✅ Password reset modal detected - resetting password first")
|
|
# Get current password from tracker or use Excel password
|
|
from utils.password_tracker import password_tracker
|
|
current_password = password_tracker.get_password(TEST_USERNAME, TEST_PASSWORD)
|
|
reset_page.reset_password(
|
|
current_password=current_password,
|
|
new_password=TEST_NEW_PASSWORD,
|
|
confirm_password=TEST_NEW_PASSWORD,
|
|
student_cpid=TEST_USERNAME
|
|
)
|
|
print("✅ Password reset completed - can now proceed to logout")
|
|
else:
|
|
print("✅ Password already reset - proceeding to logout")
|
|
|
|
# Step 3: Verify password reset modal is closed
|
|
assert not reset_page.is_modal_present(), \
|
|
"Password reset modal should be closed before logout test"
|
|
|
|
# Step 4: Handle profile incomplete modal (if present)
|
|
# IMPORTANT: We need to click "Complete Profile Now" to enable profile button
|
|
profile_incomplete = ProfileIncompletePage(driver)
|
|
if profile_incomplete.is_modal_present():
|
|
print("✅ Profile incomplete modal detected - clicking 'Complete Profile Now' to enable logout")
|
|
profile_incomplete.click_complete()
|
|
# Wait for navigation to profile builder
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
WebDriverWait(driver, 5).until(
|
|
EC.url_contains("/profile-builder")
|
|
)
|
|
print("✅ Navigated to profile builder - profile button is now enabled")
|
|
|
|
# Step 5: Double-check no modals are blocking
|
|
assert not reset_page.is_modal_present(), "Password reset modal must be closed"
|
|
assert not profile_incomplete.is_modal_present(), "Profile incomplete modal must be handled"
|
|
|
|
# Step 6: Verify we're on a page where logout is accessible
|
|
# (Either dashboard or profile-builder)
|
|
current_url = driver.current_url
|
|
assert "/dashboard" in current_url or "/profile-builder" in current_url or "/student" in current_url, \
|
|
f"Should be on dashboard or profile builder before logout. Current URL: {current_url}"
|
|
|
|
# Step 7: Logout using profile dropdown
|
|
# Flow: Click profile button → Click Sign Out
|
|
from pages.student_nav_page import StudentNavPage
|
|
nav_page = StudentNavPage(driver)
|
|
nav_page.logout()
|
|
|
|
# Step 8: Verify redirect to login page
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
WebDriverWait(driver, 5).until(
|
|
lambda d: "/login" in d.current_url or d.current_url.rstrip("/") == BASE_URL.rstrip("/")
|
|
)
|
|
assert "/login" in driver.current_url or driver.current_url.rstrip("/") == BASE_URL.rstrip("/"), \
|
|
f"Should be redirected to login page. Current URL: {driver.current_url}"
|
|
print("✅ Logout successful - redirected to login page")
|
|
|
|
def test_logout_after_password_reset(self, driver):
|
|
"""
|
|
Test logout after password reset
|
|
|
|
This test explicitly verifies logout works after password reset.
|
|
"""
|
|
# Step 1: Login (use tracked password if available)
|
|
from utils.password_tracker import password_tracker
|
|
password = password_tracker.get_password(TEST_USERNAME, TEST_PASSWORD)
|
|
login_page = LoginPage(driver)
|
|
login_page.login(identifier=TEST_USERNAME, password=password)
|
|
|
|
# Step 2: Password reset (MUST happen first)
|
|
reset_page = MandatoryResetPage(driver)
|
|
password_reset_done = False
|
|
if reset_page.is_modal_present():
|
|
print("✅ Password reset modal detected - resetting password")
|
|
# CRITICAL: Get current password from tracker (not hardcoded TEST_PASSWORD)
|
|
# This ensures we use the correct password even if it was already reset
|
|
current_password = password_tracker.get_password(TEST_USERNAME, TEST_PASSWORD)
|
|
print(f"🔐 Using current password from tracker: {current_password[:3]}...")
|
|
|
|
# CRITICAL: Always reset to TEST_NEW_PASSWORD (not TEST_PASSWORD)
|
|
reset_page.reset_password(
|
|
current_password=current_password,
|
|
new_password=TEST_NEW_PASSWORD, # ✅ Always use TEST_NEW_PASSWORD
|
|
confirm_password=TEST_NEW_PASSWORD,
|
|
student_cpid=TEST_USERNAME
|
|
)
|
|
password_reset_done = True
|
|
print("✅ Password reset completed")
|
|
else:
|
|
print("✅ Password already reset")
|
|
|
|
# Step 3: Verify reset modal is closed
|
|
assert not reset_page.is_modal_present(), \
|
|
"Password reset modal must be closed before logout"
|
|
|
|
# Step 4: Handle profile incomplete (if present)
|
|
# IMPORTANT: Click "Complete Profile Now" to enable profile button
|
|
profile_incomplete = ProfileIncompletePage(driver)
|
|
if profile_incomplete.is_modal_present():
|
|
print("✅ Profile incomplete modal detected - clicking 'Complete Profile Now'")
|
|
profile_incomplete.click_complete()
|
|
# Wait for navigation to profile builder
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
WebDriverWait(driver, 5).until(
|
|
EC.url_contains("/profile-builder")
|
|
)
|
|
print("✅ Navigated to profile builder - profile button enabled")
|
|
|
|
# Step 5: Double-check no modals are blocking
|
|
assert not reset_page.is_modal_present(), "Password reset modal must be closed"
|
|
assert not profile_incomplete.is_modal_present(), "Profile incomplete modal must be handled"
|
|
|
|
# Step 6: Verify we're on a page where logout is accessible
|
|
current_url = driver.current_url
|
|
assert "/dashboard" in current_url or "/profile-builder" in current_url or "/student" in current_url, \
|
|
f"Should be on dashboard or profile builder. Current URL: {current_url}"
|
|
|
|
# Step 7: Logout using profile dropdown
|
|
from pages.student_nav_page import StudentNavPage
|
|
nav_page = StudentNavPage(driver)
|
|
nav_page.logout()
|
|
|
|
# Step 8: Verify redirect to login page
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
WebDriverWait(driver, 5).until(
|
|
lambda d: "/login" in d.current_url or d.current_url.rstrip("/") == BASE_URL.rstrip("/")
|
|
)
|
|
assert "/login" in driver.current_url or driver.current_url.rstrip("/") == BASE_URL.rstrip("/"), \
|
|
f"Should be redirected to login page. Current URL: {driver.current_url}"
|
|
print("✅ Logout successful after password reset")
|