Skip to content

Commit abea6ab

Browse files
ccevstephanlensky
andauthored
Make Browser.get and Tab.close wait for their appropiate target events before returning (#91)
* Wait for their appropiate target events before returning Browser.get and Tab.close * fix mypy issues * always wait for TargetInfoChanged in Browser.get --------- Co-authored-by: Stephan Lensky <8302875+stephanlensky@users.noreply.github.com>
1 parent 9350d39 commit abea6ab

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- `Browser.get` and `Tab.close` will now wait for their appropiate target events before returning @ccev
13+
1214
### Added
1315

1416
- Added `Tab.save_snapshot` to export the current page to MHTML format.

zendriver/core/browser.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,19 @@ async def get(
252252
:param new_tab: open new tab
253253
:param new_window: open new window
254254
:return: Page
255+
:raises: asyncio.TimeoutError
255256
"""
256257
if not self.connection:
257258
raise RuntimeError("Browser not yet started. use await browser.start()")
258259

260+
future = asyncio.get_running_loop().create_future()
261+
event_type = cdp.target.TargetInfoChanged
262+
263+
async def get_handler(event: cdp.target.TargetInfoChanged) -> None:
264+
future.set_result(event)
265+
266+
self.connection.add_handler(event_type, get_handler)
267+
259268
if new_tab or new_window:
260269
# create new target using the browser session
261270
target_id = await self.connection.send(
@@ -271,15 +280,16 @@ async def get(
271280
)
272281
)
273282
connection.browser = self
274-
275283
else:
276284
# first tab from browser.tabs
277285
connection = next(filter(lambda item: item.type_ == "page", self.targets))
278286
# use the tab to navigate to new url
279287
await connection.send(cdp.page.navigate(url))
280288
connection.browser = self
281289

282-
await connection.sleep(0.25)
290+
await asyncio.wait_for(future, 10)
291+
self.connection.remove_handlers(event_type, get_handler)
292+
283293
return connection
284294

285295
async def start(self) -> Browser:

zendriver/core/tab.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,10 +907,28 @@ async def close(self):
907907
close the current target (ie: tab,window,page)
908908
:return:
909909
:rtype:
910+
:raises: asyncio.TimeoutError
911+
:raises: RuntimeError
910912
"""
913+
914+
if not self.browser or not self.browser.connection:
915+
raise RuntimeError("Browser not yet started. use await browser.start()")
916+
917+
future = asyncio.get_running_loop().create_future()
918+
event_type = cdp.target.TargetDestroyed
919+
920+
async def close_handler(event: cdp.target.TargetDestroyed) -> None:
921+
if self.target and event.target_id == self.target.target_id:
922+
future.set_result(event)
923+
924+
self.browser.connection.add_handler(event_type, close_handler)
925+
911926
if self.target and self.target.target_id:
912927
await self.send(cdp.target.close_target(target_id=self.target.target_id))
913928

929+
await asyncio.wait_for(future, 10)
930+
self.browser.connection.remove_handlers(event_type, close_handler)
931+
914932
async def get_window(self) -> Tuple[cdp.browser.WindowID, cdp.browser.Bounds]:
915933
"""
916934
get the window Bounds

0 commit comments

Comments
 (0)