diff --git a/pydoll/browser/page.py b/pydoll/browser/page.py index 4f29e28b..185c9396 100644 --- a/pydoll/browser/page.py +++ b/pydoll/browser/page.py @@ -126,6 +126,39 @@ async def delete_all_cookies(self): await self._execute_command(StorageCommands.clear_cookies()) await self._execute_command(NetworkCommands.clear_browser_cookies()) + async def has_dialog(self) -> bool: + """ + Checks if a dialog is present on the page. + + Returns: + bool: True if a dialog is present, False otherwise. + """ + if self._connection_handler.dialog: + return True + return False + + async def get_dialog_message(self) -> str: + """ + Retrieves the message of the dialog on the page. + + Returns: + str: The message of the dialog. + """ + if not await self.has_dialog(): + raise LookupError('No dialog present on the page') + return self._connection_handler.dialog['params']['message'] + + async def accept_dialog(self): + """ + Accepts the dialog on the page. + + Raises: + LookupError: If no dialog is present on the page. + """ + if not await self.has_dialog(): + raise LookupError('No dialog present on the page') + await self._execute_command(PageCommands.handle_dialog(True)) + async def go_to(self, url: str, timeout=300): """ Navigates to a URL in the page. diff --git a/pydoll/commands/page.py b/pydoll/commands/page.py index 5256dd11..6e0ad433 100644 --- a/pydoll/commands/page.py +++ b/pydoll/commands/page.py @@ -30,6 +30,25 @@ class PageCommands: 'method': 'Page.setDownloadBehavior', 'params': {}, } + HANDLE_DIALOG = {'method': 'Page.handleJavaScriptDialog', 'params': {}} + + @classmethod + def handle_dialog(cls, accept: bool = True) -> dict: + """ + Generates the command to handle a JavaScript dialog. + + Args: + accept (bool): Whether to accept the dialog. + If True, the dialog will be accepted. + If False, the dialog will be dismissed. + + Returns: + dict: The command to be sent to the browser, + containing the method and parameters for handling the dialog. + """ + command = cls.HANDLE_DIALOG.copy() + command['params']['accept'] = accept + return command @classmethod def set_download_path(cls, path: str) -> dict: diff --git a/pydoll/connection.py b/pydoll/connection.py index dd17a3c3..55f2dc03 100644 --- a/pydoll/connection.py +++ b/pydoll/connection.py @@ -38,6 +38,7 @@ def __init__(self, connection_port: int, page_id: str = 'browser'): self._callback_id = 0 self._pending_commands: dict[int, asyncio.Future] = {} self.network_logs = [] + self.dialog = {} logger.info('ConnectionHandler initialized.') @property @@ -228,6 +229,12 @@ async def _handle_event(self, event: dict): self.network_logs.append(event) self.network_logs = self.network_logs[-10000:] + if 'Page.javascriptDialogOpening' in event_name: + self.dialog = event + + if 'Page.javascriptDialogClosed' in event_name: + self.dialog = {} + event_callbacks = self._event_callbacks.copy() for callback_id, callback_data in event_callbacks.items(): if callback_data['event'] == event_name: