diff --git a/pydoll/browser/interfaces.py b/pydoll/browser/interfaces.py index 48fff1d..d40ed76 100644 --- a/pydoll/browser/interfaces.py +++ b/pydoll/browser/interfaces.py @@ -1,5 +1,7 @@ from abc import ABC, abstractmethod +from pydoll.constants import PageLoadState + class Options(ABC): @property @@ -36,6 +38,16 @@ def headless(self) -> bool: def headless(self, headless: bool): pass + @property + @abstractmethod + def page_load_state(self) -> PageLoadState: + pass + + @page_load_state.setter + @abstractmethod + def page_load_state(self, state: PageLoadState): + pass + class BrowserOptionsManager(ABC): @abstractmethod diff --git a/pydoll/browser/options.py b/pydoll/browser/options.py index bd545bf..9c7e5be 100644 --- a/pydoll/browser/options.py +++ b/pydoll/browser/options.py @@ -1,6 +1,7 @@ from contextlib import suppress from pydoll.browser.interfaces import Options +from pydoll.constants import PageLoadState from pydoll.exceptions import ( ArgumentAlreadyExistsInOptions, ArgumentNotFoundInOptions, @@ -28,6 +29,7 @@ def __init__(self): self._start_timeout = 10 self._browser_preferences = {} self._headless = False + self._page_load_state = PageLoadState.COMPLETE @property def arguments(self) -> list[str]: @@ -316,3 +318,11 @@ def headless(self, headless: bool): if headless == has_argument: return methods_map[headless]('--headless') + + @property + def page_load_state(self) -> PageLoadState: + return self._page_load_state + + @page_load_state.setter + def page_load_state(self, state: PageLoadState): + self._page_load_state = state diff --git a/pydoll/browser/tab.py b/pydoll/browser/tab.py index 5cba5a7..dac198a 100644 --- a/pydoll/browser/tab.py +++ b/pydoll/browser/tab.py @@ -1044,7 +1044,10 @@ async def _wait_page_load(self, timeout: int = 300): response: EvaluateResponse = await self._execute_command( RuntimeCommands.evaluate(expression='document.readyState') ) - if response['result']['result']['value'] == 'complete': + if ( + response['result']['result']['value'] + == self._browser.options.page_load_state.value + ): break if asyncio.get_event_loop().time() - start_time > timeout: raise WaitElementTimeout('Page load timed out') diff --git a/pydoll/constants.py b/pydoll/constants.py index f0e3e63..f194d3d 100644 --- a/pydoll/constants.py +++ b/pydoll/constants.py @@ -10,6 +10,11 @@ class By(str, Enum): NAME = 'name' +class PageLoadState(str, Enum): + COMPLETE = 'complete' + INTERACTIVE = 'interactive' + + class Scripts: ELEMENT_VISIBLE = """ function() { diff --git a/tests/test_browser/test_browser_options.py b/tests/test_browser/test_browser_options.py index 3e15a45..4af4e3f 100644 --- a/tests/test_browser/test_browser_options.py +++ b/tests/test_browser/test_browser_options.py @@ -2,6 +2,7 @@ from pydoll.browser.interfaces import Options as OptionsInterface from pydoll.browser.options import ChromiumOptions as Options +from pydoll.constants import PageLoadState from pydoll.exceptions import ( ArgumentAlreadyExistsInOptions, ArgumentNotFoundInOptions, @@ -31,6 +32,17 @@ def test_set_start_timeout(): assert options.start_timeout == 30 +def test_initial_page_load_state(): + options = Options() + assert options.page_load_state == PageLoadState.COMPLETE + + +def test_set_page_load_state(): + options = Options() + options.page_load_state = PageLoadState.INTERACTIVE + assert options.page_load_state == PageLoadState.INTERACTIVE + + def test_add_argument(): options = Options() options.add_argument('--headless') @@ -225,6 +237,14 @@ def browser_preferences(self): def headless(self): return False + @property + def page_load_state(self): + return PageLoadState.COMPLETE + + @page_load_state.setter + def page_load_state(self, state): + pass + CompleteOptions() def test_set_headless(): diff --git a/tests/test_browser/test_browser_tab.py b/tests/test_browser/test_browser_tab.py index d443b08..c1d40a3 100644 --- a/tests/test_browser/test_browser_tab.py +++ b/tests/test_browser/test_browser_tab.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch, ANY from pathlib import Path +from pydoll.browser.options import ChromiumOptions from pydoll.protocol.network.types import ResourceType, RequestMethod from pydoll.protocol.fetch.types import RequestStage from pydoll.constants import By @@ -45,6 +46,7 @@ async def mock_browser(): """Mock browser instance.""" browser = MagicMock() browser.close_tab = AsyncMock() + browser.options = ChromiumOptions() return browser