11using System . Collections . Generic ;
2- using System . Threading . Tasks ;
3- using System . Linq ;
4- using System . Diagnostics . Contracts ;
5- using PuppeteerSharp . Helpers ;
6-
2+ using System . Threading . Tasks ;
3+ using System . Linq ;
4+ using System . Diagnostics . Contracts ;
5+ using PuppeteerSharp . Helpers ;
6+
77namespace PuppeteerSharp
88{
99 internal class NavigatorWatcher
@@ -24,9 +24,14 @@ internal class NavigatorWatcher
2424 private readonly int _timeout ;
2525 private readonly string _initialLoaderId ;
2626 private Request _navigationRequest ;
27- private bool _hasSameDocumentNavigation ;
27+ private bool _hasSameDocumentNavigation ;
28+ private TaskCompletionSource < bool > _newDocumentNavigationTaskWrapper ;
29+ private TaskCompletionSource < bool > _sameDocumentNavigationTaskWrapper ;
30+ private TaskCompletionSource < bool > _terminationTaskWrapper ;
31+ private Task _timeoutTask ;
2832
2933 public NavigatorWatcher (
34+ CDPSession client ,
3035 FrameManager frameManager ,
3136 Frame mainFrame ,
3237 NetworkManager networkManager ,
@@ -58,20 +63,22 @@ public NavigatorWatcher(
5863 frameManager . FrameNavigatedWithinDocument += NavigatedWithinDocument ;
5964 frameManager . FrameDetached += CheckLifecycleComplete ;
6065 networkManager . Request += OnRequest ;
66+ Connection . FromSession ( client ) . Closed += ( sender , e )
67+ => Terminate ( new TargetClosedException ( "Navigation failed because browser has disconnected!" ) ) ;
68+
69+ _sameDocumentNavigationTaskWrapper = new TaskCompletionSource < bool > ( ) ;
70+ _newDocumentNavigationTaskWrapper = new TaskCompletionSource < bool > ( ) ;
71+ _terminationTaskWrapper = new TaskCompletionSource < bool > ( ) ;
72+ _timeoutTask = TaskHelper . CreateTimeoutTask ( timeout ) ;
73+ }
6174
62- SameDocumentNavigationTaskWrapper = new TaskCompletionSource < bool > ( ) ;
63- NewDocumentNavigationTaskWrapper = new TaskCompletionSource < bool > ( ) ;
64- TimeoutTask = TaskHelper . CreateTimeoutTask ( timeout ) ;
65- }
66-
6775 #region Properties
6876 public Task < Task > NavigationTask { get ; internal set ; }
69- public Task < bool > SameDocumentNavigationTask => SameDocumentNavigationTaskWrapper . Task ;
70- public TaskCompletionSource < bool > SameDocumentNavigationTaskWrapper { get ; }
71- public Task < bool > NewDocumentNavigationTask => NewDocumentNavigationTaskWrapper . Task ;
72- public TaskCompletionSource < bool > NewDocumentNavigationTaskWrapper { get ; }
77+ public Task < bool > SameDocumentNavigationTask => _sameDocumentNavigationTaskWrapper . Task ;
78+ public Task < bool > NewDocumentNavigationTask => _newDocumentNavigationTaskWrapper . Task ;
7379 public Response NavigationResponse => _navigationRequest ? . Response ;
74- public Task TimeoutTask { get ; }
80+ public Task < Task > TimeoutOrTerminationTask => Task . WhenAny ( _timeoutTask , _terminationTaskWrapper . Task ) ;
81+
7582 #endregion
7683
7784 #region Private methods
@@ -90,13 +97,15 @@ private void CheckLifecycleComplete(object sender, FrameEventArgs e)
9097
9198 if ( _hasSameDocumentNavigation )
9299 {
93- SameDocumentNavigationTaskWrapper . TrySetResult ( true ) ;
100+ _sameDocumentNavigationTaskWrapper . TrySetResult ( true ) ;
94101 }
95102 if ( _frame . LoaderId != _initialLoaderId )
96103 {
97- NewDocumentNavigationTaskWrapper . TrySetResult ( true ) ;
104+ _newDocumentNavigationTaskWrapper . TrySetResult ( true ) ;
98105 }
99- }
106+ }
107+
108+ private void Terminate ( PuppeteerException ex ) => _terminationTaskWrapper . TrySetException ( ex ) ;
100109
101110 private void OnRequest ( object sender , RequestEventArgs e )
102111 {
0 commit comments