Best JavaScript code snippet using playwright-internal
frames.js
Source:frames.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.Frame = exports.FrameManager = void 0;6var dom = _interopRequireWildcard(require("./dom"));7var _helper = require("./helper");8var _eventsHelper = require("../utils/eventsHelper");9var js = _interopRequireWildcard(require("./javascript"));10var network = _interopRequireWildcard(require("./network"));11var _page = require("./page");12var types = _interopRequireWildcard(require("./types"));13var _browserContext = require("./browserContext");14var _progress = require("./progress");15var _utils = require("../utils/utils");16var _debugLogger = require("../utils/debugLogger");17var _instrumentation = require("./instrumentation");18function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }19function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }20/**21 * Copyright 2017 Google Inc. All rights reserved.22 * Modifications copyright (c) Microsoft Corporation.23 *24 * Licensed under the Apache License, Version 2.0 (the "License");25 * you may not use this file except in compliance with the License.26 * You may obtain a copy of the License at27 *28 * http://www.apache.org/licenses/LICENSE-2.029 *30 * Unless required by applicable law or agreed to in writing, software31 * distributed under the License is distributed on an "AS IS" BASIS,32 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.33 * See the License for the specific language governing permissions and34 * limitations under the License.35 */36class FrameManager {37 constructor(page) {38 this._page = void 0;39 this._frames = new Map();40 this._mainFrame = void 0;41 this._consoleMessageTags = new Map();42 this._signalBarriers = new Set();43 this._webSockets = new Map();44 this._responses = [];45 this._page = page;46 this._mainFrame = undefined;47 }48 dispose() {49 for (const frame of this._frames.values()) frame._stopNetworkIdleTimer();50 }51 mainFrame() {52 return this._mainFrame;53 }54 frames() {55 const frames = [];56 collect(this._mainFrame);57 return frames;58 function collect(frame) {59 frames.push(frame);60 for (const subframe of frame.childFrames()) collect(subframe);61 }62 }63 frame(frameId) {64 return this._frames.get(frameId) || null;65 }66 frameAttached(frameId, parentFrameId) {67 const parentFrame = parentFrameId ? this._frames.get(parentFrameId) : null;68 if (!parentFrame) {69 if (this._mainFrame) {70 // Update frame id to retain frame identity on cross-process navigation.71 this._frames.delete(this._mainFrame._id);72 this._mainFrame._id = frameId;73 } else {74 (0, _utils.assert)(!this._frames.has(frameId));75 this._mainFrame = new Frame(this._page, frameId, parentFrame);76 }77 this._frames.set(frameId, this._mainFrame);78 return this._mainFrame;79 } else {80 (0, _utils.assert)(!this._frames.has(frameId));81 const frame = new Frame(this._page, frameId, parentFrame);82 this._frames.set(frameId, frame);83 this._page.emit(_page.Page.Events.FrameAttached, frame);84 return frame;85 }86 }87 async waitForSignalsCreatedBy(progress, noWaitAfter, action, source) {88 if (noWaitAfter) return action();89 const barrier = new SignalBarrier(progress);90 this._signalBarriers.add(barrier);91 if (progress) progress.cleanupWhenAborted(() => this._signalBarriers.delete(barrier));92 const result = await action();93 if (source === 'input') await this._page._delegate.inputActionEpilogue();94 await barrier.waitFor();95 this._signalBarriers.delete(barrier); // Resolve in the next task, after all waitForNavigations.96 await new Promise((0, _utils.makeWaitForNextTask)());97 return result;98 }99 frameWillPotentiallyRequestNavigation() {100 for (const barrier of this._signalBarriers) barrier.retain();101 }102 frameDidPotentiallyRequestNavigation() {103 for (const barrier of this._signalBarriers) barrier.release();104 }105 frameRequestedNavigation(frameId, documentId) {106 const frame = this._frames.get(frameId);107 if (!frame) return;108 for (const barrier of this._signalBarriers) barrier.addFrameNavigation(frame);109 if (frame.pendingDocument() && frame.pendingDocument().documentId === documentId) {110 // Do not override request with undefined.111 return;112 }113 frame.setPendingDocument({114 documentId,115 request: undefined116 });117 }118 frameCommittedNewDocumentNavigation(frameId, url, name, documentId, initial) {119 const frame = this._frames.get(frameId);120 this.removeChildFramesRecursively(frame);121 this.clearWebSockets(frame);122 frame._url = url;123 frame._name = name;124 let keepPending;125 const pendingDocument = frame.pendingDocument();126 if (pendingDocument) {127 if (pendingDocument.documentId === undefined) {128 // Pending with unknown documentId - assume it is the one being committed.129 pendingDocument.documentId = documentId;130 }131 if (pendingDocument.documentId === documentId) {132 // Committing a pending document.133 frame._currentDocument = pendingDocument;134 } else {135 // Sometimes, we already have a new pending when the old one commits.136 // An example would be Chromium error page followed by a new navigation request,137 // where the error page commit arrives after Network.requestWillBeSent for the138 // new navigation.139 // We commit, but keep the pending request since it's not done yet.140 keepPending = pendingDocument;141 frame._currentDocument = {142 documentId,143 request: undefined144 };145 }146 frame.setPendingDocument(undefined);147 } else {148 // No pending - just commit a new document.149 frame._currentDocument = {150 documentId,151 request: undefined152 };153 }154 frame._onClearLifecycle();155 const navigationEvent = {156 url,157 name,158 newDocument: frame._currentDocument159 };160 frame.emit(Frame.Events.Navigation, navigationEvent);161 this._responses.length = 0;162 if (!initial) {163 _debugLogger.debugLogger.log('api', ` navigated to "${url}"`);164 this._page.frameNavigatedToNewDocument(frame);165 } // Restore pending if any - see comments above about keepPending.166 frame.setPendingDocument(keepPending);167 }168 frameCommittedSameDocumentNavigation(frameId, url) {169 const frame = this._frames.get(frameId);170 if (!frame) return;171 frame._url = url;172 const navigationEvent = {173 url,174 name: frame._name175 };176 frame.emit(Frame.Events.Navigation, navigationEvent);177 _debugLogger.debugLogger.log('api', ` navigated to "${url}"`);178 }179 frameAbortedNavigation(frameId, errorText, documentId) {180 const frame = this._frames.get(frameId);181 if (!frame || !frame.pendingDocument()) return;182 if (documentId !== undefined && frame.pendingDocument().documentId !== documentId) return;183 const navigationEvent = {184 url: frame._url,185 name: frame._name,186 newDocument: frame.pendingDocument(),187 error: new Error(errorText)188 };189 frame.setPendingDocument(undefined);190 frame.emit(Frame.Events.Navigation, navigationEvent);191 }192 frameDetached(frameId) {193 const frame = this._frames.get(frameId);194 if (frame) this._removeFramesRecursively(frame);195 }196 frameStoppedLoading(frameId) {197 this.frameLifecycleEvent(frameId, 'domcontentloaded');198 this.frameLifecycleEvent(frameId, 'load');199 }200 frameLifecycleEvent(frameId, event) {201 const frame = this._frames.get(frameId);202 if (frame) frame._onLifecycleEvent(event);203 }204 requestStarted(request, route) {205 const frame = request.frame();206 this._inflightRequestStarted(request);207 if (request._documentId) frame.setPendingDocument({208 documentId: request._documentId,209 request210 });211 if (request._isFavicon) {212 if (route) route.continue(request, {});213 return;214 }215 this._page._browserContext.emit(_browserContext.BrowserContext.Events.Request, request);216 if (route) this._page._requestStarted(request, route);217 }218 requestReceivedResponse(response) {219 if (response.request()._isFavicon) return;220 this._responses.push(response);221 this._page._browserContext.emit(_browserContext.BrowserContext.Events.Response, response);222 }223 requestFinished(request) {224 this._inflightRequestFinished(request);225 if (request._isFavicon) return;226 this._page._browserContext.emit(_browserContext.BrowserContext.Events.RequestFinished, request);227 }228 requestFailed(request, canceled) {229 const frame = request.frame();230 this._inflightRequestFinished(request);231 if (frame.pendingDocument() && frame.pendingDocument().request === request) {232 let errorText = request.failure().errorText;233 if (canceled) errorText += '; maybe frame was detached?';234 this.frameAbortedNavigation(frame._id, errorText, frame.pendingDocument().documentId);235 }236 if (request._isFavicon) return;237 this._page._browserContext.emit(_browserContext.BrowserContext.Events.RequestFailed, request);238 }239 removeChildFramesRecursively(frame) {240 for (const child of frame.childFrames()) this._removeFramesRecursively(child);241 }242 _removeFramesRecursively(frame) {243 this.removeChildFramesRecursively(frame);244 frame._onDetached();245 this._frames.delete(frame._id);246 if (!this._page.isClosed()) this._page.emit(_page.Page.Events.FrameDetached, frame);247 }248 _inflightRequestFinished(request) {249 const frame = request.frame();250 if (request._isFavicon) return;251 if (!frame._inflightRequests.has(request)) return;252 frame._inflightRequests.delete(request);253 if (frame._inflightRequests.size === 0) frame._startNetworkIdleTimer();254 }255 _inflightRequestStarted(request) {256 const frame = request.frame();257 if (request._isFavicon) return;258 frame._inflightRequests.add(request);259 if (frame._inflightRequests.size === 1) frame._stopNetworkIdleTimer();260 }261 interceptConsoleMessage(message) {262 if (message.type() !== 'debug') return false;263 const tag = message.text();264 const handler = this._consoleMessageTags.get(tag);265 if (!handler) return false;266 this._consoleMessageTags.delete(tag);267 handler();268 return true;269 }270 clearWebSockets(frame) {271 // TODO: attribute sockets to frames.272 if (frame.parentFrame()) return;273 this._webSockets.clear();274 }275 onWebSocketCreated(requestId, url) {276 const ws = new network.WebSocket(this._page, url);277 this._webSockets.set(requestId, ws);278 }279 onWebSocketRequest(requestId) {280 const ws = this._webSockets.get(requestId);281 if (ws) this._page.emit(_page.Page.Events.WebSocket, ws);282 }283 onWebSocketResponse(requestId, status, statusText) {284 const ws = this._webSockets.get(requestId);285 if (status < 400) return;286 if (ws) ws.error(`${statusText}: ${status}`);287 }288 onWebSocketFrameSent(requestId, opcode, data) {289 const ws = this._webSockets.get(requestId);290 if (ws) ws.frameSent(opcode, data);291 }292 webSocketFrameReceived(requestId, opcode, data) {293 const ws = this._webSockets.get(requestId);294 if (ws) ws.frameReceived(opcode, data);295 }296 webSocketClosed(requestId) {297 const ws = this._webSockets.get(requestId);298 if (ws) ws.closed();299 this._webSockets.delete(requestId);300 }301 webSocketError(requestId, errorMessage) {302 const ws = this._webSockets.get(requestId);303 if (ws) ws.error(errorMessage);304 }305}306exports.FrameManager = FrameManager;307class Frame extends _instrumentation.SdkObject {308 constructor(page, id, parentFrame) {309 super(page, 'frame');310 this._id = void 0;311 this._firedLifecycleEvents = new Set();312 this._subtreeLifecycleEvents = new Set();313 this._currentDocument = void 0;314 this._pendingDocument = void 0;315 this._page = void 0;316 this._parentFrame = void 0;317 this._url = '';318 this._detached = false;319 this._contextData = new Map();320 this._childFrames = new Set();321 this._name = '';322 this._inflightRequests = new Set();323 this._networkIdleTimer = void 0;324 this._setContentCounter = 0;325 this._detachedPromise = void 0;326 this._detachedCallback = () => {};327 this._nonStallingEvaluations = new Set();328 this.attribution.frame = this;329 this._id = id;330 this._page = page;331 this._parentFrame = parentFrame;332 this._currentDocument = {333 documentId: undefined,334 request: undefined335 };336 this._detachedPromise = new Promise(x => this._detachedCallback = x);337 this._contextData.set('main', {338 contextPromise: new Promise(() => {}),339 contextResolveCallback: () => {},340 context: null,341 rerunnableTasks: new Set()342 });343 this._contextData.set('utility', {344 contextPromise: new Promise(() => {}),345 contextResolveCallback: () => {},346 context: null,347 rerunnableTasks: new Set()348 });349 this._setContext('main', null);350 this._setContext('utility', null);351 if (this._parentFrame) this._parentFrame._childFrames.add(this);352 }353 _onLifecycleEvent(event) {354 if (this._firedLifecycleEvents.has(event)) return;355 this._firedLifecycleEvents.add(event); // Recalculate subtree lifecycle for the whole tree - it should not be that big.356 this._page.mainFrame()._recalculateLifecycle();357 }358 _onClearLifecycle() {359 this._firedLifecycleEvents.clear(); // Recalculate subtree lifecycle for the whole tree - it should not be that big.360 this._page.mainFrame()._recalculateLifecycle(); // Keep the current navigation request if any.361 this._inflightRequests = new Set(Array.from(this._inflightRequests).filter(request => request === this._currentDocument.request));362 this._stopNetworkIdleTimer();363 if (this._inflightRequests.size === 0) this._startNetworkIdleTimer();364 }365 setPendingDocument(documentInfo) {366 this._pendingDocument = documentInfo;367 if (documentInfo) this._invalidateNonStallingEvaluations();368 }369 pendingDocument() {370 return this._pendingDocument;371 }372 async _invalidateNonStallingEvaluations() {373 if (!this._nonStallingEvaluations) return;374 const error = new Error('Navigation interrupted the evaluation');375 for (const callback of this._nonStallingEvaluations) callback(error);376 }377 async nonStallingRawEvaluateInExistingMainContext(expression) {378 if (this._pendingDocument) throw new Error('Frame is currently attempting a navigation');379 const context = this._existingMainContext();380 if (!context) throw new Error('Frame does not yet have a main execution context');381 let callback = () => {};382 const frameInvalidated = new Promise((f, r) => callback = r);383 this._nonStallingEvaluations.add(callback);384 try {385 return await Promise.race([context.rawEvaluateJSON(expression), frameInvalidated]);386 } finally {387 this._nonStallingEvaluations.delete(callback);388 }389 }390 async nonStallingEvaluateInExistingContext(expression, isFunction, world) {391 var _this$_contextData$ge;392 if (this._pendingDocument) throw new Error('Frame is currently attempting a navigation');393 const context = (_this$_contextData$ge = this._contextData.get(world)) === null || _this$_contextData$ge === void 0 ? void 0 : _this$_contextData$ge.context;394 if (!context) throw new Error('Frame does not yet have the execution context');395 let callback = () => {};396 const frameInvalidated = new Promise((f, r) => callback = r);397 this._nonStallingEvaluations.add(callback);398 try {399 return await Promise.race([context.evaluateExpression(expression, isFunction), frameInvalidated]);400 } finally {401 this._nonStallingEvaluations.delete(callback);402 }403 }404 _recalculateLifecycle() {405 const events = new Set(this._firedLifecycleEvents);406 for (const child of this._childFrames) {407 child._recalculateLifecycle(); // We require a particular lifecycle event to be fired in the whole408 // frame subtree, and then consider it done.409 for (const event of events) {410 if (!child._subtreeLifecycleEvents.has(event)) events.delete(event);411 }412 }413 const mainFrame = this._page.mainFrame();414 for (const event of events) {415 // Checking whether we have already notified about this event.416 if (!this._subtreeLifecycleEvents.has(event)) {417 this.emit(Frame.Events.AddLifecycle, event);418 if (this === mainFrame && this._url !== 'about:blank') _debugLogger.debugLogger.log('api', ` "${event}" event fired`);419 if (this === mainFrame && event === 'load') this._page.emit(_page.Page.Events.Load);420 if (this === mainFrame && event === 'domcontentloaded') this._page.emit(_page.Page.Events.DOMContentLoaded);421 }422 }423 for (const event of this._subtreeLifecycleEvents) {424 if (!events.has(event)) this.emit(Frame.Events.RemoveLifecycle, event);425 }426 this._subtreeLifecycleEvents = events;427 }428 async raceNavigationAction(action) {429 return Promise.race([this._page._disconnectedPromise.then(() => {430 throw new Error('Navigation failed because page was closed!');431 }), this._page._crashedPromise.then(() => {432 throw new Error('Navigation failed because page crashed!');433 }), this._detachedPromise.then(() => {434 throw new Error('Navigating frame was detached!');435 }), action()]);436 }437 async goto(metadata, url, options = {}) {438 const constructedNavigationURL = (0, _utils.constructURLBasedOnBaseURL)(this._page._browserContext._options.baseURL, url);439 const controller = new _progress.ProgressController(metadata, this);440 return controller.run(progress => this._goto(progress, constructedNavigationURL, options), this._page._timeoutSettings.navigationTimeout(options));441 }442 async _goto(progress, url, options) {443 return this.raceNavigationAction(async () => {444 const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);445 progress.log(`navigating to "${url}", waiting until "${waitUntil}"`);446 const headers = this._page._state.extraHTTPHeaders || [];447 const refererHeader = headers.find(h => h.name.toLowerCase() === 'referer');448 let referer = refererHeader ? refererHeader.value : undefined;449 if (options.referer !== undefined) {450 if (referer !== undefined && referer !== options.referer) throw new Error('"referer" is already specified as extra HTTP header');451 referer = options.referer;452 }453 url = _helper.helper.completeUserURL(url);454 const sameDocument = _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, e => !e.newDocument);455 const navigateResult = await this._page._delegate.navigateFrame(this, url, referer);456 let event;457 if (navigateResult.newDocumentId) {458 sameDocument.dispose();459 event = await _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, event => {460 // We are interested either in this specific document, or any other document that461 // did commit and replaced the expected document.462 return event.newDocument && (event.newDocument.documentId === navigateResult.newDocumentId || !event.error);463 }).promise;464 if (event.newDocument.documentId !== navigateResult.newDocumentId) {465 // This is just a sanity check. In practice, new navigation should466 // cancel the previous one and report "request cancelled"-like error.467 throw new Error('Navigation interrupted by another one');468 }469 if (event.error) throw event.error;470 } else {471 event = await sameDocument.promise;472 }473 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;474 const request = event.newDocument ? event.newDocument.request : undefined;475 const response = request ? request._finalRequest().response() : null;476 await this._page._doSlowMo();477 return response;478 });479 }480 async _waitForNavigation(progress, options) {481 const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);482 progress.log(`waiting for navigation until "${waitUntil}"`);483 const navigationEvent = await _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, event => {484 // Any failed navigation results in a rejection.485 if (event.error) return true;486 progress.log(` navigated to "${this._url}"`);487 return true;488 }).promise;489 if (navigationEvent.error) throw navigationEvent.error;490 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;491 const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : undefined;492 return request ? request._finalRequest().response() : null;493 }494 async _waitForLoadState(progress, state) {495 const waitUntil = verifyLifecycle('state', state);496 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;497 }498 async frameElement() {499 return this._page._delegate.getFrameElement(this);500 }501 _context(world) {502 if (this._detached) throw new Error(`Execution Context is not available in detached frame "${this.url()}" (are you trying to evaluate?)`);503 return this._contextData.get(world).contextPromise;504 }505 _mainContext() {506 return this._context('main');507 }508 _existingMainContext() {509 var _this$_contextData$ge2;510 return ((_this$_contextData$ge2 = this._contextData.get('main')) === null || _this$_contextData$ge2 === void 0 ? void 0 : _this$_contextData$ge2.context) || null;511 }512 _utilityContext() {513 return this._context('utility');514 }515 async evaluateExpressionHandleAndWaitForSignals(expression, isFunction, arg, world = 'main') {516 const context = await this._context(world);517 const handle = await context.evaluateExpressionHandleAndWaitForSignals(expression, isFunction, arg);518 if (world === 'main') await this._page._doSlowMo();519 return handle;520 }521 async evaluateExpression(expression, isFunction, arg, world = 'main') {522 const context = await this._context(world);523 const value = await context.evaluateExpression(expression, isFunction, arg);524 if (world === 'main') await this._page._doSlowMo();525 return value;526 }527 async evaluateExpressionAndWaitForSignals(expression, isFunction, arg, world = 'main') {528 const context = await this._context(world);529 const value = await context.evaluateExpressionAndWaitForSignals(expression, isFunction, arg);530 if (world === 'main') await this._page._doSlowMo();531 return value;532 }533 async querySelector(selector, options) {534 _debugLogger.debugLogger.log('api', ` finding element using the selector "${selector}"`);535 return this._page.selectors.query(this, selector, options);536 }537 async waitForSelector(metadata, selector, options = {}) {538 const controller = new _progress.ProgressController(metadata, this);539 if (options.visibility) throw new Error('options.visibility is not supported, did you mean options.state?');540 if (options.waitFor && options.waitFor !== 'visible') throw new Error('options.waitFor is not supported, did you mean options.state?');541 const {542 state = 'visible'543 } = options;544 if (!['attached', 'detached', 'visible', 'hidden'].includes(state)) throw new Error(`state: expected one of (attached|detached|visible|hidden)`);545 const info = this._page.parseSelector(selector, options);546 const task = dom.waitForSelectorTask(info, state);547 return controller.run(async progress => {548 progress.log(`waiting for selector "${selector}"${state === 'attached' ? '' : ' to be ' + state}`);549 while (progress.isRunning()) {550 const result = await this._scheduleRerunnableHandleTask(progress, info.world, task);551 if (!result.asElement()) {552 result.dispose();553 return null;554 }555 if (options.__testHookBeforeAdoptNode) await options.__testHookBeforeAdoptNode();556 try {557 const handle = result.asElement();558 const adopted = await handle._adoptTo(await this._mainContext());559 return adopted;560 } catch (e) {561 // Navigated while trying to adopt the node.562 if (!js.isContextDestroyedError(e) && !e.message.includes(dom.kUnableToAdoptErrorMessage)) throw e;563 result.dispose();564 }565 }566 return null;567 }, this._page._timeoutSettings.timeout(options));568 }569 async dispatchEvent(metadata, selector, type, eventInit, options = {}) {570 const controller = new _progress.ProgressController(metadata, this);571 const info = this._page.parseSelector(selector, options);572 const task = dom.dispatchEventTask(info, type, eventInit || {});573 await controller.run(async progress => {574 progress.log(`Dispatching "${type}" event on selector "${selector}"...`); // Note: we always dispatch events in the main world.575 await this._scheduleRerunnableTask(progress, 'main', task);576 }, this._page._timeoutSettings.timeout(options));577 await this._page._doSlowMo();578 }579 async evalOnSelectorAndWaitForSignals(selector, strict, expression, isFunction, arg) {580 const handle = await this.querySelector(selector, {581 strict582 });583 if (!handle) throw new Error(`Error: failed to find element matching selector "${selector}"`);584 const result = await handle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);585 handle.dispose();586 return result;587 }588 async evalOnSelectorAllAndWaitForSignals(selector, expression, isFunction, arg) {589 const arrayHandle = await this._page.selectors._queryArray(this, selector);590 const result = await arrayHandle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);591 arrayHandle.dispose();592 return result;593 }594 async querySelectorAll(selector) {595 return this._page.selectors._queryAll(this, selector, undefined, true596 /* adoptToMain */597 );598 }599 async content() {600 const context = await this._utilityContext();601 return context.evaluate(() => {602 let retVal = '';603 if (document.doctype) retVal = new XMLSerializer().serializeToString(document.doctype);604 if (document.documentElement) retVal += document.documentElement.outerHTML;605 return retVal;606 });607 }608 async setContent(metadata, html, options = {}) {609 const controller = new _progress.ProgressController(metadata, this);610 return controller.run(progress => this.raceNavigationAction(async () => {611 const waitUntil = options.waitUntil === undefined ? 'load' : options.waitUntil;612 progress.log(`setting frame content, waiting until "${waitUntil}"`);613 const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;614 const context = await this._utilityContext();615 const lifecyclePromise = new Promise((resolve, reject) => {616 this._page._frameManager._consoleMessageTags.set(tag, () => {617 // Clear lifecycle right after document.open() - see 'tag' below.618 this._onClearLifecycle();619 this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);620 });621 });622 const contentPromise = context.evaluate(({623 html,624 tag625 }) => {626 window.stop();627 document.open();628 console.debug(tag); // eslint-disable-line no-console629 document.write(html);630 document.close();631 }, {632 html,633 tag634 });635 await Promise.all([contentPromise, lifecyclePromise]);636 await this._page._doSlowMo();637 }), this._page._timeoutSettings.navigationTimeout(options));638 }639 name() {640 return this._name || '';641 }642 url() {643 return this._url;644 }645 parentFrame() {646 return this._parentFrame;647 }648 childFrames() {649 return Array.from(this._childFrames);650 }651 async addScriptTag(params) {652 const {653 url = null,654 content = null,655 type = ''656 } = params;657 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');658 const context = await this._mainContext();659 return this._raceWithCSPError(async () => {660 if (url !== null) return (await context.evaluateHandle(addScriptUrl, {661 url,662 type663 })).asElement();664 const result = (await context.evaluateHandle(addScriptContent, {665 content: content,666 type667 })).asElement(); // Another round trip to the browser to ensure that we receive CSP error messages668 // (if any) logged asynchronously in a separate task on the content main thread.669 if (this._page._delegate.cspErrorsAsynchronousForInlineScipts) await context.evaluate(() => true);670 return result;671 });672 async function addScriptUrl(params) {673 const script = document.createElement('script');674 script.src = params.url;675 if (params.type) script.type = params.type;676 const promise = new Promise((res, rej) => {677 script.onload = res;678 script.onerror = e => rej(typeof e === 'string' ? new Error(e) : new Error(`Failed to load script at ${script.src}`));679 });680 document.head.appendChild(script);681 await promise;682 return script;683 }684 function addScriptContent(params) {685 const script = document.createElement('script');686 script.type = params.type || 'text/javascript';687 script.text = params.content;688 let error = null;689 script.onerror = e => error = e;690 document.head.appendChild(script);691 if (error) throw error;692 return script;693 }694 }695 async addStyleTag(params) {696 const {697 url = null,698 content = null699 } = params;700 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');701 const context = await this._mainContext();702 return this._raceWithCSPError(async () => {703 if (url !== null) return (await context.evaluateHandle(addStyleUrl, url)).asElement();704 return (await context.evaluateHandle(addStyleContent, content)).asElement();705 });706 async function addStyleUrl(url) {707 const link = document.createElement('link');708 link.rel = 'stylesheet';709 link.href = url;710 const promise = new Promise((res, rej) => {711 link.onload = res;712 link.onerror = rej;713 });714 document.head.appendChild(link);715 await promise;716 return link;717 }718 async function addStyleContent(content) {719 const style = document.createElement('style');720 style.type = 'text/css';721 style.appendChild(document.createTextNode(content));722 const promise = new Promise((res, rej) => {723 style.onload = res;724 style.onerror = rej;725 });726 document.head.appendChild(style);727 await promise;728 return style;729 }730 }731 async _raceWithCSPError(func) {732 const listeners = [];733 let result;734 let error;735 let cspMessage;736 const actionPromise = new Promise(async resolve => {737 try {738 result = await func();739 } catch (e) {740 error = e;741 }742 resolve();743 });744 const errorPromise = new Promise(resolve => {745 listeners.push(_eventsHelper.eventsHelper.addEventListener(this._page, _page.Page.Events.Console, message => {746 if (message.type() === 'error' && message.text().includes('Content Security Policy')) {747 cspMessage = message;748 resolve();749 }750 }));751 });752 await Promise.race([actionPromise, errorPromise]);753 _eventsHelper.eventsHelper.removeEventListeners(listeners);754 if (cspMessage) throw new Error(cspMessage.text());755 if (error) throw error;756 return result;757 }758 async _retryWithProgressIfNotConnected(progress, selector, strict, action) {759 const info = this._page.parseSelector(selector, {760 strict761 });762 while (progress.isRunning()) {763 progress.log(`waiting for selector "${selector}"`);764 const task = dom.waitForSelectorTask(info, 'attached');765 const handle = await this._scheduleRerunnableHandleTask(progress, info.world, task);766 const element = handle.asElement();767 progress.cleanupWhenAborted(() => {768 // Do not await here to avoid being blocked, either by stalled769 // page (e.g. alert) or unresolved navigation in Chromium.770 element.dispose();771 });772 const result = await action(element);773 element.dispose();774 if (result === 'error:notconnected') {775 progress.log('element was detached from the DOM, retrying');776 continue;777 }778 return result;779 }780 return undefined;781 }782 async _retryWithSelectorIfNotConnected(controller, selector, options, action) {783 return controller.run(async progress => {784 return this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => action(progress, handle));785 }, this._page._timeoutSettings.timeout(options));786 }787 async click(metadata, selector, options) {788 const controller = new _progress.ProgressController(metadata, this);789 return controller.run(async progress => {790 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._click(progress, options)));791 }, this._page._timeoutSettings.timeout(options));792 }793 async dblclick(metadata, selector, options = {}) {794 const controller = new _progress.ProgressController(metadata, this);795 return controller.run(async progress => {796 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._dblclick(progress, options)));797 }, this._page._timeoutSettings.timeout(options));798 }799 async dragAndDrop(metadata, source, target, options = {}) {800 const controller = new _progress.ProgressController(metadata, this);801 await controller.run(async progress => {802 await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, async handle => {803 return handle._retryPointerAction(progress, 'move and down', false, async point => {804 await this._page.mouse.move(point.x, point.y);805 await this._page.mouse.down();806 }, { ...options,807 position: options.sourcePosition,808 timeout: progress.timeUntilDeadline()809 });810 }));811 await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, async handle => {812 return handle._retryPointerAction(progress, 'move and up', false, async point => {813 await this._page.mouse.move(point.x, point.y);814 await this._page.mouse.up();815 }, { ...options,816 position: options.targetPosition,817 timeout: progress.timeUntilDeadline()818 });819 }));820 }, this._page._timeoutSettings.timeout(options));821 }822 async tap(metadata, selector, options) {823 const controller = new _progress.ProgressController(metadata, this);824 return controller.run(async progress => {825 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._tap(progress, options)));826 }, this._page._timeoutSettings.timeout(options));827 }828 async fill(metadata, selector, value, options) {829 const controller = new _progress.ProgressController(metadata, this);830 return controller.run(async progress => {831 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._fill(progress, value, options)));832 }, this._page._timeoutSettings.timeout(options));833 }834 async focus(metadata, selector, options = {}) {835 const controller = new _progress.ProgressController(metadata, this);836 await this._retryWithSelectorIfNotConnected(controller, selector, options, (progress, handle) => handle._focus(progress));837 await this._page._doSlowMo();838 }839 async textContent(metadata, selector, options = {}) {840 const controller = new _progress.ProgressController(metadata, this);841 const info = this._page.parseSelector(selector, options);842 const task = dom.textContentTask(info);843 return controller.run(async progress => {844 progress.log(` retrieving textContent from "${selector}"`);845 return this._scheduleRerunnableTask(progress, info.world, task);846 }, this._page._timeoutSettings.timeout(options));847 }848 async innerText(metadata, selector, options = {}) {849 const controller = new _progress.ProgressController(metadata, this);850 const info = this._page.parseSelector(selector, options);851 const task = dom.innerTextTask(info);852 return controller.run(async progress => {853 progress.log(` retrieving innerText from "${selector}"`);854 const result = dom.throwFatalDOMError(await this._scheduleRerunnableTask(progress, info.world, task));855 return result.innerText;856 }, this._page._timeoutSettings.timeout(options));857 }858 async innerHTML(metadata, selector, options = {}) {859 const controller = new _progress.ProgressController(metadata, this);860 const info = this._page.parseSelector(selector, options);861 const task = dom.innerHTMLTask(info);862 return controller.run(async progress => {863 progress.log(` retrieving innerHTML from "${selector}"`);864 return this._scheduleRerunnableTask(progress, info.world, task);865 }, this._page._timeoutSettings.timeout(options));866 }867 async getAttribute(metadata, selector, name, options = {}) {868 const controller = new _progress.ProgressController(metadata, this);869 const info = this._page.parseSelector(selector, options);870 const task = dom.getAttributeTask(info, name);871 return controller.run(async progress => {872 progress.log(` retrieving attribute "${name}" from "${selector}"`);873 return this._scheduleRerunnableTask(progress, info.world, task);874 }, this._page._timeoutSettings.timeout(options));875 }876 async inputValue(metadata, selector, options = {}) {877 const controller = new _progress.ProgressController(metadata, this);878 const info = this._page.parseSelector(selector, options);879 const task = dom.inputValueTask(info);880 return controller.run(async progress => {881 progress.log(` retrieving value from "${selector}"`);882 return dom.throwFatalDOMError(await this._scheduleRerunnableTask(progress, info.world, task));883 }, this._page._timeoutSettings.timeout(options));884 }885 async _checkElementState(metadata, selector, state, options = {}) {886 const controller = new _progress.ProgressController(metadata, this);887 const info = this._page.parseSelector(selector, options);888 const task = dom.elementStateTask(info, state);889 const result = await controller.run(async progress => {890 progress.log(` checking "${state}" state of "${selector}"`);891 return this._scheduleRerunnableTask(progress, info.world, task);892 }, this._page._timeoutSettings.timeout(options));893 return dom.throwFatalDOMError(dom.throwRetargetableDOMError(result));894 }895 async isVisible(metadata, selector, options = {}) {896 const controller = new _progress.ProgressController(metadata, this);897 return controller.run(async progress => {898 progress.log(` checking visibility of "${selector}"`);899 const element = await this.querySelector(selector, options);900 return element ? await element.isVisible() : false;901 }, this._page._timeoutSettings.timeout(options));902 }903 async isHidden(metadata, selector, options = {}) {904 return !(await this.isVisible(metadata, selector, options));905 }906 async isDisabled(metadata, selector, options = {}) {907 return this._checkElementState(metadata, selector, 'disabled', options);908 }909 async isEnabled(metadata, selector, options = {}) {910 return this._checkElementState(metadata, selector, 'enabled', options);911 }912 async isEditable(metadata, selector, options = {}) {913 return this._checkElementState(metadata, selector, 'editable', options);914 }915 async isChecked(metadata, selector, options = {}) {916 return this._checkElementState(metadata, selector, 'checked', options);917 }918 async hover(metadata, selector, options = {}) {919 const controller = new _progress.ProgressController(metadata, this);920 return controller.run(async progress => {921 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options)));922 }, this._page._timeoutSettings.timeout(options));923 }924 async selectOption(metadata, selector, elements, values, options = {}) {925 const controller = new _progress.ProgressController(metadata, this);926 return controller.run(async progress => {927 return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._selectOption(progress, elements, values, options));928 }, this._page._timeoutSettings.timeout(options));929 }930 async setInputFiles(metadata, selector, files, options = {}) {931 const controller = new _progress.ProgressController(metadata, this);932 return controller.run(async progress => {933 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setInputFiles(progress, files, options)));934 }, this._page._timeoutSettings.timeout(options));935 }936 async type(metadata, selector, text, options = {}) {937 const controller = new _progress.ProgressController(metadata, this);938 return controller.run(async progress => {939 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._type(progress, text, options)));940 }, this._page._timeoutSettings.timeout(options));941 }942 async press(metadata, selector, key, options = {}) {943 const controller = new _progress.ProgressController(metadata, this);944 return controller.run(async progress => {945 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._press(progress, key, options)));946 }, this._page._timeoutSettings.timeout(options));947 }948 async check(metadata, selector, options = {}) {949 const controller = new _progress.ProgressController(metadata, this);950 return controller.run(async progress => {951 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, true, options)));952 }, this._page._timeoutSettings.timeout(options));953 }954 async uncheck(metadata, selector, options = {}) {955 const controller = new _progress.ProgressController(metadata, this);956 return controller.run(async progress => {957 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, false, options)));958 }, this._page._timeoutSettings.timeout(options));959 }960 async _waitForFunctionExpression(metadata, expression, isFunction, arg, options, world = 'main') {961 const controller = new _progress.ProgressController(metadata, this);962 if (typeof options.pollingInterval === 'number') (0, _utils.assert)(options.pollingInterval > 0, 'Cannot poll with non-positive interval: ' + options.pollingInterval);963 expression = js.normalizeEvaluationExpression(expression, isFunction);964 const task = injectedScript => injectedScript.evaluateHandle((injectedScript, {965 expression,966 isFunction,967 polling,968 arg969 }) => {970 const predicate = arg => {971 let result = self.eval(expression);972 if (isFunction === true) {973 result = result(arg);974 } else if (isFunction === false) {975 result = result;976 } else {977 // auto detect.978 if (typeof result === 'function') result = result(arg);979 }980 return result;981 };982 if (typeof polling !== 'number') return injectedScript.pollRaf((progress, continuePolling) => predicate(arg) || continuePolling);983 return injectedScript.pollInterval(polling, (progress, continuePolling) => predicate(arg) || continuePolling);984 }, {985 expression,986 isFunction,987 polling: options.pollingInterval,988 arg989 });990 return controller.run(progress => this._scheduleRerunnableHandleTask(progress, world, task), this._page._timeoutSettings.timeout(options));991 }992 async waitForFunctionValueInUtility(progress, pageFunction) {993 const expression = `() => {994 const result = (${pageFunction})();995 if (!result)996 return result;997 return JSON.stringify(result);998 }`;999 const handle = await this._waitForFunctionExpression((0, _instrumentation.internalCallMetadata)(), expression, true, undefined, {1000 timeout: progress.timeUntilDeadline()1001 }, 'utility');1002 return JSON.parse(handle.rawValue());1003 }1004 async title() {1005 const context = await this._utilityContext();1006 return context.evaluate(() => document.title);1007 }1008 _onDetached() {1009 this._stopNetworkIdleTimer();1010 this._detached = true;1011 this._detachedCallback();1012 for (const data of this._contextData.values()) {1013 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.terminate(new Error('waitForFunction failed: frame got detached.'));1014 }1015 if (this._parentFrame) this._parentFrame._childFrames.delete(this);1016 this._parentFrame = null;1017 }1018 _scheduleRerunnableTask(progress, world, task) {1019 const data = this._contextData.get(world);1020 const rerunnableTask = new RerunnableTask(data, progress, task, true1021 /* returnByValue */1022 );1023 if (this._detached) rerunnableTask.terminate(new Error('waitForFunction failed: frame got detached.'));1024 if (data.context) rerunnableTask.rerun(data.context);1025 return rerunnableTask.promise;1026 }1027 _scheduleRerunnableHandleTask(progress, world, task) {1028 const data = this._contextData.get(world);1029 const rerunnableTask = new RerunnableTask(data, progress, task, false1030 /* returnByValue */1031 );1032 if (this._detached) rerunnableTask.terminate(new Error('waitForFunction failed: frame got detached.'));1033 if (data.context) rerunnableTask.rerun(data.context);1034 return rerunnableTask.promise;1035 }1036 _setContext(world, context) {1037 const data = this._contextData.get(world);1038 data.context = context;1039 if (context) {1040 data.contextResolveCallback.call(null, context);1041 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.rerun(context);1042 } else {1043 data.contextPromise = new Promise(fulfill => {1044 data.contextResolveCallback = fulfill;1045 });1046 }1047 }1048 _contextCreated(world, context) {1049 const data = this._contextData.get(world); // In case of multiple sessions to the same target, there's a race between1050 // connections so we might end up creating multiple isolated worlds.1051 // We can use either.1052 if (data.context) this._setContext(world, null);1053 this._setContext(world, context);1054 }1055 _contextDestroyed(context) {1056 for (const [world, data] of this._contextData) {1057 if (data.context === context) this._setContext(world, null);1058 }1059 }1060 _startNetworkIdleTimer() {1061 (0, _utils.assert)(!this._networkIdleTimer); // We should not start a timer and report networkidle in detached frames.1062 // This happens at least in Firefox for child frames, where we may get requestFinished1063 // after the frame was detached - probably a race in the Firefox itself.1064 if (this._firedLifecycleEvents.has('networkidle') || this._detached) return;1065 this._networkIdleTimer = setTimeout(() => this._onLifecycleEvent('networkidle'), 500);1066 }1067 _stopNetworkIdleTimer() {1068 if (this._networkIdleTimer) clearTimeout(this._networkIdleTimer);1069 this._networkIdleTimer = undefined;1070 }1071 async extendInjectedScript(world, source, arg) {1072 const context = await this._context(world);1073 const injectedScriptHandle = await context.injectedScript();1074 return injectedScriptHandle.evaluateHandle((injectedScript, {1075 source,1076 arg1077 }) => {1078 return injectedScript.extend(source, arg);1079 }, {1080 source,1081 arg1082 });1083 }1084}1085exports.Frame = Frame;1086Frame.Events = {1087 Navigation: 'navigation',1088 AddLifecycle: 'addlifecycle',1089 RemoveLifecycle: 'removelifecycle'1090};1091class RerunnableTask {1092 constructor(data, progress, task, returnByValue) {1093 this.promise = void 0;1094 this._task = void 0;1095 this._resolve = () => {};1096 this._reject = () => {};1097 this._progress = void 0;1098 this._returnByValue = void 0;1099 this._contextData = void 0;1100 this._task = task;1101 this._progress = progress;1102 this._returnByValue = returnByValue;1103 this._contextData = data;1104 this._contextData.rerunnableTasks.add(this);1105 this.promise = new Promise((resolve, reject) => {1106 // The task is either resolved with a value, or rejected with a meaningful evaluation error.1107 this._resolve = resolve;1108 this._reject = reject;1109 });1110 }1111 terminate(error) {1112 this._reject(error);1113 }1114 async rerun(context) {1115 try {1116 const injectedScript = await context.injectedScript();1117 const pollHandler = new dom.InjectedScriptPollHandler(this._progress, await this._task(injectedScript));1118 const result = this._returnByValue ? await pollHandler.finish() : await pollHandler.finishHandle();1119 this._contextData.rerunnableTasks.delete(this);1120 this._resolve(result);1121 } catch (e) {1122 // We will try again in the new execution context.1123 if (js.isContextDestroyedError(e)) return;1124 this._contextData.rerunnableTasks.delete(this);1125 this._reject(e);1126 }1127 }1128}1129class SignalBarrier {1130 constructor(progress) {1131 this._progress = void 0;1132 this._protectCount = 0;1133 this._promise = void 0;1134 this._promiseCallback = () => {};1135 this._progress = progress;1136 this._promise = new Promise(f => this._promiseCallback = f);1137 this.retain();1138 }1139 waitFor() {1140 this.release();1141 return this._promise;1142 }1143 async addFrameNavigation(frame) {1144 // Auto-wait top-level navigations only.1145 if (frame.parentFrame()) return;1146 this.retain();1147 const waiter = _helper.helper.waitForEvent(null, frame, Frame.Events.Navigation, e => {1148 if (!e.error && this._progress) this._progress.log(` navigated to "${frame._url}"`);1149 return true;1150 });1151 await Promise.race([frame._page._disconnectedPromise, frame._page._crashedPromise, frame._detachedPromise, waiter.promise]).catch(e => {});1152 waiter.dispose();1153 this.release();1154 }1155 retain() {1156 ++this._protectCount;1157 }1158 release() {1159 --this._protectCount;1160 if (!this._protectCount) this._promiseCallback();1161 }1162}1163function verifyLifecycle(name, waitUntil) {1164 if (waitUntil === 'networkidle0') waitUntil = 'networkidle';1165 if (!types.kLifecycleEvents.has(waitUntil)) throw new Error(`${name}: expected one of (load|domcontentloaded|networkidle)`);1166 return waitUntil;...
utils.js
Source:utils.js
...334function getUserAgent() {335 const packageJson = require('./../../package.json');336 return `Playwright/${packageJson.version} (${_os.default.arch()}/${_os.default.platform()}/${_os.default.release()})`;337}338function constructURLBasedOnBaseURL(baseURL, givenURL) {339 try {340 return new URL.URL(givenURL, baseURL).toString();341 } catch (e) {342 return givenURL;343 }344}345const hostPlatform = (() => {346 const platform = _os.default.platform();347 if (platform === 'darwin') {348 const ver = _os.default.release().split('.').map(a => parseInt(a, 10));349 let macVersion = '';350 if (ver[0] < 18) {351 // Everything before 10.14 is considered 10.13.352 macVersion = 'mac10.13';...
index.js
Source:index.js
...178}179function createGuid() {180 return crypto.randomBytes(16).toString('hex');181}182function constructURLBasedOnBaseURL(baseURL, givenURL) {183 try {184 return new URL.URL(givenURL, baseURL).toString();185 } catch (e) {186 return givenURL;187 }188}189function wrapInASCIIBox(text, padding = 0) {190 const lines = text.split('\n');191 const maxLength = Math.max(...lines.map(line => line.length));192 return ['â' + 'â'.repeat(maxLength + padding * 2) + 'â', ...lines.map(line => 'â' + ' '.repeat(padding) + line + ' '.repeat(maxLength - line.length + padding) + 'â'), 'â' + 'â'.repeat(maxLength + padding * 2) + 'â'].join('\n');193}194function isFilePayload(value) {195 return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer'];196}...
clientHelper.js
Source:clientHelper.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.deprecate = deprecate;6exports.envObjectToArray = envObjectToArray;7exports.evaluationScript = evaluationScript;8exports.parsedURL = parsedURL;9exports.urlMatches = urlMatches;10exports.globToRegex = globToRegex;11var _fs = _interopRequireDefault(require("fs"));12var _utils = require("../utils/utils");13function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }14/**15 * Copyright 2017 Google Inc. All rights reserved.16 * Modifications copyright (c) Microsoft Corporation.17 *18 * Licensed under the Apache License, Version 2.0 (the "License");19 * you may not use this file except in compliance with the License.20 * You may obtain a copy of the License at21 *22 * http://www.apache.org/licenses/LICENSE-2.023 *24 * Unless required by applicable law or agreed to in writing, software25 * distributed under the License is distributed on an "AS IS" BASIS,26 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.27 * See the License for the specific language governing permissions and28 * limitations under the License.29 */30const deprecatedHits = new Set();31function deprecate(methodName, message) {32 if (deprecatedHits.has(methodName)) return;33 deprecatedHits.add(methodName);34 console.warn(message);35}36function envObjectToArray(env) {37 const result = [];38 for (const name in env) {39 if (!Object.is(env[name], undefined)) result.push({40 name,41 value: String(env[name])42 });43 }44 return result;45}46async function evaluationScript(fun, arg, addSourceUrl = true) {47 if (typeof fun === 'function') {48 const source = fun.toString();49 const argString = Object.is(arg, undefined) ? 'undefined' : JSON.stringify(arg);50 return `(${source})(${argString})`;51 }52 if (arg !== undefined) throw new Error('Cannot evaluate a string with arguments');53 if ((0, _utils.isString)(fun)) return fun;54 if (fun.content !== undefined) return fun.content;55 if (fun.path !== undefined) {56 let source = await _fs.default.promises.readFile(fun.path, 'utf8');57 if (addSourceUrl) source += '//# sourceURL=' + fun.path.replace(/\n/g, '');58 return source;59 }60 throw new Error('Either path or content property must be present');61}62function parsedURL(url) {63 try {64 return new URL(url);65 } catch (e) {66 return null;67 }68}69function urlMatches(baseURL, urlString, match) {70 if (match === undefined || match === '') return true;71 if ((0, _utils.isString)(match) && !match.startsWith('*')) match = (0, _utils.constructURLBasedOnBaseURL)(baseURL, match);72 if ((0, _utils.isString)(match)) match = globToRegex(match);73 if ((0, _utils.isRegExp)(match)) return match.test(urlString);74 if (typeof match === 'string' && match === urlString) return true;75 const url = parsedURL(urlString);76 if (!url) return false;77 if (typeof match === 'string') return url.pathname === match;78 if (typeof match !== 'function') throw new Error('url parameter should be string, RegExp or function');79 return match(url);80}81const escapeGlobChars = new Set(['/', '$', '^', '+', '.', '(', ')', '=', '!', '|']);82function globToRegex(glob) {83 const tokens = ['^'];84 let inGroup;85 for (let i = 0; i < glob.length; ++i) {86 const c = glob[i];87 if (escapeGlobChars.has(c)) {88 tokens.push('\\' + c);89 continue;90 }91 if (c === '*') {92 const beforeDeep = glob[i - 1];93 let starCount = 1;94 while (glob[i + 1] === '*') {95 starCount++;96 i++;97 }98 const afterDeep = glob[i + 1];99 const isDeep = starCount > 1 && (beforeDeep === '/' || beforeDeep === undefined) && (afterDeep === '/' || afterDeep === undefined);100 if (isDeep) {101 tokens.push('((?:[^/]*(?:\/|$))*)');102 i++;103 } else {104 tokens.push('([^/]*)');105 }106 continue;107 }108 switch (c) {109 case '?':110 tokens.push('.');111 break;112 case '{':113 inGroup = true;114 tokens.push('(');115 break;116 case '}':117 inGroup = false;118 tokens.push(')');119 break;120 case ',':121 if (inGroup) {122 tokens.push('|');123 break;124 }125 tokens.push('\\' + c);126 break;127 default:128 tokens.push(c);129 }130 }131 tokens.push('$');132 return new RegExp(tokens.join(''));...
Using AI Code Generation
1const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');2console.log(url);3const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');4console.log(url);5const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');6console.log(url);7const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');8console.log(url);9const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');10console.log(url);11const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');12console.log(url);13const { constructURLBasedOnBaseURL } = require('playwright/lib/server/network');
Using AI Code Generation
1const url = await page.evaluate((url) => {2 const { constructURLBasedOnBaseURL } = require('@playwright/test/lib/utils/utils');3}, 'test');4console.log(url);5const url = await page.evaluate((url) => {6 const { constructURLBasedOnBaseURL } = require('@playwright/test/lib/utils/utils');7console.log(url);8const url = await page.evaluate((url) => {9 const { constructURLBasedOnBaseURL } = require('@playwright/test/lib/utils/utils');10console.log(url);11const url = await page.evaluate((url) => {12 const { constructURLBasedOnBaseURL } = require('@playwright/test/lib/utils/utils');13console.log(url);14const url = await page.evaluate((url) => {15 const { constructURLBasedOnBaseURL } = require('@playwright/test/lib/utils/utils');
Using AI Code Generation
1const internal = require('playwright/lib/internal');2const { constructURLBasedOnBaseURL } = internal;3constructURLBasedOnBaseURL(url, newUrl);4console.log(url);5console.log(newUrl);6console.log(constructURLBasedOnBaseURL(url, newUrl));7const internal = require('playwright/lib/internal');8const { constructURLBasedOnBaseURL } = internal;9console.log(constructURLBasedOnBaseURL(url, newUrl));10const browser = await chromium.launch({ headless: false });11const logs = await page.context().storageState({ path: 'logs.json' });12TypeError: page.context(...).storageState is not a function13const logs = await page.context().storageState({ path: 'logs.json' });14TypeError: page.context(...).storageState is
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!