How to use OnRequest method of PuppeteerSharp.LifecycleWatcher class

Best Puppeteer-sharp code snippet using PuppeteerSharp.LifecycleWatcher.OnRequest

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

LifecycleWatcher.cs

Source: LifecycleWatcher.cs Github

copy
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
4using System.Linq;
5using System.Diagnostics.Contracts;
6using PuppeteerSharp.Helpers;
7
8namespace PuppeteerSharp
9{
10    internal class LifecycleWatcher : IDisposable
11    {
12        private static readonly Dictionary<WaitUntilNavigation, string> _puppeteerToProtocolLifecycle =
13            new Dictionary<WaitUntilNavigation, string>
14            {
15                [WaitUntilNavigation.Load] = "load",
16                [WaitUntilNavigation.DOMContentLoaded] = "DOMContentLoaded",
17                [WaitUntilNavigation.Networkidle0] = "networkIdle",
18                [WaitUntilNavigation.Networkidle2] = "networkAlmostIdle"
19            };
20
21        private static readonly WaitUntilNavigation[] _defaultWaitUntil = { WaitUntilNavigation.Load };
22
23        private readonly FrameManager _frameManager;
24        private readonly Frame _frame;
25        private readonly IEnumerable<string> _expectedLifecycle;
26        private readonly int _timeout;
27        private readonly string _initialLoaderId;
28        private Request _navigationRequest;
29        private bool _hasSameDocumentNavigation;
30        private TaskCompletionSource<bool> _newDocumentNavigationTaskWrapper;
31        private TaskCompletionSource<bool> _sameDocumentNavigationTaskWrapper;
32        private TaskCompletionSource<bool> _lifecycleTaskWrapper;
33        private TaskCompletionSource<bool> _terminationTaskWrapper;
34
35        public LifecycleWatcher(
36            FrameManager frameManager,
37            Frame frame,
38            WaitUntilNavigation[] waitUntil,
39            int timeout)
40        {
41            _expectedLifecycle = (waitUntil ?? _defaultWaitUntil).Select(w =>
42            {
43                var protocolEvent = _puppeteerToProtocolLifecycle.GetValueOrDefault(w);
44                Contract.Assert(protocolEvent != null, $"Unknown value for options.waitUntil: {w}");
45                return protocolEvent;
46            });
47
48            _frameManager = frameManager;
49            _frame = frame;
50            _initialLoaderId = frame.LoaderId;
51            _timeout = timeout;
52            _hasSameDocumentNavigation = false;
53
54            _sameDocumentNavigationTaskWrapper = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
55            _newDocumentNavigationTaskWrapper = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
56            _lifecycleTaskWrapper = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
57            _terminationTaskWrapper = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
58
59            frameManager.LifecycleEvent += FrameManager_LifecycleEvent;
60            frameManager.FrameNavigatedWithinDocument += NavigatedWithinDocument;
61            frameManager.FrameDetached += OnFrameDetached;
62            frameManager.NetworkManager.Request += OnRequest;
63            frameManager.Client.Disconnected += OnClientDisconnected;
64
65            CheckLifecycleComplete();
66        }
67
68        #region Properties
69        public Task<Task> NavigationTask { get; internal set; }
70        public Task<bool> SameDocumentNavigationTask => _sameDocumentNavigationTaskWrapper.Task;
71        public Task<bool> NewDocumentNavigationTask => _newDocumentNavigationTaskWrapper.Task;
72        public Response NavigationResponse => _navigationRequest?.Response;
73        public Task TimeoutOrTerminationTask
74            => _terminationTaskWrapper.Task.WithTimeout(_timeout);
75        public Task LifecycleTask => _lifecycleTaskWrapper.Task;
76
77        #endregion
78
79        #region Private methods
80
81        private void OnClientDisconnected(object sender, EventArgs e)
82            => Terminate(new TargetClosedException("Navigation failed because browser has disconnected!", _frameManager.Client.CloseReason));
83
84        void FrameManager_LifecycleEvent(object sender, FrameEventArgs e) => CheckLifecycleComplete();
85
86        private void OnFrameDetached(object sender, FrameEventArgs e)
87        {
88            var frame = e.Frame;
89            if (_frame == frame)
90            {
91                Terminate(new PuppeteerException("Navigating frame was detached"));
92                return;
93            }
94            CheckLifecycleComplete();
95        }
96
97        private void CheckLifecycleComplete()
98        {
99            // We expect navigation to commit.
100            if (!CheckLifecycle(_frame, _expectedLifecycle))
101            {
102                return;
103            }
104            _lifecycleTaskWrapper.TrySetResult(true);
105            if (_frame.LoaderId == _initialLoaderId && !_hasSameDocumentNavigation)
106            {
107                return;
108            }
109
110            if (_hasSameDocumentNavigation)
111            {
112                _sameDocumentNavigationTaskWrapper.TrySetResult(true);
113            }
114            if (_frame.LoaderId != _initialLoaderId)
115            {
116                _newDocumentNavigationTaskWrapper.TrySetResult(true);
117            }
118        }
119
120        private void Terminate(PuppeteerException ex) => _terminationTaskWrapper.TrySetException(ex);
121
122        private void OnRequest(object sender, RequestEventArgs e)
123        {
124            if (e.Request.Frame != _frame || !e.Request.IsNavigationRequest)
125            {
126                return;
127            }
128            _navigationRequest = e.Request;
129        }
130
131        private void NavigatedWithinDocument(object sender, FrameEventArgs e)
132        {
133            if (e.Frame != _frame)
134            {
135                return;
136            }
137            _hasSameDocumentNavigation = true;
138            CheckLifecycleComplete();
139        }
140
141        private bool CheckLifecycle(Frame frame, IEnumerable<string> expectedLifecycle)
142        {
143            foreach (var item in expectedLifecycle)
144            {
145                if (!frame.LifecycleEvents.Contains(item))
146                {
147                    return false;
148                }
149            }
150            foreach (var child in frame.ChildFrames)
151            {
152                if (!CheckLifecycle(child, expectedLifecycle))
153                {
154                    return false;
155                }
156            }
157            return true;
158        }
159
160        public void Dispose() => Dispose(true);
161
162        ~LifecycleWatcher() => Dispose(false);
163
164        public void Dispose(bool disposing)
165        {
166            _frameManager.LifecycleEvent -= FrameManager_LifecycleEvent;
167            _frameManager.FrameNavigatedWithinDocument -= NavigatedWithinDocument;
168            _frameManager.FrameDetached -= OnFrameDetached;
169            _frameManager.NetworkManager.Request -= OnRequest;
170            _frameManager.Client.Disconnected -= OnClientDisconnected;
171        }
172
173        #endregion
174    }
175}
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger OnRequest code on LambdaTest Cloud Grid

Execute automation tests with OnRequest on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)