07.03 — Dashboard login scenarios#
Three families: happy paths, unhappy paths, data-driven multi-login. All exercise the 10%-fail useAuth and OTP coordination.
dashboard_login#
# src/tests/campaigns/dashboard_login.py
def create_igoristan_login_campaign(*, drivers_pool: SeleniumWebDriversPool) -> TestCampaign:
return TestCampaign(
name="Dashboard login",
suites=[
create_igoristan_login_happy_paths_test_suite(drivers_pool=drivers_pool),
create_igoristan_login_unhappy_paths_test_suite(drivers_pool=drivers_pool),
create_igoristan_login_data_driven_test_suite(drivers_pool=drivers_pool),
],
)
Happy paths#
# src/tests/suites/dashboard/access/happy_paths.py
def create_igoristan_login_happy_paths_test_suite(*, drivers_pool) -> TestSuite:
return TestSuite(
name="Login happy paths",
tests=[
test_dashboard_login_without_otp_happy_path,
test_dashboard_login_with_otp_happy_path,
test_dashboard_login_page_back_to_igoristan_button,
],
drivers_pool=drivers_pool,
)
Test 1: login without OTP#
def dashboard_login_without_otp_happy_path(driver, logger):
dashboard_creds = create_env_getters().get_credentials("dashboard")
on_dashboard_login_page = DashboardLoginPage(driver=driver)
on_dashboard_welcome_page = DashboardWelcomePage(driver=driver)
just_log_error = create_just_log_error(logger=logger)
log_error_with_current_url = create_log_error_with_current_url(logger=logger, driver=driver)
just_log_success = create_just_log_success(logger=logger)
log_success_with_current_url_and_take_screenshot = create_log_success_with_current_url_and_take_screenshot(...)
retries_amount = max(get_max_workers(), 10)
return [
drive_page(
act(on_dashboard_login_page, open_dashboard_login_page)
.failure(just_log_error("Failed to open the dashboard login page..."))
.success(just_log_success("Opened the dashboard login page!")),
act(on_dashboard_login_page, verify_dashboard_login_page)
.failure(log_error_with_current_url("Failed to verify..."))
.success(log_success_with_current_url_and_take_screenshot("Verified!")),
act(on_dashboard_login_page,
login_without_otp_and_with_retries(dashboard_creds, retries_amount, logger=logger))
.failure(just_log_error("Failed to connect to the dashboard without OTP..."))
.success(just_log_success("Connected to the dashboard!")),
),
drive_page(
act(on_dashboard_welcome_page, verify_dashboard_welcome_page)
.failure(log_error_with_current_url("Failed to verify..."))
.success(log_success_with_current_url_and_take_screenshot("Verified!")),
),
]
retries_amount = max(get_max_workers(), 10): at least 10 internal login retries to beat the 10% random failure.login_without_otp_and_with_retries(creds, retries_amount, logger=logger): closure capturing creds, retry count, and logger. Returns Callable[[DashboardLoginPage], DashboardLoginPage].- 2
drive_pages: login page then welcome page. Each opens, verifies, screenshots. - Log factories everywhere: no inline lambdas.
SeleniumTitleMixin: get_current_title() feeds act’s on_failure hook.
Test 2: login with OTP#
def dashboard_login_with_otp_happy_path(driver, logger):
# ... same setup ...
cache = in_memory_cache_with_30m_ttl
fresh_cache_key_for_username = reserve_free_cache_key(cache)
fresh_cache_key_for_otp_send_button_click_date = reserve_free_cache_key(cache)
return [
drive_page(
act(on_dashboard_login_page, open_dashboard_login_page)...,
act(on_dashboard_login_page, verify_dashboard_login_page)...,
act(on_dashboard_login_page,
start_to_login_with_otp_and_with_retries(
dashboard_creds, retries_amount,
cache=cache, logger=logger,
username_cache_key=fresh_cache_key_for_username,
otp_send_button_click_date_cache_key=fresh_cache_key_for_otp_send_button_click_date,
))...,
act(on_dashboard_login_page, verify_otp_screen)...,
act(on_dashboard_login_page,
type_otp_with_retries(
retries_amount,
cache=cache, logger=logger,
username_cache_key=fresh_cache_key_for_username,
otp_send_button_click_date_cache_key=fresh_cache_key_for_otp_send_button_click_date,
))...,
),
drive_page(
act(on_dashboard_welcome_page, verify_dashboard_welcome_page)...,
act(on_dashboard_welcome_page, click_on_go_to_nested_page_btn)...,
),
drive_page(
act(on_dashboard_protected_page, verify_dashboard_protected_page)...,
),
]
Three drive_pages, five acts in the first. L1 cache + reserved keys share values between acts (see 08-caches-locks.md).