from unittest.mock import MagicMock import pytest from selenium.common.exceptions import WebDriverException from wabot.browser import Browser from wabot.pacing import HumanPacing, NoPacing from wabot.page import Page class Login(Page): elements = {"username": ("el", ("id", "username"))} def do_login(self): return "logged-in" def explode(self): raise WebDriverException("browser gone") class Unverifiable(Page): def verify(self): return False @pytest.fixture def bot(): return Browser(MagicMock(name="driver"), pacing=NoPacing()) class TestConstruction: def test_good_flag_starts_true(self, bot): assert bot.good is True def test_default_pacing_is_human(self): assert isinstance(Browser(MagicMock()).pacing, HumanPacing) class TestSetPage: def test_sets_and_returns_true(self, bot): assert bot.set_page(Login) is True assert isinstance(bot.page, Login) def test_failed_verify_refuses_switch(self, bot): bot.set_page(Login) assert bot.set_page(Unverifiable) is False assert isinstance(bot.page, Login) # unchanged class TestDelegation: def test_getattr_delegates_to_page(self, bot): bot.set_page(Login) assert bot.do_login() == "logged-in" def test_getitem_delegates_to_page(self, bot): bot.set_page(Login) el = bot["username"] assert el.name == "username" def test_getattr_without_page_raises(self, bot): with pytest.raises(AttributeError): _ = bot.do_login class TestPerform: def test_returns_method_result(self, bot): bot.set_page(Login) assert bot.perform("do_login") == "logged-in" def test_missing_method_returns_none(self, bot): bot.set_page(Login) assert bot.perform("nope") is None def test_webdriver_exception_flips_good(self, bot): bot.set_page(Login) assert bot.perform("explode") is None assert bot.good is False def test_broken_state_refuses_actions_until_reset(self, bot): bot.set_page(Login) bot.perform("explode") assert bot.perform("do_login") is None # refused assert bot.do_login() is None # __getattr__ path also refused bot.reset() assert bot.perform("do_login") == "logged-in" class TestQuit: def test_quit_quits_driver_and_removes_session(self): driver, store = MagicMock(), MagicMock() bot = Browser(driver, session_name="s1", store=store) bot.quit() driver.quit.assert_called_once_with() store.remove.assert_called_once_with("s1") def test_quit_without_session_only_quits(self): driver = MagicMock() Browser(driver).quit() driver.quit.assert_called_once_with()