Best JavaScript code snippet using puppeteer
crPage.js
Source:crPage.js
...305 throw e;306 });307 parent = frame.parentFrame();308 if (!parent) throw new Error('Frame has been detached.');309 return parentSession._adoptBackendNodeId(backendNodeId, await parent._mainContext());310 }311}312exports.CRPage = CRPage;313class FrameSession {314 // Marks the oopif session that remote -> local transition has happened in the parent.315 // See Target.detachedFromTarget handler for details.316 constructor(crPage, client, targetId, parentSession) {317 this._client = void 0;318 this._crPage = void 0;319 this._page = void 0;320 this._networkManager = void 0;321 this._contextIdToContext = new Map();322 this._eventListeners = [];323 this._targetId = void 0;324 this._firstNonInitialNavigationCommittedPromise = void 0;325 this._firstNonInitialNavigationCommittedFulfill = () => {};326 this._firstNonInitialNavigationCommittedReject = e => {};327 this._windowId = void 0;328 this._swappedIn = false;329 this._videoRecorder = null;330 this._screencastId = null;331 this._screencastClients = new Set();332 this._client = client;333 this._crPage = crPage;334 this._page = crPage._page;335 this._targetId = targetId;336 this._networkManager = new _crNetworkManager.CRNetworkManager(client, this._page, parentSession ? parentSession._networkManager : null);337 this._firstNonInitialNavigationCommittedPromise = new Promise((f, r) => {338 this._firstNonInitialNavigationCommittedFulfill = f;339 this._firstNonInitialNavigationCommittedReject = r;340 });341 client.once(_crConnection.CRSessionEvents.Disconnected, () => {342 this._firstNonInitialNavigationCommittedReject(new Error('Page closed'));343 });344 }345 _isMainFrame() {346 return this._targetId === this._crPage._targetId;347 }348 _addRendererListeners() {349 this._eventListeners.push(...[_eventsHelper.eventsHelper.addEventListener(this._client, 'Log.entryAdded', event => this._onLogEntryAdded(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.fileChooserOpened', event => this._onFileChooserOpened(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameDetached', event => this._onFrameDetached(event.frameId, event.reason)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameNavigated', event => this._onFrameNavigated(event.frame, false)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameRequestedNavigation', event => this._onFrameRequestedNavigation(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.javascriptDialogOpening', event => this._onDialog(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.bindingCalled', event => this._onBindingCalled(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.consoleAPICalled', event => this._onConsoleAPI(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextDestroyed', event => this._onExecutionContextDestroyed(event.executionContextId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextsCleared', event => this._onExecutionContextsCleared()), _eventsHelper.eventsHelper.addEventListener(this._client, 'Target.attachedToTarget', event => this._onAttachedToTarget(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Target.detachedFromTarget', event => this._onDetachedFromTarget(event))]);350 }351 _addBrowserListeners() {352 this._eventListeners.push(...[_eventsHelper.eventsHelper.addEventListener(this._client, 'Inspector.targetCrashed', event => this._onTargetCrashed()), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.screencastFrame', event => this._onScreencastFrame(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.windowOpen', event => this._onWindowOpen(event))]);353 }354 async _initialize(hasUIWindow) {355 if (hasUIWindow && !this._crPage._browserContext._browser.isClank() && !this._crPage._browserContext._options.noDefaultViewport) {356 const {357 windowId358 } = await this._client.send('Browser.getWindowForTarget');359 this._windowId = windowId;360 }361 let screencastOptions;362 if (this._isMainFrame() && this._crPage._browserContext._options.recordVideo && hasUIWindow) {363 const screencastId = (0, _utils.createGuid)();364 const outputFile = _path.default.join(this._crPage._browserContext._options.recordVideo.dir, screencastId + '.webm');365 screencastOptions = { // validateBrowserContextOptions ensures correct video size.366 ...this._crPage._browserContext._options.recordVideo.size,367 outputFile368 };369 await this._crPage._browserContext._ensureVideosPath(); // Note: it is important to start video recorder before sending Page.startScreencast,370 // and it is equally important to send Page.startScreencast before sending Runtime.runIfWaitingForDebugger.371 await this._createVideoRecorder(screencastId, screencastOptions);372 this._crPage.pageOrError().then(p => {373 if (p instanceof Error) this._stopVideoRecording().catch(() => {});374 });375 }376 let lifecycleEventsEnabled;377 if (!this._isMainFrame()) this._addRendererListeners();378 this._addBrowserListeners();379 const promises = [this._client.send('Page.enable'), this._client.send('Page.getFrameTree').then(({380 frameTree381 }) => {382 if (this._isMainFrame()) {383 this._handleFrameTree(frameTree);384 this._addRendererListeners();385 }386 const localFrames = this._isMainFrame() ? this._page.frames() : [this._page._frameManager.frame(this._targetId)];387 for (const frame of localFrames) {388 // Note: frames might be removed before we send these.389 this._client._sendMayFail('Page.createIsolatedWorld', {390 frameId: frame._id,391 grantUniveralAccess: true,392 worldName: UTILITY_WORLD_NAME393 });394 for (const binding of this._crPage._browserContext._pageBindings.values()) frame.evaluateExpression(binding.source, false, undefined).catch(e => {});395 for (const source of this._crPage._browserContext._evaluateOnNewDocumentSources) frame.evaluateExpression(source, false, undefined, 'main').catch(e => {});396 }397 const isInitialEmptyPage = this._isMainFrame() && this._page.mainFrame().url() === ':';398 if (isInitialEmptyPage) {399 // Ignore lifecycle events for the initial empty page. It is never the final page400 // hence we are going to get more lifecycle updates after the actual navigation has401 // started (even if the target url is about:blank).402 lifecycleEventsEnabled.catch(e => {}).then(() => {403 this._eventListeners.push(_eventsHelper.eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event)));404 });405 } else {406 this._firstNonInitialNavigationCommittedFulfill();407 this._eventListeners.push(_eventsHelper.eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event)));408 }409 }), this._client.send('Log.enable', {}), lifecycleEventsEnabled = this._client.send('Page.setLifecycleEventsEnabled', {410 enabled: true411 }), this._client.send('Runtime.enable', {}), this._client.send('Page.addScriptToEvaluateOnNewDocument', {412 source: '',413 worldName: UTILITY_WORLD_NAME414 }), this._networkManager.initialize(), this._client.send('Target.setAutoAttach', {415 autoAttach: true,416 waitForDebuggerOnStart: true,417 flatten: true418 })];419 if (this._isMainFrame()) promises.push(this._client.send('Emulation.setFocusEmulationEnabled', {420 enabled: true421 }));422 const options = this._crPage._browserContext._options;423 if (options.bypassCSP) promises.push(this._client.send('Page.setBypassCSP', {424 enabled: true425 }));426 if (options.ignoreHTTPSErrors) promises.push(this._client.send('Security.setIgnoreCertificateErrors', {427 ignore: true428 }));429 if (this._isMainFrame()) promises.push(this._updateViewport());430 if (options.hasTouch) promises.push(this._client.send('Emulation.setTouchEmulationEnabled', {431 enabled: true432 }));433 if (options.javaScriptEnabled === false) promises.push(this._client.send('Emulation.setScriptExecutionDisabled', {434 value: true435 }));436 if (options.userAgent || options.locale) promises.push(this._client.send('Emulation.setUserAgentOverride', {437 userAgent: options.userAgent || '',438 acceptLanguage: options.locale439 }));440 if (options.locale) promises.push(emulateLocale(this._client, options.locale));441 if (options.timezoneId) promises.push(emulateTimezone(this._client, options.timezoneId));442 if (!this._crPage._browserContext._browser.options.headful) promises.push(this._setDefaultFontFamilies(this._client));443 promises.push(this._updateGeolocation(true));444 promises.push(this._updateExtraHTTPHeaders(true));445 promises.push(this._updateRequestInterception());446 promises.push(this._updateOffline(true));447 promises.push(this._updateHttpCredentials(true));448 promises.push(this._updateEmulateMedia(true));449 for (const binding of this._crPage._page.allBindings()) promises.push(this._initBinding(binding));450 for (const source of this._crPage._browserContext._evaluateOnNewDocumentSources) promises.push(this._evaluateOnNewDocument(source, 'main'));451 for (const source of this._crPage._page._evaluateOnNewDocumentSources) promises.push(this._evaluateOnNewDocument(source, 'main'));452 if (screencastOptions) promises.push(this._startVideoRecording(screencastOptions));453 promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));454 promises.push(this._firstNonInitialNavigationCommittedPromise);455 await Promise.all(promises);456 }457 dispose() {458 _eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);459 this._networkManager.dispose();460 this._crPage._sessions.delete(this._targetId);461 }462 async _navigate(frame, url, referrer) {463 const response = await this._client.send('Page.navigate', {464 url,465 referrer,466 frameId: frame._id467 });468 if (response.errorText) throw new Error(`${response.errorText} at ${url}`);469 return {470 newDocumentId: response.loaderId471 };472 }473 _onLifecycleEvent(event) {474 if (this._eventBelongsToStaleFrame(event.frameId)) return;475 if (event.name === 'load') this._page._frameManager.frameLifecycleEvent(event.frameId, 'load');else if (event.name === 'DOMContentLoaded') this._page._frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded');476 }477 _onFrameStoppedLoading(frameId) {478 if (this._eventBelongsToStaleFrame(frameId)) return;479 this._page._frameManager.frameStoppedLoading(frameId);480 }481 _handleFrameTree(frameTree) {482 this._onFrameAttached(frameTree.frame.id, frameTree.frame.parentId || null);483 this._onFrameNavigated(frameTree.frame, true);484 if (!frameTree.childFrames) return;485 for (const child of frameTree.childFrames) this._handleFrameTree(child);486 }487 _eventBelongsToStaleFrame(frameId) {488 const frame = this._page._frameManager.frame(frameId); // Subtree may be already gone because some ancestor navigation destroyed the oopif.489 if (!frame) return true; // When frame goes remote, parent process may still send some events490 // related to the local frame before it sends frameDetached.491 // In this case, we already have a new session for this frame, so events492 // in the old session should be ignored.493 const session = this._crPage._sessionForFrame(frame);494 return session && session !== this && !session._swappedIn;495 }496 _onFrameAttached(frameId, parentFrameId) {497 const frameSession = this._crPage._sessions.get(frameId);498 if (frameSession && frameId !== this._targetId) {499 // This is a remote -> local frame transition.500 frameSession._swappedIn = true;501 const frame = this._page._frameManager.frame(frameId); // Frame or even a whole subtree may be already gone, because some ancestor did navigate.502 if (frame) this._page._frameManager.removeChildFramesRecursively(frame);503 return;504 }505 if (parentFrameId && !this._page._frameManager.frame(parentFrameId)) {506 // Parent frame may be gone already because some ancestor frame navigated and507 // destroyed the whole subtree of some oopif, while oopif's process is still sending us events.508 // Be careful to not confuse this with "main frame navigated cross-process" scenario509 // where parentFrameId is null.510 return;511 }512 this._page._frameManager.frameAttached(frameId, parentFrameId);513 }514 _onFrameNavigated(framePayload, initial) {515 if (this._eventBelongsToStaleFrame(framePayload.id)) return;516 this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url + (framePayload.urlFragment || ''), framePayload.name || '', framePayload.loaderId, initial);517 if (!initial) this._firstNonInitialNavigationCommittedFulfill();518 }519 _onFrameRequestedNavigation(payload) {520 if (this._eventBelongsToStaleFrame(payload.frameId)) return;521 if (payload.disposition === 'currentTab') this._page._frameManager.frameRequestedNavigation(payload.frameId);522 }523 _onFrameNavigatedWithinDocument(frameId, url) {524 if (this._eventBelongsToStaleFrame(frameId)) return;525 this._page._frameManager.frameCommittedSameDocumentNavigation(frameId, url);526 }527 _onFrameDetached(frameId, reason) {528 if (this._crPage._sessions.has(frameId)) {529 // This is a local -> remote frame transtion, where530 // Page.frameDetached arrives after Target.attachedToTarget.531 // We've already handled the new target and frame reattach - nothing to do here.532 return;533 }534 if (reason === 'swap') {535 // This is a local -> remote frame transtion, where536 // Page.frameDetached arrives before Target.attachedToTarget.537 // We should keep the frame in the tree, and it will be used for the new target.538 const frame = this._page._frameManager.frame(frameId);539 if (frame) this._page._frameManager.removeChildFramesRecursively(frame);540 return;541 } // Just a regular frame detach.542 this._page._frameManager.frameDetached(frameId);543 }544 _onExecutionContextCreated(contextPayload) {545 const frame = contextPayload.auxData ? this._page._frameManager.frame(contextPayload.auxData.frameId) : null;546 if (!frame || this._eventBelongsToStaleFrame(frame._id)) return;547 const delegate = new _crExecutionContext.CRExecutionContext(this._client, contextPayload);548 let worldName = null;549 if (contextPayload.auxData && !!contextPayload.auxData.isDefault) worldName = 'main';else if (contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';550 const context = new dom.FrameExecutionContext(delegate, frame, worldName);551 context[contextDelegateSymbol] = delegate;552 if (worldName) frame._contextCreated(worldName, context);553 this._contextIdToContext.set(contextPayload.id, context);554 }555 _onExecutionContextDestroyed(executionContextId) {556 const context = this._contextIdToContext.get(executionContextId);557 if (!context) return;558 this._contextIdToContext.delete(executionContextId);559 context.frame._contextDestroyed(context);560 }561 _onExecutionContextsCleared() {562 for (const contextId of Array.from(this._contextIdToContext.keys())) this._onExecutionContextDestroyed(contextId);563 }564 _onAttachedToTarget(event) {565 const session = _crConnection.CRConnection.fromSession(this._client).session(event.sessionId);566 if (event.targetInfo.type === 'iframe') {567 // Frame id equals target id.568 const targetId = event.targetInfo.targetId;569 const frame = this._page._frameManager.frame(targetId);570 if (!frame) return; // Subtree may be already gone due to renderer/browser race.571 this._page._frameManager.removeChildFramesRecursively(frame);572 const frameSession = new FrameSession(this._crPage, session, targetId, this);573 this._crPage._sessions.set(targetId, frameSession);574 frameSession._initialize(false).catch(e => e);575 return;576 }577 if (event.targetInfo.type !== 'worker') {578 // Ideally, detaching should resume any target, but there is a bug in the backend.579 session._sendMayFail('Runtime.runIfWaitingForDebugger').then(() => {580 this._client._sendMayFail('Target.detachFromTarget', {581 sessionId: event.sessionId582 });583 });584 return;585 }586 const url = event.targetInfo.url;587 const worker = new _page.Worker(this._page, url);588 this._page._addWorker(event.sessionId, worker);589 session.once('Runtime.executionContextCreated', async event => {590 worker._createExecutionContext(new _crExecutionContext.CRExecutionContext(session, event.context));591 }); // This might fail if the target is closed before we initialize.592 session._sendMayFail('Runtime.enable');593 session._sendMayFail('Network.enable');594 session._sendMayFail('Runtime.runIfWaitingForDebugger');595 session.on('Runtime.consoleAPICalled', event => {596 const args = event.args.map(o => worker._existingExecutionContext.createHandle(o));597 this._page._addConsoleMessage(event.type, args, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));598 });599 session.on('Runtime.exceptionThrown', exception => this._page.emit(_page.Page.Events.PageError, (0, _crProtocolHelper.exceptionToError)(exception.exceptionDetails))); // TODO: attribute workers to the right frame.600 this._networkManager.instrumentNetworkEvents(session, this._page._frameManager.frame(this._targetId));601 }602 _onDetachedFromTarget(event) {603 // This might be a worker...604 this._page._removeWorker(event.sessionId); // ... or an oopif.605 const childFrameSession = this._crPage._sessions.get(event.targetId);606 if (!childFrameSession) return; // Usually, we get frameAttached in this session first and mark child as swappedIn.607 if (childFrameSession._swappedIn) {608 childFrameSession.dispose();609 return;610 } // However, sometimes we get detachedFromTarget before frameAttached.611 // In this case we don't know wheter this is a remote frame detach,612 // or just a remote -> local transition. In the latter case, frameAttached613 // is already inflight, so let's make a safe roundtrip to ensure it arrives.614 this._client.send('Page.enable').catch(e => null).then(() => {615 // Child was not swapped in - that means frameAttached did not happen and616 // this is remote detach rather than remote -> local swap.617 if (!childFrameSession._swappedIn) this._page._frameManager.frameDetached(event.targetId);618 childFrameSession.dispose();619 });620 }621 _onWindowOpen(event) {622 this._crPage._nextWindowOpenPopupFeatures.push(event.windowFeatures);623 }624 async _onConsoleAPI(event) {625 if (event.executionContextId === 0) {626 // DevTools protocol stores the last 1000 console messages. These627 // messages are always reported even for removed execution contexts. In628 // this case, they are marked with executionContextId = 0 and are629 // reported upon enabling Runtime agent.630 //631 // Ignore these messages since:632 // - there's no execution context we can use to operate with message633 // arguments634 // - these messages are reported before Playwright clients can subscribe635 // to the 'console'636 // page event.637 //638 // @see https://github.com/GoogleChrome/puppeteer/issues/3865639 return;640 }641 const context = this._contextIdToContext.get(event.executionContextId);642 if (!context) return;643 const values = event.args.map(arg => context.createHandle(arg));644 this._page._addConsoleMessage(event.type, values, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));645 }646 async _initBinding(binding) {647 await Promise.all([this._client.send('Runtime.addBinding', {648 name: binding.name649 }), this._client.send('Page.addScriptToEvaluateOnNewDocument', {650 source: binding.source651 })]);652 }653 async _onBindingCalled(event) {654 const pageOrError = await this._crPage.pageOrError();655 if (!(pageOrError instanceof Error)) {656 const context = this._contextIdToContext.get(event.executionContextId);657 if (context) await this._page._onBindingCalled(event.payload, context);658 }659 }660 _onDialog(event) {661 if (!this._page._frameManager.frame(this._targetId)) return; // Our frame/subtree may be gone already.662 this._page.emit(_page.Page.Events.Dialog, new dialog.Dialog(this._page, event.type, event.message, async (accept, promptText) => {663 await this._client.send('Page.handleJavaScriptDialog', {664 accept,665 promptText666 });667 }, event.defaultPrompt));668 }669 _handleException(exceptionDetails) {670 this._page.firePageError((0, _crProtocolHelper.exceptionToError)(exceptionDetails));671 }672 async _onTargetCrashed() {673 this._client._markAsCrashed();674 this._page._didCrash();675 }676 _onLogEntryAdded(event) {677 const {678 level,679 text,680 args,681 source,682 url,683 lineNumber684 } = event.entry;685 if (args) args.map(arg => (0, _crProtocolHelper.releaseObject)(this._client, arg.objectId));686 if (source !== 'worker') {687 const location = {688 url: url || '',689 lineNumber: lineNumber || 0,690 columnNumber: 0691 };692 this._page._addConsoleMessage(level, [], location, text);693 }694 }695 async _onFileChooserOpened(event) {696 const frame = this._page._frameManager.frame(event.frameId);697 if (!frame) return;698 let handle;699 try {700 const utilityContext = await frame._utilityContext();701 handle = await this._adoptBackendNodeId(event.backendNodeId, utilityContext);702 } catch (e) {703 // During async processing, frame/context may go away. We should not throw.704 return;705 }706 await this._page._onFileChooserOpened(handle);707 }708 _willBeginDownload() {709 const originPage = this._crPage._initializedPage;710 if (!originPage) {711 // Resume the page creation with an error. The page will automatically close right712 // after the download begins.713 this._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));714 }715 }716 _onScreencastFrame(payload) {717 this._page.throttleScreencastFrameAck(() => {718 this._client.send('Page.screencastFrameAck', {719 sessionId: payload.sessionId720 }).catch(() => {});721 });722 const buffer = Buffer.from(payload.data, 'base64');723 this._page.emit(_page.Page.Events.ScreencastFrame, {724 buffer,725 timestamp: payload.metadata.timestamp,726 width: payload.metadata.deviceWidth,727 height: payload.metadata.deviceHeight728 });729 }730 async _createVideoRecorder(screencastId, options) {731 (0, _utils.assert)(!this._screencastId);732 const ffmpegPath = _registry.registry.findExecutable('ffmpeg').executablePathOrDie(this._page._browserContext._browser.options.sdkLanguage);733 this._videoRecorder = await _videoRecorder.VideoRecorder.launch(this._crPage._page, ffmpegPath, options);734 this._screencastId = screencastId;735 }736 async _startVideoRecording(options) {737 const screencastId = this._screencastId;738 (0, _utils.assert)(screencastId);739 this._page.once(_page.Page.Events.Close, () => this._stopVideoRecording().catch(() => {}));740 const gotFirstFrame = new Promise(f => this._client.once('Page.screencastFrame', f));741 await this._startScreencast(this._videoRecorder, {742 format: 'jpeg',743 quality: 90,744 maxWidth: options.width,745 maxHeight: options.height746 }); // Wait for the first frame before reporting video to the client.747 gotFirstFrame.then(() => {748 this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage.pageOrError());749 });750 }751 async _stopVideoRecording() {752 if (!this._screencastId) return;753 const screencastId = this._screencastId;754 this._screencastId = null;755 const recorder = this._videoRecorder;756 this._videoRecorder = null;757 await this._stopScreencast(recorder);758 await recorder.stop().catch(() => {}); // Keep the video artifact in the map utntil encoding is fully finished, if the context759 // starts closing before the video is fully written to disk it will wait for it.760 const video = this._crPage._browserContext._browser._takeVideo(screencastId);761 video === null || video === void 0 ? void 0 : video.reportFinished();762 }763 async _startScreencast(client, options = {}) {764 this._screencastClients.add(client);765 if (this._screencastClients.size === 1) await this._client.send('Page.startScreencast', options);766 }767 async _stopScreencast(client) {768 this._screencastClients.delete(client);769 if (!this._screencastClients.size) await this._client._sendMayFail('Page.stopScreencast');770 }771 async _updateExtraHTTPHeaders(initial) {772 const headers = network.mergeHeaders([this._crPage._browserContext._options.extraHTTPHeaders, this._page._state.extraHTTPHeaders]);773 if (!initial || headers.length) await this._client.send('Network.setExtraHTTPHeaders', {774 headers: (0, _utils.headersArrayToObject)(headers, false775 /* lowerCase */776 )777 });778 }779 async _updateGeolocation(initial) {780 const geolocation = this._crPage._browserContext._options.geolocation;781 if (!initial || geolocation) await this._client.send('Emulation.setGeolocationOverride', geolocation || {});782 }783 async _updateOffline(initial) {784 const offline = !!this._crPage._browserContext._options.offline;785 if (!initial || offline) await this._networkManager.setOffline(offline);786 }787 async _updateHttpCredentials(initial) {788 const credentials = this._crPage._browserContext._options.httpCredentials || null;789 if (!initial || credentials) await this._networkManager.authenticate(credentials);790 }791 async _updateViewport() {792 if (this._crPage._browserContext._browser.isClank()) return;793 (0, _utils.assert)(this._isMainFrame());794 const options = this._crPage._browserContext._options;795 const emulatedSize = this._page._state.emulatedSize;796 if (emulatedSize === null) return;797 const viewportSize = emulatedSize.viewport;798 const screenSize = emulatedSize.screen;799 const isLandscape = viewportSize.width > viewportSize.height;800 const promises = [this._client.send('Emulation.setDeviceMetricsOverride', {801 mobile: !!options.isMobile,802 width: viewportSize.width,803 height: viewportSize.height,804 screenWidth: screenSize.width,805 screenHeight: screenSize.height,806 deviceScaleFactor: options.deviceScaleFactor || 1,807 screenOrientation: isLandscape ? {808 angle: 90,809 type: 'landscapePrimary'810 } : {811 angle: 0,812 type: 'portraitPrimary'813 }814 })];815 if (this._windowId) {816 let insets = {817 width: 0,818 height: 0819 };820 if (this._crPage._browserContext._browser.options.headful) {821 // TODO: popup windows have their own insets.822 insets = {823 width: 24,824 height: 88825 };826 if (process.platform === 'win32') insets = {827 width: 16,828 height: 88829 };else if (process.platform === 'linux') insets = {830 width: 8,831 height: 85832 };else if (process.platform === 'darwin') insets = {833 width: 2,834 height: 80835 };836 if (this._crPage._browserContext.isPersistentContext()) {837 // FIXME: Chrome bug: OOPIF router is confused when hit target is838 // outside browser window.839 // Account for the infobar here to work around the bug.840 insets.height += 46;841 }842 }843 promises.push(this.setWindowBounds({844 width: viewportSize.width + insets.width,845 height: viewportSize.height + insets.height846 }));847 }848 await Promise.all(promises);849 }850 async windowBounds() {851 const {852 bounds853 } = await this._client.send('Browser.getWindowBounds', {854 windowId: this._windowId855 });856 return bounds;857 }858 async setWindowBounds(bounds) {859 return await this._client.send('Browser.setWindowBounds', {860 windowId: this._windowId,861 bounds862 });863 }864 async _updateEmulateMedia(initial) {865 const colorScheme = this._page._state.colorScheme === null ? '' : this._page._state.colorScheme;866 const reducedMotion = this._page._state.reducedMotion === null ? '' : this._page._state.reducedMotion;867 const forcedColors = this._page._state.forcedColors === null ? '' : this._page._state.forcedColors;868 const features = [{869 name: 'prefers-color-scheme',870 value: colorScheme871 }, {872 name: 'prefers-reduced-motion',873 value: reducedMotion874 }, {875 name: 'forced-colors',876 value: forcedColors877 }]; // Empty string disables the override.878 await this._client.send('Emulation.setEmulatedMedia', {879 media: this._page._state.mediaType || '',880 features881 });882 }883 async _setDefaultFontFamilies(session) {884 const fontFamilies = _defaultFontFamilies.platformToFontFamilies[this._crPage._browserContext._browser._platform()];885 await session.send('Page.setFontFamilies', fontFamilies);886 }887 async _updateRequestInterception() {888 await this._networkManager.setRequestInterception(this._page._needsRequestInterception());889 }890 async _setFileChooserIntercepted(enabled) {891 await this._client.send('Page.setInterceptFileChooserDialog', {892 enabled893 }).catch(e => {}); // target can be closed.894 }895 async _evaluateOnNewDocument(source, world) {896 const worldName = world === 'utility' ? UTILITY_WORLD_NAME : undefined;897 await this._client.send('Page.addScriptToEvaluateOnNewDocument', {898 source,899 worldName900 });901 }902 async _getContentFrame(handle) {903 const nodeInfo = await this._client.send('DOM.describeNode', {904 objectId: handle._objectId905 });906 if (!nodeInfo || typeof nodeInfo.node.frameId !== 'string') return null;907 return this._page._frameManager.frame(nodeInfo.node.frameId);908 }909 async _getOwnerFrame(handle) {910 // document.documentElement has frameId of the owner frame.911 const documentElement = await handle.evaluateHandle(node => {912 const doc = node;913 if (doc.documentElement && doc.documentElement.ownerDocument === doc) return doc.documentElement;914 return node.ownerDocument ? node.ownerDocument.documentElement : null;915 });916 if (!documentElement) return null;917 if (!documentElement._objectId) return null;918 const nodeInfo = await this._client.send('DOM.describeNode', {919 objectId: documentElement._objectId920 });921 const frameId = nodeInfo && typeof nodeInfo.node.frameId === 'string' ? nodeInfo.node.frameId : null;922 documentElement.dispose();923 return frameId;924 }925 async _getBoundingBox(handle) {926 const result = await this._client._sendMayFail('DOM.getBoxModel', {927 objectId: handle._objectId928 });929 if (!result) return null;930 const quad = result.model.border;931 const x = Math.min(quad[0], quad[2], quad[4], quad[6]);932 const y = Math.min(quad[1], quad[3], quad[5], quad[7]);933 const width = Math.max(quad[0], quad[2], quad[4], quad[6]) - x;934 const height = Math.max(quad[1], quad[3], quad[5], quad[7]) - y;935 const position = await this._framePosition();936 if (!position) return null;937 return {938 x: x + position.x,939 y: y + position.y,940 width,941 height942 };943 }944 async _framePosition() {945 const frame = this._page._frameManager.frame(this._targetId);946 if (!frame) return null;947 if (frame === this._page.mainFrame()) return {948 x: 0,949 y: 0950 };951 const element = await frame.frameElement();952 const box = await element.boundingBox();953 return box;954 }955 async _scrollRectIntoViewIfNeeded(handle, rect) {956 return await this._client.send('DOM.scrollIntoViewIfNeeded', {957 objectId: handle._objectId,958 rect959 }).then(() => 'done').catch(e => {960 if (e instanceof Error && e.message.includes('Node does not have a layout object')) return 'error:notvisible';961 if (e instanceof Error && e.message.includes('Node is detached from document')) return 'error:notconnected';962 throw e;963 });964 }965 async _getContentQuads(handle) {966 const result = await this._client._sendMayFail('DOM.getContentQuads', {967 objectId: handle._objectId968 });969 if (!result) return null;970 const position = await this._framePosition();971 if (!position) return null;972 return result.quads.map(quad => [{973 x: quad[0] + position.x,974 y: quad[1] + position.y975 }, {976 x: quad[2] + position.x,977 y: quad[3] + position.y978 }, {979 x: quad[4] + position.x,980 y: quad[5] + position.y981 }, {982 x: quad[6] + position.x,983 y: quad[7] + position.y984 }]);985 }986 async _adoptElementHandle(handle, to) {987 const nodeInfo = await this._client.send('DOM.describeNode', {988 objectId: handle._objectId989 });990 return this._adoptBackendNodeId(nodeInfo.node.backendNodeId, to);991 }992 async _adoptBackendNodeId(backendNodeId, to) {993 const result = await this._client._sendMayFail('DOM.resolveNode', {994 backendNodeId,995 executionContextId: to[contextDelegateSymbol]._contextId996 });997 if (!result || result.object.subtype === 'null') throw new Error(dom.kUnableToAdoptErrorMessage);998 return to.createHandle(result.object).asElement();999 }1000}1001async function emulateLocale(session, locale) {1002 try {1003 await session.send('Emulation.setLocaleOverride', {1004 locale1005 });1006 } catch (exception) {...
ExecutionContext.js
Source:ExecutionContext.js
...139 prototypeObjectId: prototypeHandle._remoteObject.objectId140 });141 return JSHandle_1.createJSHandle(this, response.objects);142 }143 async _adoptBackendNodeId(backendNodeId) {144 const { object } = await this._client.send('DOM.resolveNode', {145 backendNodeId: backendNodeId,146 executionContextId: this._contextId,147 });148 return JSHandle_1.createJSHandle(this, object);149 }150 async _adoptElementHandle(elementHandle) {151 helper_1.assert(elementHandle.executionContext() !== this, 'Cannot adopt handle that already belongs to this execution context');152 helper_1.assert(this._world, 'Cannot adopt handle without DOMWorld');153 const nodeInfo = await this._client.send('DOM.describeNode', {154 objectId: elementHandle._remoteObject.objectId,155 });156 return this._adoptBackendNodeId(nodeInfo.node.backendNodeId);157 }158}...
AriaQueryHandler.js
Source:AriaQueryHandler.js
...44 const res = await queryAXTree(exeCtx._client, element, name, role);45 if (res.length < 1) {46 return null;47 }48 return exeCtx._adoptBackendNodeId(res[0].backendDOMNodeId);49};50const waitFor = async (domWorld, selector, options) => {51 const binding = {52 name: 'ariaQuerySelector',53 pptrFunction: async (selector) => {54 const document = await domWorld._document();55 const element = await queryOne(document, selector);56 return element;57 },58 };59 return domWorld.waitForSelectorInPage((_, selector) => globalThis.ariaQuerySelector(selector), selector, options, binding);60};61const queryAll = async (element, selector) => {62 const exeCtx = element.executionContext();63 const { name, role } = parseAriaSelector(selector);64 const res = await queryAXTree(exeCtx._client, element, name, role);65 return Promise.all(res.map((axNode) => exeCtx._adoptBackendNodeId(axNode.backendDOMNodeId)));66};67const queryAllArray = async (element, selector) => {68 const elementHandles = await queryAll(element, selector);69 const exeCtx = element.executionContext();70 const jsHandle = exeCtx.evaluateHandle((...elements) => elements, ...elementHandles);71 return jsHandle;72};73/**74 * @internal75 */76export const ariaHandler = {77 queryOne,78 waitFor,79 queryAll,...
Using AI Code Generation
1const puppeteer = require('puppeteer');2(async () => {3 const browser = await puppeteer.launch({headless: false});4 const page = await browser.newPage();5 await page.waitFor(5000);6 await page._client.send('DOM.getDocument');7 const {root} = await page._client.send('DOM.getDocument');8 await page._client.send('DOM.querySelector', {9 });10 const {nodeId} = await page._client.send('DOM.querySelector', {11 });12 const {backendNodeId} = await page._client.send('DOM.resolveNode', {13 });14 await page._client.send('DOM.requestNode', {15 });16 const {nodeId: nodeId2} = await page._client.send('DOM.requestNode', {17 });18 await page._client.send('DOM.getBoxModel', {19 });20 const {model} = await page._client.send('DOM.getBoxModel', {21 });22 console.log(model);23 await browser.close();24})();25const puppeteer = require('puppeteer');26(async () => {27 const browser = await puppeteer.launch({headless: false});28 const page = await browser.newPage();29 await page.waitFor(5000);30 await page._client.send('DOM.getDocument');31 const {root} = await page._client.send('DOM.getDocument');32 await page._client.send('DOM.querySelector', {33 });34 const {nodeId} = await page._client.send('DOM.querySelector', {35 });36 const {backendNodeId} = await page._client.send('DOM.resolveNode', {37 });38 await page._client.send('DOM.requestNode', {39 });40 const {nodeId: nodeId2} = await page._client.send('DOM.requestNode', {41 });
Using AI Code Generation
1const puppeteer = require('puppeteer');2const browser = await puppeteer.launch({headless: false});3const page = await browser.newPage();4const element = await page.$('input[name="q"]');5const backendNodeId = await page._client.send('DOM.describeNode', {6}).then(res => res.node.backendNodeId);7await page._client.send('DOM.adoptBackendNodeId', {8});9await page.$eval('input[name="q"]', e => e.value = 'hello world');10const puppeteer = require('puppeteer');11const browser = await puppeteer.launch({headless: false});12const page = await browser.newPage();13const element = await page.$('input[name="q"]');14await page._client.send('DOM.adoptBackendNodeId', {15});16await page.$eval('input[name="q"]', e => e.value = 'hello world');
Using AI Code Generation
1const puppeteer = require('puppeteer');2(async () => {3 const browser = await puppeteer.launch();4 const page = await browser.newPage();5 const searchBoxBackendNodeId = await page.$eval('input[name="q"]', el => el._remoteObject.backendNodeId);6 const searchButtonBackendNodeId = await page.$eval('input[name="btnK"]', el => el._remoteObject.backendNodeId);7 await page._client.send('DOM.adoptBackendNodeId', {backendNodeId: searchBoxBackendNodeId, targetNodeId: 1});8 await page._client.send('DOM.adoptBackendNodeId', {backendNodeId: searchButtonBackendNodeId, targetNodeId: 1});9 await page.type('input[name="q"]', 'Puppeteer');10 await page.click('input[name="btnK"]');11 await page.waitFor(3000);12 await browser.close();13})();
Using AI Code Generation
1const puppeteer = require('puppeteer');2const element = document.querySelector('div');3browser._connection.send('DOM.resolveNode', {nodeId: element._remoteObject.objectId}).then(result => {4 console.log(result.backendNodeId);5});6const puppeteer = require('puppeteer');7const element = document.querySelector('div');8browser._connection.send('DOM.resolveNode', {nodeId: element._remoteObject.objectId}).then(result => {9 browser._clickAt(result.backendNodeId);10});
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!