How to use _checkLifecycleComplete method in Puppeteer

Best JavaScript code snippet using puppeteer

Run Puppeteer automation tests on LambdaTest cloud grid

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

LifecycleWatcher.js

Source: LifecycleWatcher.js Github

copy
1/**
2 * Copyright 2019 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {
18  helper,
19  assert
20} from './helper.js';
21import {
22  Events
23} from './Events.js';
24import {
25  TimeoutError
26} from './Errors.js';
27
28class LifecycleWatcher {
29  /**
30   * @param {!Puppeteer.FrameManager} frameManager
31   * @param {!Puppeteer.Frame} frame
32   * @param {string|!Array<string>} waitUntil
33   * @param {number} timeout
34   */
35  constructor(frameManager, frame, waitUntil, timeout) {
36    if (Array.isArray(waitUntil))
37      waitUntil = waitUntil.slice();
38    else if (typeof waitUntil === 'string')
39      waitUntil = [waitUntil];
40    this._expectedLifecycle = waitUntil.map(value => {
41      const protocolEvent = puppeteerToProtocolLifecycle[value];
42      assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value);
43      return protocolEvent;
44    });
45
46    this._frameManager = frameManager;
47    this._frame = frame;
48    this._initialLoaderId = frame._loaderId;
49    this._timeout = timeout;
50    /** @type {?Puppeteer.Request} */
51    this._navigationRequest = null;
52    this._eventListeners = [
53      helper.addEventListener(frameManager._client, Events.CDPSession.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))),
54      helper.addEventListener(this._frameManager, Events.FrameManager.LifecycleEvent, this._checkLifecycleComplete.bind(this)),
55      helper.addEventListener(this._frameManager, Events.FrameManager.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)),
56      helper.addEventListener(this._frameManager, Events.FrameManager.FrameDetached, this._onFrameDetached.bind(this)),
57      helper.addEventListener(this._frameManager.networkManager(), Events.NetworkManager.Request, this._onRequest.bind(this)),
58    ];
59
60    this._sameDocumentNavigationPromise = new Promise(fulfill => {
61      this._sameDocumentNavigationCompleteCallback = fulfill;
62    });
63
64    this._lifecyclePromise = new Promise(fulfill => {
65      this._lifecycleCallback = fulfill;
66    });
67
68    this._newDocumentNavigationPromise = new Promise(fulfill => {
69      this._newDocumentNavigationCompleteCallback = fulfill;
70    });
71
72    this._timeoutPromise = this._createTimeoutPromise();
73    this._terminationPromise = new Promise(fulfill => {
74      this._terminationCallback = fulfill;
75    });
76    this._checkLifecycleComplete();
77  }
78
79  /**
80   * @param {!Puppeteer.Request} request
81   */
82  _onRequest(request) {
83    if (request.frame() !== this._frame || !request.isNavigationRequest())
84      return;
85    this._navigationRequest = request;
86  }
87
88  /**
89   * @param {!Puppeteer.Frame} frame
90   */
91  _onFrameDetached(frame) {
92    if (this._frame === frame) {
93      this._terminationCallback.call(null, new Error('Navigating frame was detached'));
94      return;
95    }
96    this._checkLifecycleComplete();
97  }
98
99  /**
100   * @return {?Puppeteer.Response}
101   */
102  navigationResponse() {
103    return this._navigationRequest ? this._navigationRequest.response() : null;
104  }
105
106  /**
107   * @param {!Error} error
108   */
109  _terminate(error) {
110    this._terminationCallback.call(null, error);
111  }
112
113  /**
114   * @return {!Promise<?Error>}
115   */
116  sameDocumentNavigationPromise() {
117    return this._sameDocumentNavigationPromise;
118  }
119
120  /**
121   * @return {!Promise<?Error>}
122   */
123  newDocumentNavigationPromise() {
124    return this._newDocumentNavigationPromise;
125  }
126
127  /**
128   * @return {!Promise}
129   */
130  lifecyclePromise() {
131    return this._lifecyclePromise;
132  }
133
134  /**
135   * @return {!Promise<?Error>}
136   */
137  timeoutOrTerminationPromise() {
138    return Promise.race([this._timeoutPromise, this._terminationPromise]);
139  }
140
141  /**
142   * @return {!Promise<?Error>}
143   */
144  _createTimeoutPromise() {
145    if (!this._timeout)
146      return new Promise(() => {});
147    const errorMessage = 'Navigation Timeout Exceeded: ' + this._timeout + 'ms exceeded';
148    return new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._timeout))
149      .then(() => new TimeoutError(errorMessage));
150  }
151
152  /**
153   * @param {!Puppeteer.Frame} frame
154   */
155  _navigatedWithinDocument(frame) {
156    if (frame !== this._frame)
157      return;
158    this._hasSameDocumentNavigation = true;
159    this._checkLifecycleComplete();
160  }
161
162  _checkLifecycleComplete() {
163    // We expect navigation to commit.
164    if (!checkLifecycle(this._frame, this._expectedLifecycle))
165      return;
166    this._lifecycleCallback();
167    if (this._frame._loaderId === this._initialLoaderId && !this._hasSameDocumentNavigation)
168      return;
169    if (this._hasSameDocumentNavigation)
170      this._sameDocumentNavigationCompleteCallback();
171    if (this._frame._loaderId !== this._initialLoaderId)
172      this._newDocumentNavigationCompleteCallback();
173
174    /**
175     * @param {!Puppeteer.Frame} frame
176     * @param {!Array<string>} expectedLifecycle
177     * @return {boolean}
178     */
179    function checkLifecycle(frame, expectedLifecycle) {
180      for (const event of expectedLifecycle) {
181        if (!frame._lifecycleEvents.has(event))
182          return false;
183      }
184      for (const child of frame.childFrames()) {
185        if (!checkLifecycle(child, expectedLifecycle))
186          return false;
187      }
188      return true;
189    }
190  }
191
192  dispose() {
193    helper.removeEventListeners(this._eventListeners);
194    clearTimeout(this._maximumTimer);
195  }
196}
197
198const puppeteerToProtocolLifecycle = {
199  'load': 'load',
200  'domcontentloaded': 'DOMContentLoaded',
201  'networkidle0': 'networkIdle',
202  'networkidle2': 'networkAlmostIdle',
203};
204
205export {
206  LifecycleWatcher
207};
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

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Puppeteer 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)