36
36
SetCookieParam ,
37
37
StorageState ,
38
38
)
39
- from playwright ._impl ._api_types import Error
40
39
from playwright ._impl ._artifact import Artifact
41
40
from playwright ._impl ._cdp_session import CDPSession
42
41
from playwright ._impl ._connection import (
43
42
ChannelOwner ,
43
+ filter_none ,
44
44
from_channel ,
45
45
from_nullable_channel ,
46
46
)
47
47
from playwright ._impl ._console_message import ConsoleMessage
48
48
from playwright ._impl ._dialog import Dialog
49
+ from playwright ._impl ._errors import Error , TargetClosedError
49
50
from playwright ._impl ._event_context_manager import EventContextManagerImpl
50
51
from playwright ._impl ._fetch import APIRequestContext
51
52
from playwright ._impl ._frame import Frame
70
71
from playwright ._impl ._network import Request , Response , Route , serialize_headers
71
72
from playwright ._impl ._page import BindingCall , Page , Worker
72
73
from playwright ._impl ._tracing import Tracing
73
- from playwright ._impl ._wait_helper import WaitHelper
74
+ from playwright ._impl ._waiter import Waiter
74
75
from playwright ._impl ._web_error import WebError
75
76
76
77
if TYPE_CHECKING : # pragma: no cover
@@ -194,6 +195,7 @@ def __init__(
194
195
self .once (
195
196
self .Events .Close , lambda context : self ._closed_future .set_result (True )
196
197
)
198
+ self ._close_reason : Optional [str ] = None
197
199
self ._set_event_to_subscription_mapping (
198
200
{
199
201
BrowserContext .Events .Console : "console" ,
@@ -433,26 +435,27 @@ def expect_event(
433
435
) -> EventContextManagerImpl :
434
436
if timeout is None :
435
437
timeout = self ._timeout_settings .timeout ()
436
- wait_helper = WaitHelper (self , f"browser_context.expect_event({ event } )" )
437
- wait_helper .reject_on_timeout (
438
+ waiter = Waiter (self , f"browser_context.expect_event({ event } )" )
439
+ waiter .reject_on_timeout (
438
440
timeout , f'Timeout { timeout } ms exceeded while waiting for event "{ event } "'
439
441
)
440
442
if event != BrowserContext .Events .Close :
441
- wait_helper .reject_on_event (
442
- self , BrowserContext .Events .Close , Error ( "Context closed" )
443
+ waiter .reject_on_event (
444
+ self , BrowserContext .Events .Close , lambda : TargetClosedError ( )
443
445
)
444
- wait_helper .wait_for_event (self , event , predicate )
445
- return EventContextManagerImpl (wait_helper .result ())
446
+ waiter .wait_for_event (self , event , predicate )
447
+ return EventContextManagerImpl (waiter .result ())
446
448
447
449
def _on_close (self ) -> None :
448
450
if self ._browser :
449
451
self ._browser ._contexts .remove (self )
450
452
451
453
self .emit (BrowserContext .Events .Close , self )
452
454
453
- async def close (self ) -> None :
455
+ async def close (self , reason : str = None ) -> None :
454
456
if self ._close_was_called :
455
457
return
458
+ self ._close_reason = reason
456
459
self ._close_was_called = True
457
460
458
461
async def _inner_close () -> None :
@@ -479,7 +482,7 @@ async def _inner_close() -> None:
479
482
await har .delete ()
480
483
481
484
await self ._channel ._connection .wrap_api_call (_inner_close , True )
482
- await self ._channel .send ("close" )
485
+ await self ._channel .send ("close" , filter_none ({ "reason" : reason }) )
483
486
await self ._closed_future
484
487
485
488
async def storage_state (self , path : Union [str , Path ] = None ) -> StorageState :
@@ -488,6 +491,13 @@ async def storage_state(self, path: Union[str, Path] = None) -> StorageState:
488
491
await async_writefile (path , json .dumps (result ))
489
492
return result
490
493
494
+ def _effective_close_reason (self ) -> Optional [str ]:
495
+ if self ._close_reason :
496
+ return self ._close_reason
497
+ if self ._browser :
498
+ return self ._browser ._close_reason
499
+ return None
500
+
491
501
async def wait_for_event (
492
502
self , event : str , predicate : Callable = None , timeout : float = None
493
503
) -> Any :
0 commit comments