from datetime import datetime import pytest from playwright_tests.planning import build_plan from playwright_tests.setup_page import SetupPage @pytest.fixture def config(): return { "setup": {"run_session": True, "run_token": True}, "trading_token_idas": {"product_codes": "IDAS,IDASTEST01", "market_code": "NATIONAL"}, } def test_combined_plan_dates_and_products(config): plan = build_plan(config, now=datetime(2026, 9, 8, 10, 0)) assert plan["session"] == ("08/09/2026 10:07", "08/09/2026 20:30") assert [t["product_code"] for t in plan["tokens"]] == ["IDAS", "IDASTEST01"] assert plan["tokens"][0]["delivery_date"] == "09/09/2026" assert plan["tokens"][0]["rows"][0] == ("ORDER_NOR", "10:10", "18:30") def test_login_ignores_expired_mutation_settings(config): assert build_plan(config, "login", now=datetime(2026, 9, 8, 23)) == {"session": None, "tokens": []} def test_token_override_does_not_modify_config(config): plan = build_plan(config, "token", "IDASTEST02", datetime(2026, 9, 8, 10)) assert plan["session"] is None assert [t["product_code"] for t in plan["tokens"]] == ["IDASTEST02"] assert config["trading_token_idas"]["product_codes"] == "IDAS,IDASTEST01" @pytest.mark.parametrize("flow, message", [("session", "Session end_time"), ("token", "expiry_time")]) def test_reject_expired_schedule(config, flow, message): with pytest.raises(ValueError, match=message): build_plan(config, flow, now=datetime(2026, 9, 8, 23)) def test_reject_inverted_time_session(config): config["trading_token_idas"]["time_sessions"] = {"ORDER_NOR": {"start_time": "19:00", "end_time": "18:30"}} with pytest.raises(ValueError, match="ORDER_NOR"): build_plan(config, "token", now=datetime(2026, 9, 8, 10)) def test_save_waits_for_delayed_confirmation(page, tmp_path): page.set_content('''
''') app = SetupPage(page, tmp_path) app.save("//button", "saved", timeout=2) assert len(app.screenshots) == 1 def test_save_rejects_error_dialog(page, tmp_path): page.set_content('''''') app = SetupPage(page, tmp_path) with pytest.raises(AssertionError, match="Invalid session"): app.save("//button", "saved", timeout=2) assert not app.screenshots def test_save_accepts_success_dialog(page, tmp_path): page.set_content('''''') app = SetupPage(page, tmp_path) app.save("//button", "activated", timeout=2) assert app.screenshots def test_save_does_not_pass_on_click_alone(page, tmp_path): page.set_content("") with pytest.raises(AssertionError, match="no explicit success"): SetupPage(page, tmp_path).save("//button", "saved", timeout=0.2) def test_grid_button_targets_exact_time_session(page, tmp_path): page.set_content('''
ORDER_NOR
ORDER_EXCH
''') SetupPage(page, tmp_path).grid_button("Details", "ORDER_EXCH") assert page.evaluate("window.selected") == "exchange" def test_login_clicks_automatically_after_complete_captcha(page, tmp_path): page.route("https://setup.test/", lambda route: route.fulfill(body=''' ''', content_type="text/html")) app = SetupPage(page, tmp_path) app.login({"url": "https://setup.test/", "login": {"username": "sample", "password": "sample"}}, 2000) assert page.evaluate("window.clickedValue") == "123456" def test_token_details_button_can_be_outside_grid(page, tmp_path): page.set_content('''''') SetupPage(page, tmp_path).grid_button("Token Details") assert page.evaluate("window.opened") is True @pytest.mark.parametrize("configured,displayed", [("ORDER_NOR", "ORDER_NORMAL"), ("ORDER_EXCH", "ORDER_EXCHANGE")]) def test_time_session_aliases_match_live_labels(page, tmp_path, configured, displayed): page.set_content(f'''
{displayed}_OTHER
{displayed}
''') SetupPage(page, tmp_path).grid_button("Details", configured) assert page.evaluate("window.selected") == "correct" def test_dropdown_preserves_already_selected_value(page, tmp_path): page.set_content('') SetupPage(page, tmp_path).choose(page.locator("#market"), "NATIONAL") assert page.evaluate("window.clicked === undefined") @pytest.mark.parametrize("message,passes", [("1|Token updated successfully", True), ("0|Invalid session", False)]) def test_token_save_requires_own_response_despite_old_banner(page, tmp_path, message, passes): from tests.locators import Locator page.route("https://setup.test/", lambda route: route.fulfill(content_type="text/html", body='''
Previous token saved successfully
''')) page.route("**/tokenCtrl/updateTimeSessionMap", lambda route: route.fulfill(json={"message": message})) page.goto("https://setup.test/") app = SetupPage(page, tmp_path) if passes: app.save(Locator.savetimesessionbtn, "saved", timeout=2) assert app.screenshots else: with pytest.raises(AssertionError, match="Invalid session"): app.save(Locator.savetimesessionbtn, "saved", timeout=2) def test_activation_rejects_null_message_even_with_zero_status(page, tmp_path): from tests.locators import Locator page.route("https://setup.test/", lambda route: route.fulfill(content_type="text/html", body='''
TOKEN123
ABC
I
''')) page.route("**/tokenCtrl/updateTokenMstr", lambda route: route.fulfill(json={"message": None, "status": 0})) page.goto("https://setup.test/") app = SetupPage(page, tmp_path) app.token_id = "TOKEN123" with pytest.raises(AssertionError, match="Activation not confirmed for token TOKEN123"): app.save(Locator.savetokenandactivatebtn, "activated", timeout=2) assert not app.screenshots