How to use isInvalidSelectorError method in Playwright Internal

Best JavaScript code snippet using playwright-internal

frames.js

Source:frames.js Github

copy

Full Screen

1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.FrameManager = exports.Frame = 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 _async = require("../utils/async");17var _debugLogger = require("../utils/debugLogger");18var _instrumentation = require("./instrumentation");19var _protocolError = require("./common/protocolError");20var _selectorParser = require("./common/selectorParser");21var _selectorErrors = require("./common/selectorErrors");22function _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); }23function _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; }24/**25 * Copyright 2017 Google Inc. All rights reserved.26 * Modifications copyright (c) Microsoft Corporation.27 *28 * Licensed under the Apache License, Version 2.0 (the "License");29 * you may not use this file except in compliance with the License.30 * You may obtain a copy of the License at31 *32 * http://www.apache.org/licenses/LICENSE-2.033 *34 * Unless required by applicable law or agreed to in writing, software35 * distributed under the License is distributed on an "AS IS" BASIS,36 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.37 * See the License for the specific language governing permissions and38 * limitations under the License.39 */40class FrameManager {41 constructor(page) {42 this._page = void 0;43 this._frames = new Map();44 this._mainFrame = void 0;45 this._consoleMessageTags = new Map();46 this._signalBarriers = new Set();47 this._webSockets = new Map();48 this._dialogCounter = 0;49 this._page = page;50 this._mainFrame = undefined;51 }52 dispose() {53 for (const frame of this._frames.values()) frame._stopNetworkIdleTimer();54 }55 mainFrame() {56 return this._mainFrame;57 }58 frames() {59 const frames = [];60 collect(this._mainFrame);61 return frames;62 function collect(frame) {63 frames.push(frame);64 for (const subframe of frame.childFrames()) collect(subframe);65 }66 }67 frame(frameId) {68 return this._frames.get(frameId) || null;69 }70 frameAttached(frameId, parentFrameId) {71 const parentFrame = parentFrameId ? this._frames.get(parentFrameId) : null;72 if (!parentFrame) {73 if (this._mainFrame) {74 // Update frame id to retain frame identity on cross-process navigation.75 this._frames.delete(this._mainFrame._id);76 this._mainFrame._id = frameId;77 } else {78 (0, _utils.assert)(!this._frames.has(frameId));79 this._mainFrame = new Frame(this._page, frameId, parentFrame);80 }81 this._frames.set(frameId, this._mainFrame);82 return this._mainFrame;83 } else {84 (0, _utils.assert)(!this._frames.has(frameId));85 const frame = new Frame(this._page, frameId, parentFrame);86 this._frames.set(frameId, frame);87 this._page.emit(_page.Page.Events.FrameAttached, frame);88 return frame;89 }90 }91 async waitForSignalsCreatedBy(progress, noWaitAfter, action, source) {92 if (noWaitAfter) return action();93 const barrier = new SignalBarrier(progress);94 this._signalBarriers.add(barrier);95 if (progress) progress.cleanupWhenAborted(() => this._signalBarriers.delete(barrier));96 const result = await action();97 if (source === 'input') await this._page._delegate.inputActionEpilogue();98 await barrier.waitFor();99 this._signalBarriers.delete(barrier); // Resolve in the next task, after all waitForNavigations.100 await new Promise((0, _utils.makeWaitForNextTask)());101 return result;102 }103 frameWillPotentiallyRequestNavigation() {104 for (const barrier of this._signalBarriers) barrier.retain();105 }106 frameDidPotentiallyRequestNavigation() {107 for (const barrier of this._signalBarriers) barrier.release();108 }109 frameRequestedNavigation(frameId, documentId) {110 const frame = this._frames.get(frameId);111 if (!frame) return;112 for (const barrier of this._signalBarriers) barrier.addFrameNavigation(frame);113 if (frame.pendingDocument() && frame.pendingDocument().documentId === documentId) {114 // Do not override request with undefined.115 return;116 }117 frame.setPendingDocument({118 documentId,119 request: undefined120 });121 }122 frameCommittedNewDocumentNavigation(frameId, url, name, documentId, initial) {123 const frame = this._frames.get(frameId);124 this.removeChildFramesRecursively(frame);125 this.clearWebSockets(frame);126 frame._url = url;127 frame._name = name;128 let keepPending;129 const pendingDocument = frame.pendingDocument();130 if (pendingDocument) {131 if (pendingDocument.documentId === undefined) {132 // Pending with unknown documentId - assume it is the one being committed.133 pendingDocument.documentId = documentId;134 }135 if (pendingDocument.documentId === documentId) {136 // Committing a pending document.137 frame._currentDocument = pendingDocument;138 } else {139 // Sometimes, we already have a new pending when the old one commits.140 // An example would be Chromium error page followed by a new navigation request,141 // where the error page commit arrives after Network.requestWillBeSent for the142 // new navigation.143 // We commit, but keep the pending request since it's not done yet.144 keepPending = pendingDocument;145 frame._currentDocument = {146 documentId,147 request: undefined148 };149 }150 frame.setPendingDocument(undefined);151 } else {152 // No pending - just commit a new document.153 frame._currentDocument = {154 documentId,155 request: undefined156 };157 }158 frame._onClearLifecycle();159 const navigationEvent = {160 url,161 name,162 newDocument: frame._currentDocument163 };164 frame.emit(Frame.Events.Navigation, navigationEvent);165 if (!initial) {166 _debugLogger.debugLogger.log('api', ` navigated to "${url}"`);167 this._page.frameNavigatedToNewDocument(frame);168 } // Restore pending if any - see comments above about keepPending.169 frame.setPendingDocument(keepPending);170 }171 frameCommittedSameDocumentNavigation(frameId, url) {172 const frame = this._frames.get(frameId);173 if (!frame) return;174 frame._url = url;175 const navigationEvent = {176 url,177 name: frame._name178 };179 frame.emit(Frame.Events.Navigation, navigationEvent);180 _debugLogger.debugLogger.log('api', ` navigated to "${url}"`);181 }182 frameAbortedNavigation(frameId, errorText, documentId) {183 const frame = this._frames.get(frameId);184 if (!frame || !frame.pendingDocument()) return;185 if (documentId !== undefined && frame.pendingDocument().documentId !== documentId) return;186 const navigationEvent = {187 url: frame._url,188 name: frame._name,189 newDocument: frame.pendingDocument(),190 error: new Error(errorText)191 };192 frame.setPendingDocument(undefined);193 frame.emit(Frame.Events.Navigation, navigationEvent);194 }195 frameDetached(frameId) {196 const frame = this._frames.get(frameId);197 if (frame) this._removeFramesRecursively(frame);198 }199 frameStoppedLoading(frameId) {200 this.frameLifecycleEvent(frameId, 'domcontentloaded');201 this.frameLifecycleEvent(frameId, 'load');202 }203 frameLifecycleEvent(frameId, event) {204 const frame = this._frames.get(frameId);205 if (frame) frame._onLifecycleEvent(event);206 }207 requestStarted(request, route) {208 const frame = request.frame();209 this._inflightRequestStarted(request);210 if (request._documentId) frame.setPendingDocument({211 documentId: request._documentId,212 request213 });214 if (request._isFavicon) {215 if (route) route.continue(request, {});216 return;217 }218 this._page._browserContext.emit(_browserContext.BrowserContext.Events.Request, request);219 if (route) this._page._requestStarted(request, route);220 }221 requestReceivedResponse(response) {222 if (response.request()._isFavicon) return;223 this._page._browserContext.emit(_browserContext.BrowserContext.Events.Response, response);224 }225 reportRequestFinished(request, response) {226 this._inflightRequestFinished(request);227 if (request._isFavicon) return;228 this._page._browserContext.emit(_browserContext.BrowserContext.Events.RequestFinished, {229 request,230 response231 });232 }233 requestFailed(request, canceled) {234 const frame = request.frame();235 this._inflightRequestFinished(request);236 if (frame.pendingDocument() && frame.pendingDocument().request === request) {237 let errorText = request.failure().errorText;238 if (canceled) errorText += '; maybe frame was detached?';239 this.frameAbortedNavigation(frame._id, errorText, frame.pendingDocument().documentId);240 }241 if (request._isFavicon) return;242 this._page._browserContext.emit(_browserContext.BrowserContext.Events.RequestFailed, request);243 }244 dialogDidOpen() {245 // Any ongoing evaluations will be stalled until the dialog is closed.246 for (const frame of this._frames.values()) frame._invalidateNonStallingEvaluations('JavaScript dialog interrupted evaluation');247 this._dialogCounter++;248 }249 dialogWillClose() {250 this._dialogCounter--;251 }252 removeChildFramesRecursively(frame) {253 for (const child of frame.childFrames()) this._removeFramesRecursively(child);254 }255 _removeFramesRecursively(frame) {256 this.removeChildFramesRecursively(frame);257 frame._onDetached();258 this._frames.delete(frame._id);259 if (!this._page.isClosed()) this._page.emit(_page.Page.Events.FrameDetached, frame);260 }261 _inflightRequestFinished(request) {262 const frame = request.frame();263 if (request._isFavicon) return;264 if (!frame._inflightRequests.has(request)) return;265 frame._inflightRequests.delete(request);266 if (frame._inflightRequests.size === 0) frame._startNetworkIdleTimer();267 }268 _inflightRequestStarted(request) {269 const frame = request.frame();270 if (request._isFavicon) return;271 frame._inflightRequests.add(request);272 if (frame._inflightRequests.size === 1) frame._stopNetworkIdleTimer();273 }274 interceptConsoleMessage(message) {275 if (message.type() !== 'debug') return false;276 const tag = message.text();277 const handler = this._consoleMessageTags.get(tag);278 if (!handler) return false;279 this._consoleMessageTags.delete(tag);280 handler();281 return true;282 }283 clearWebSockets(frame) {284 // TODO: attribute sockets to frames.285 if (frame.parentFrame()) return;286 this._webSockets.clear();287 }288 onWebSocketCreated(requestId, url) {289 const ws = new network.WebSocket(this._page, url);290 this._webSockets.set(requestId, ws);291 }292 onWebSocketRequest(requestId) {293 const ws = this._webSockets.get(requestId);294 if (ws && ws.markAsNotified()) this._page.emit(_page.Page.Events.WebSocket, ws);295 }296 onWebSocketResponse(requestId, status, statusText) {297 const ws = this._webSockets.get(requestId);298 if (status < 400) return;299 if (ws) ws.error(`${statusText}: ${status}`);300 }301 onWebSocketFrameSent(requestId, opcode, data) {302 const ws = this._webSockets.get(requestId);303 if (ws) ws.frameSent(opcode, data);304 }305 webSocketFrameReceived(requestId, opcode, data) {306 const ws = this._webSockets.get(requestId);307 if (ws) ws.frameReceived(opcode, data);308 }309 webSocketClosed(requestId) {310 const ws = this._webSockets.get(requestId);311 if (ws) ws.closed();312 this._webSockets.delete(requestId);313 }314 webSocketError(requestId, errorMessage) {315 const ws = this._webSockets.get(requestId);316 if (ws) ws.error(errorMessage);317 }318}319exports.FrameManager = FrameManager;320class Frame extends _instrumentation.SdkObject {321 constructor(page, id, parentFrame) {322 super(page, 'frame');323 this._id = void 0;324 this._firedLifecycleEvents = new Set();325 this._subtreeLifecycleEvents = new Set();326 this._currentDocument = void 0;327 this._pendingDocument = void 0;328 this._page = void 0;329 this._parentFrame = void 0;330 this._url = '';331 this._detached = false;332 this._contextData = new Map();333 this._childFrames = new Set();334 this._name = '';335 this._inflightRequests = new Set();336 this._networkIdleTimer = void 0;337 this._setContentCounter = 0;338 this._detachedPromise = void 0;339 this._detachedCallback = () => {};340 this._nonStallingEvaluations = new Set();341 this.attribution.frame = this;342 this._id = id;343 this._page = page;344 this._parentFrame = parentFrame;345 this._currentDocument = {346 documentId: undefined,347 request: undefined348 };349 this._detachedPromise = new Promise(x => this._detachedCallback = x);350 this._contextData.set('main', {351 contextPromise: new _async.ManualPromise(),352 context: null,353 rerunnableTasks: new Set()354 });355 this._contextData.set('utility', {356 contextPromise: new _async.ManualPromise(),357 context: null,358 rerunnableTasks: new Set()359 });360 this._setContext('main', null);361 this._setContext('utility', null);362 if (this._parentFrame) this._parentFrame._childFrames.add(this);363 this._firedLifecycleEvents.add('commit');364 this._subtreeLifecycleEvents.add('commit');365 }366 isDetached() {367 return this._detached;368 }369 _onLifecycleEvent(event) {370 if (this._firedLifecycleEvents.has(event)) return;371 this._firedLifecycleEvents.add(event); // Recalculate subtree lifecycle for the whole tree - it should not be that big.372 this._page.mainFrame()._recalculateLifecycle();373 }374 _onClearLifecycle() {375 this._firedLifecycleEvents.clear(); // Recalculate subtree lifecycle for the whole tree - it should not be that big.376 this._page.mainFrame()._recalculateLifecycle(); // Keep the current navigation request if any.377 this._inflightRequests = new Set(Array.from(this._inflightRequests).filter(request => request === this._currentDocument.request));378 this._stopNetworkIdleTimer();379 if (this._inflightRequests.size === 0) this._startNetworkIdleTimer();380 this._onLifecycleEvent('commit');381 }382 setPendingDocument(documentInfo) {383 this._pendingDocument = documentInfo;384 if (documentInfo) this._invalidateNonStallingEvaluations('Navigation interrupted the evaluation');385 }386 pendingDocument() {387 return this._pendingDocument;388 }389 _invalidateNonStallingEvaluations(message) {390 if (!this._nonStallingEvaluations) return;391 const error = new Error(message);392 for (const callback of this._nonStallingEvaluations) callback(error);393 }394 async nonStallingRawEvaluateInExistingMainContext(expression) {395 if (this._pendingDocument) throw new Error('Frame is currently attempting a navigation');396 if (this._page._frameManager._dialogCounter) throw new Error('Open JavaScript dialog prevents evaluation');397 const context = this._existingMainContext();398 if (!context) throw new Error('Frame does not yet have a main execution context');399 let callback = () => {};400 const frameInvalidated = new Promise((f, r) => callback = r);401 this._nonStallingEvaluations.add(callback);402 try {403 return await Promise.race([context.rawEvaluateJSON(expression), frameInvalidated]);404 } finally {405 this._nonStallingEvaluations.delete(callback);406 }407 }408 async nonStallingEvaluateInExistingContext(expression, isFunction, world) {409 var _this$_contextData$ge;410 if (this._pendingDocument) throw new Error('Frame is currently attempting a navigation');411 const context = (_this$_contextData$ge = this._contextData.get(world)) === null || _this$_contextData$ge === void 0 ? void 0 : _this$_contextData$ge.context;412 if (!context) throw new Error('Frame does not yet have the execution context');413 let callback = () => {};414 const frameInvalidated = new Promise((f, r) => callback = r);415 this._nonStallingEvaluations.add(callback);416 try {417 return await Promise.race([context.evaluateExpression(expression, isFunction), frameInvalidated]);418 } finally {419 this._nonStallingEvaluations.delete(callback);420 }421 }422 _recalculateLifecycle() {423 const events = new Set(this._firedLifecycleEvents);424 for (const child of this._childFrames) {425 child._recalculateLifecycle(); // We require a particular lifecycle event to be fired in the whole426 // frame subtree, and then consider it done.427 for (const event of events) {428 if (!child._subtreeLifecycleEvents.has(event)) events.delete(event);429 }430 }431 const mainFrame = this._page.mainFrame();432 for (const event of events) {433 // Checking whether we have already notified about this event.434 if (!this._subtreeLifecycleEvents.has(event)) {435 this.emit(Frame.Events.AddLifecycle, event);436 if (this === mainFrame && this._url !== 'about:blank') _debugLogger.debugLogger.log('api', ` "${event}" event fired`);437 if (this === mainFrame && event === 'load') this._page.emit(_page.Page.Events.Load);438 if (this === mainFrame && event === 'domcontentloaded') this._page.emit(_page.Page.Events.DOMContentLoaded);439 }440 }441 for (const event of this._subtreeLifecycleEvents) {442 if (!events.has(event)) this.emit(Frame.Events.RemoveLifecycle, event);443 }444 this._subtreeLifecycleEvents = events;445 }446 async raceNavigationAction(action) {447 return Promise.race([this._page._disconnectedPromise.then(() => {448 throw new Error('Navigation failed because page was closed!');449 }), this._page._crashedPromise.then(() => {450 throw new Error('Navigation failed because page crashed!');451 }), this._detachedPromise.then(() => {452 throw new Error('Navigating frame was detached!');453 }), action()]);454 }455 async goto(metadata, url, options = {}) {456 const constructedNavigationURL = (0, _utils.constructURLBasedOnBaseURL)(this._page._browserContext._options.baseURL, url);457 const controller = new _progress.ProgressController(metadata, this);458 return controller.run(progress => this._goto(progress, constructedNavigationURL, options), this._page._timeoutSettings.navigationTimeout(options));459 }460 async _goto(progress, url, options) {461 return this.raceNavigationAction(async () => {462 const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);463 progress.log(`navigating to "${url}", waiting until "${waitUntil}"`);464 const headers = this._page._state.extraHTTPHeaders || [];465 const refererHeader = headers.find(h => h.name.toLowerCase() === 'referer');466 let referer = refererHeader ? refererHeader.value : undefined;467 if (options.referer !== undefined) {468 if (referer !== undefined && referer !== options.referer) throw new Error('"referer" is already specified as extra HTTP header');469 referer = options.referer;470 }471 url = _helper.helper.completeUserURL(url);472 const sameDocument = _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, e => !e.newDocument);473 const navigateResult = await this._page._delegate.navigateFrame(this, url, referer);474 let event;475 if (navigateResult.newDocumentId) {476 sameDocument.dispose();477 event = await _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, event => {478 // We are interested either in this specific document, or any other document that479 // did commit and replaced the expected document.480 return event.newDocument && (event.newDocument.documentId === navigateResult.newDocumentId || !event.error);481 }).promise;482 if (event.newDocument.documentId !== navigateResult.newDocumentId) {483 // This is just a sanity check. In practice, new navigation should484 // cancel the previous one and report "request cancelled"-like error.485 throw new Error('Navigation interrupted by another one');486 }487 if (event.error) throw event.error;488 } else {489 event = await sameDocument.promise;490 }491 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;492 const request = event.newDocument ? event.newDocument.request : undefined;493 const response = request ? request._finalRequest().response() : null;494 await this._page._doSlowMo();495 return response;496 });497 }498 async _waitForNavigation(progress, options) {499 const waitUntil = verifyLifecycle('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);500 progress.log(`waiting for navigation until "${waitUntil}"`);501 const navigationEvent = await _helper.helper.waitForEvent(progress, this, Frame.Events.Navigation, event => {502 // Any failed navigation results in a rejection.503 if (event.error) return true;504 progress.log(` navigated to "${this._url}"`);505 return true;506 }).promise;507 if (navigationEvent.error) throw navigationEvent.error;508 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;509 const request = navigationEvent.newDocument ? navigationEvent.newDocument.request : undefined;510 return request ? request._finalRequest().response() : null;511 }512 async _waitForLoadState(progress, state) {513 const waitUntil = verifyLifecycle('state', state);514 if (!this._subtreeLifecycleEvents.has(waitUntil)) await _helper.helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, e => e === waitUntil).promise;515 }516 async frameElement() {517 return this._page._delegate.getFrameElement(this);518 }519 _context(world) {520 return this._contextData.get(world).contextPromise.then(contextOrError => {521 if (contextOrError instanceof js.ExecutionContext) return contextOrError;522 throw contextOrError;523 });524 }525 _mainContext() {526 return this._context('main');527 }528 _existingMainContext() {529 var _this$_contextData$ge2;530 return ((_this$_contextData$ge2 = this._contextData.get('main')) === null || _this$_contextData$ge2 === void 0 ? void 0 : _this$_contextData$ge2.context) || null;531 }532 _utilityContext() {533 return this._context('utility');534 }535 async evaluateExpressionHandleAndWaitForSignals(expression, isFunction, arg, world = 'main') {536 const context = await this._context(world);537 const handle = await context.evaluateExpressionHandleAndWaitForSignals(expression, isFunction, arg);538 if (world === 'main') await this._page._doSlowMo();539 return handle;540 }541 async evaluateExpression(expression, isFunction, arg, world = 'main') {542 const context = await this._context(world);543 const value = await context.evaluateExpression(expression, isFunction, arg);544 if (world === 'main') await this._page._doSlowMo();545 return value;546 }547 async evaluateExpressionAndWaitForSignals(expression, isFunction, arg, world = 'main') {548 const context = await this._context(world);549 const value = await context.evaluateExpressionAndWaitForSignals(expression, isFunction, arg);550 if (world === 'main') await this._page._doSlowMo();551 return value;552 }553 async querySelector(selector, options) {554 _debugLogger.debugLogger.log('api', ` finding element using the selector "${selector}"`);555 const result = await this.resolveFrameForSelectorNoWait(selector, options);556 if (!result) return null;557 return this._page.selectors.query(result.frame, result.info);558 }559 async waitForSelector(metadata, selector, options, scope) {560 const controller = new _progress.ProgressController(metadata, this);561 if (options.visibility) throw new Error('options.visibility is not supported, did you mean options.state?');562 if (options.waitFor && options.waitFor !== 'visible') throw new Error('options.waitFor is not supported, did you mean options.state?');563 const {564 state = 'visible'565 } = options;566 if (!['attached', 'detached', 'visible', 'hidden'].includes(state)) throw new Error(`state: expected one of (attached|detached|visible|hidden)`);567 return controller.run(async progress => {568 progress.log(`waiting for selector "${selector}"${state === 'attached' ? '' : ' to be ' + state}`);569 return this.retryWithProgress(progress, selector, options, async (selectorInFrame, continuePolling) => {570 // Be careful, |this| can be different from |frame|.571 // We did not pass omitAttached, so it is non-null.572 const {573 frame,574 info575 } = selectorInFrame;576 const actualScope = this === frame ? scope : undefined;577 const task = dom.waitForSelectorTask(info, state, options.omitReturnValue, actualScope);578 const result = actualScope ? await frame._runWaitForSelectorTaskOnce(progress, (0, _selectorParser.stringifySelector)(info.parsed), info.world, task) : await frame._scheduleRerunnableHandleTask(progress, info.world, task);579 if (!result.asElement()) {580 result.dispose();581 return null;582 }583 if (options.__testHookBeforeAdoptNode) await options.__testHookBeforeAdoptNode();584 const handle = result.asElement();585 try {586 return await handle._adoptTo(await frame._mainContext());587 } catch (e) {588 return continuePolling;589 }590 }, scope);591 }, this._page._timeoutSettings.timeout(options));592 }593 async dispatchEvent(metadata, selector, type, eventInit = {}, options = {}) {594 await this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => {595 progress.injectedScript.dispatchEvent(element, data.type, data.eventInit);596 }, {597 type,598 eventInit599 }, {600 mainWorld: true,601 ...options602 });603 await this._page._doSlowMo();604 }605 async evalOnSelectorAndWaitForSignals(selector, strict, expression, isFunction, arg) {606 const pair = await this.resolveFrameForSelectorNoWait(selector, {607 strict608 });609 const handle = pair ? await this._page.selectors.query(pair.frame, pair.info) : null;610 if (!handle) throw new Error(`Error: failed to find element matching selector "${selector}"`);611 const result = await handle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);612 handle.dispose();613 return result;614 }615 async evalOnSelectorAllAndWaitForSignals(selector, expression, isFunction, arg) {616 const pair = await this.resolveFrameForSelectorNoWait(selector, {});617 if (!pair) throw new Error(`Error: failed to find frame for selector "${selector}"`);618 const arrayHandle = await this._page.selectors._queryArrayInMainWorld(pair.frame, pair.info);619 const result = await arrayHandle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);620 arrayHandle.dispose();621 return result;622 }623 async querySelectorAll(selector) {624 const pair = await this.resolveFrameForSelectorNoWait(selector, {});625 if (!pair) return [];626 return this._page.selectors._queryAll(pair.frame, pair.info, undefined, true627 /* adoptToMain */628 );629 }630 async queryCount(selector) {631 const pair = await this.resolveFrameForSelectorNoWait(selector);632 if (!pair) throw new Error(`Error: failed to find frame for selector "${selector}"`);633 return await this._page.selectors._queryCount(pair.frame, pair.info);634 }635 async content() {636 try {637 const context = await this._utilityContext();638 return await context.evaluate(() => {639 let retVal = '';640 if (document.doctype) retVal = new XMLSerializer().serializeToString(document.doctype);641 if (document.documentElement) retVal += document.documentElement.outerHTML;642 return retVal;643 });644 } catch (e) {645 if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) throw e;646 throw new Error(`Unable to retrieve content because the page is navigating and changing the content.`);647 }648 }649 async setContent(metadata, html, options = {}) {650 const controller = new _progress.ProgressController(metadata, this);651 return controller.run(progress => this.raceNavigationAction(async () => {652 const waitUntil = options.waitUntil === undefined ? 'load' : options.waitUntil;653 progress.log(`setting frame content, waiting until "${waitUntil}"`);654 const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;655 const context = await this._utilityContext();656 const lifecyclePromise = new Promise((resolve, reject) => {657 this._page._frameManager._consoleMessageTags.set(tag, () => {658 // Clear lifecycle right after document.open() - see 'tag' below.659 this._onClearLifecycle();660 this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);661 });662 });663 const contentPromise = context.evaluate(({664 html,665 tag666 }) => {667 window.stop();668 document.open();669 console.debug(tag); // eslint-disable-line no-console670 document.write(html);671 document.close();672 }, {673 html,674 tag675 });676 await Promise.all([contentPromise, lifecyclePromise]);677 await this._page._doSlowMo();678 }), this._page._timeoutSettings.navigationTimeout(options));679 }680 name() {681 return this._name || '';682 }683 url() {684 return this._url;685 }686 parentFrame() {687 return this._parentFrame;688 }689 childFrames() {690 return Array.from(this._childFrames);691 }692 async addScriptTag(params) {693 const {694 url = null,695 content = null,696 type = ''697 } = params;698 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');699 const context = await this._mainContext();700 return this._raceWithCSPError(async () => {701 if (url !== null) return (await context.evaluateHandle(addScriptUrl, {702 url,703 type704 })).asElement();705 const result = (await context.evaluateHandle(addScriptContent, {706 content: content,707 type708 })).asElement(); // Another round trip to the browser to ensure that we receive CSP error messages709 // (if any) logged asynchronously in a separate task on the content main thread.710 if (this._page._delegate.cspErrorsAsynchronousForInlineScipts) await context.evaluate(() => true);711 return result;712 });713 async function addScriptUrl(params) {714 const script = document.createElement('script');715 script.src = params.url;716 if (params.type) script.type = params.type;717 const promise = new Promise((res, rej) => {718 script.onload = res;719 script.onerror = e => rej(typeof e === 'string' ? new Error(e) : new Error(`Failed to load script at ${script.src}`));720 });721 document.head.appendChild(script);722 await promise;723 return script;724 }725 function addScriptContent(params) {726 const script = document.createElement('script');727 script.type = params.type || 'text/javascript';728 script.text = params.content;729 let error = null;730 script.onerror = e => error = e;731 document.head.appendChild(script);732 if (error) throw error;733 return script;734 }735 }736 async addStyleTag(params) {737 const {738 url = null,739 content = null740 } = params;741 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');742 const context = await this._mainContext();743 return this._raceWithCSPError(async () => {744 if (url !== null) return (await context.evaluateHandle(addStyleUrl, url)).asElement();745 return (await context.evaluateHandle(addStyleContent, content)).asElement();746 });747 async function addStyleUrl(url) {748 const link = document.createElement('link');749 link.rel = 'stylesheet';750 link.href = url;751 const promise = new Promise((res, rej) => {752 link.onload = res;753 link.onerror = rej;754 });755 document.head.appendChild(link);756 await promise;757 return link;758 }759 async function addStyleContent(content) {760 const style = document.createElement('style');761 style.type = 'text/css';762 style.appendChild(document.createTextNode(content));763 const promise = new Promise((res, rej) => {764 style.onload = res;765 style.onerror = rej;766 });767 document.head.appendChild(style);768 await promise;769 return style;770 }771 }772 async _raceWithCSPError(func) {773 const listeners = [];774 let result;775 let error;776 let cspMessage;777 const actionPromise = func().then(r => result = r).catch(e => error = e);778 const errorPromise = new Promise(resolve => {779 listeners.push(_eventsHelper.eventsHelper.addEventListener(this._page, _page.Page.Events.Console, message => {780 if (message.type() === 'error' && message.text().includes('Content Security Policy')) {781 cspMessage = message;782 resolve();783 }784 }));785 });786 await Promise.race([actionPromise, errorPromise]);787 _eventsHelper.eventsHelper.removeEventListeners(listeners);788 if (cspMessage) throw new Error(cspMessage.text());789 if (error) throw error;790 return result;791 }792 async retryWithProgress(progress, selector, options, action, scope) {793 const continuePolling = Symbol('continuePolling');794 while (progress.isRunning()) {795 let selectorInFrame;796 if (options.omitAttached) {797 selectorInFrame = await this.resolveFrameForSelectorNoWait(selector, options, scope);798 } else {799 selectorInFrame = await this._resolveFrameForSelector(progress, selector, options, scope);800 if (!selectorInFrame) {801 // Missing content frame.802 await new Promise(f => setTimeout(f, 100));803 continue;804 }805 }806 try {807 const result = await action(selectorInFrame, continuePolling);808 if (result === continuePolling) continue;809 return result;810 } catch (e) {811 var _selectorInFrame;812 // Always fail on JavaScript errors or when the main connection is closed.813 if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) throw e; // Certain error opt-out of the retries, throw.814 if (dom.isNonRecoverableDOMError(e)) throw e; // If the call is made on the detached frame - throw.815 if (this.isDetached()) throw e; // If there is scope, and scope is within the frame we use to select, assume context is destroyed and816 // operation is not recoverable.817 if (scope && scope._context.frame === ((_selectorInFrame = selectorInFrame) === null || _selectorInFrame === void 0 ? void 0 : _selectorInFrame.frame)) throw e; // Retry upon all other errors.818 continue;819 }820 }821 progress.throwIfAborted();822 return undefined;823 }824 async _retryWithProgressIfNotConnected(progress, selector, strict, action) {825 return this.retryWithProgress(progress, selector, {826 strict827 }, async (selectorInFrame, continuePolling) => {828 // We did not pass omitAttached, so selectorInFrame is not null.829 const {830 frame,831 info832 } = selectorInFrame; // Be careful, |this| can be different from |frame|.833 const task = dom.waitForSelectorTask(info, 'attached');834 progress.log(`waiting for selector "${selector}"`);835 const handle = await frame._scheduleRerunnableHandleTask(progress, info.world, task);836 const element = handle.asElement();837 try {838 const result = await action(element);839 if (result === 'error:notconnected') {840 progress.log('element was detached from the DOM, retrying');841 return continuePolling;842 }843 return result;844 } finally {845 element === null || element === void 0 ? void 0 : element.dispose();846 }847 });848 }849 async click(metadata, selector, options) {850 const controller = new _progress.ProgressController(metadata, this);851 return controller.run(async progress => {852 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._click(progress, options)));853 }, this._page._timeoutSettings.timeout(options));854 }855 async dblclick(metadata, selector, options = {}) {856 const controller = new _progress.ProgressController(metadata, this);857 return controller.run(async progress => {858 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._dblclick(progress, options)));859 }, this._page._timeoutSettings.timeout(options));860 }861 async dragAndDrop(metadata, source, target, options = {}) {862 const controller = new _progress.ProgressController(metadata, this);863 await controller.run(async progress => {864 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, async handle => {865 return handle._retryPointerAction(progress, 'move and down', false, async point => {866 await this._page.mouse.move(point.x, point.y);867 await this._page.mouse.down();868 }, { ...options,869 position: options.sourcePosition,870 timeout: progress.timeUntilDeadline()871 });872 }));873 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, async handle => {874 return handle._retryPointerAction(progress, 'move and up', false, async point => {875 await this._page.mouse.move(point.x, point.y);876 await this._page.mouse.up();877 }, { ...options,878 position: options.targetPosition,879 timeout: progress.timeUntilDeadline()880 });881 }));882 }, this._page._timeoutSettings.timeout(options));883 }884 async tap(metadata, selector, options) {885 const controller = new _progress.ProgressController(metadata, this);886 return controller.run(async progress => {887 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._tap(progress, options)));888 }, this._page._timeoutSettings.timeout(options));889 }890 async fill(metadata, selector, value, options) {891 const controller = new _progress.ProgressController(metadata, this);892 return controller.run(async progress => {893 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._fill(progress, value, options)));894 }, this._page._timeoutSettings.timeout(options));895 }896 async focus(metadata, selector, options = {}) {897 const controller = new _progress.ProgressController(metadata, this);898 await controller.run(async progress => {899 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._focus(progress)));900 await this._page._doSlowMo();901 }, this._page._timeoutSettings.timeout(options));902 }903 async textContent(metadata, selector, options = {}) {904 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.textContent, undefined, options);905 }906 async innerText(metadata, selector, options = {}) {907 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => {908 if (element.namespaceURI !== 'http://www.w3.org/1999/xhtml') throw progress.injectedScript.createStacklessError('Node is not an HTMLElement');909 return element.innerText;910 }, undefined, options);911 }912 async innerHTML(metadata, selector, options = {}) {913 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.innerHTML, undefined, options);914 }915 async getAttribute(metadata, selector, name, options = {}) {916 return this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => element.getAttribute(data.name), {917 name918 }, options);919 }920 async inputValue(metadata, selector, options = {}) {921 return this._scheduleRerunnableTask(metadata, selector, (progress, node) => {922 const element = progress.injectedScript.retarget(node, 'follow-label');923 if (!element || element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT') throw progress.injectedScript.createStacklessError('Node is not an <input>, <textarea> or <select> element');924 return element.value;925 }, undefined, options);926 }927 async highlight(selector) {928 const pair = await this.resolveFrameForSelectorNoWait(selector);929 if (!pair) return;930 const context = await this._utilityContext();931 const injectedScript = await context.injectedScript();932 return await injectedScript.evaluate((injected, {933 parsed934 }) => {935 return injected.highlight(parsed);936 }, {937 parsed: pair.info.parsed938 });939 }940 async hideHighlight() {941 const context = await this._utilityContext();942 const injectedScript = await context.injectedScript();943 return await injectedScript.evaluate(injected => {944 return injected.hideHighlight();945 });946 }947 async _elementState(metadata, selector, state, options = {}) {948 const result = await this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => {949 const injected = progress.injectedScript;950 return injected.elementState(element, data.state);951 }, {952 state953 }, options);954 return dom.throwRetargetableDOMError(result);955 }956 async isVisible(metadata, selector, options = {}) {957 const controller = new _progress.ProgressController(metadata, this);958 return controller.run(async progress => {959 progress.log(` checking visibility of "${selector}"`);960 const pair = await this.resolveFrameForSelectorNoWait(selector, options);961 if (!pair) return false;962 const element = await this._page.selectors.query(pair.frame, pair.info);963 return element ? await element.isVisible() : false;964 }, this._page._timeoutSettings.timeout({}));965 }966 async isHidden(metadata, selector, options = {}) {967 return !(await this.isVisible(metadata, selector, options));968 }969 async isDisabled(metadata, selector, options = {}) {970 return this._elementState(metadata, selector, 'disabled', options);971 }972 async isEnabled(metadata, selector, options = {}) {973 return this._elementState(metadata, selector, 'enabled', options);974 }975 async isEditable(metadata, selector, options = {}) {976 return this._elementState(metadata, selector, 'editable', options);977 }978 async isChecked(metadata, selector, options = {}) {979 return this._elementState(metadata, selector, 'checked', options);980 }981 async hover(metadata, selector, options = {}) {982 const controller = new _progress.ProgressController(metadata, this);983 return controller.run(async progress => {984 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options)));985 }, this._page._timeoutSettings.timeout(options));986 }987 async selectOption(metadata, selector, elements, values, options = {}) {988 const controller = new _progress.ProgressController(metadata, this);989 return controller.run(async progress => {990 return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._selectOption(progress, elements, values, options));991 }, this._page._timeoutSettings.timeout(options));992 }993 async setInputFiles(metadata, selector, files, options = {}) {994 const controller = new _progress.ProgressController(metadata, this);995 return controller.run(async progress => {996 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setInputFiles(progress, files, options)));997 }, this._page._timeoutSettings.timeout(options));998 }999 async type(metadata, selector, text, options = {}) {1000 const controller = new _progress.ProgressController(metadata, this);1001 return controller.run(async progress => {1002 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._type(progress, text, options)));1003 }, this._page._timeoutSettings.timeout(options));1004 }1005 async press(metadata, selector, key, options = {}) {1006 const controller = new _progress.ProgressController(metadata, this);1007 return controller.run(async progress => {1008 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._press(progress, key, options)));1009 }, this._page._timeoutSettings.timeout(options));1010 }1011 async check(metadata, selector, options = {}) {1012 const controller = new _progress.ProgressController(metadata, this);1013 return controller.run(async progress => {1014 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, true, options)));1015 }, this._page._timeoutSettings.timeout(options));1016 }1017 async uncheck(metadata, selector, options = {}) {1018 const controller = new _progress.ProgressController(metadata, this);1019 return controller.run(async progress => {1020 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, false, options)));1021 }, this._page._timeoutSettings.timeout(options));1022 }1023 async waitForTimeout(metadata, timeout) {1024 const controller = new _progress.ProgressController(metadata, this);1025 return controller.run(async () => {1026 await new Promise(resolve => setTimeout(resolve, timeout));1027 });1028 }1029 async expect(metadata, selector, options) {1030 const controller = new _progress.ProgressController(metadata, this);1031 const isArray = options.expression === 'to.have.count' || options.expression.endsWith('.array');1032 const mainWorld = options.expression === 'to.have.property';1033 const timeout = this._page._timeoutSettings.timeout(options); // List all combinations that are satisfied with the detached node(s).1034 let omitAttached = false;1035 if (!options.isNot && options.expression === 'to.be.hidden') omitAttached = true;else if (options.isNot && options.expression === 'to.be.visible') omitAttached = true;else if (!options.isNot && options.expression === 'to.have.count' && options.expectedNumber === 0) omitAttached = true;else if (options.isNot && options.expression === 'to.have.count' && options.expectedNumber !== 0) omitAttached = true;else if (!options.isNot && options.expression.endsWith('.array') && options.expectedText.length === 0) omitAttached = true;else if (options.isNot && options.expression.endsWith('.array') && options.expectedText.length > 0) omitAttached = true;1036 return controller.run(async outerProgress => {1037 outerProgress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`);1038 return await this._scheduleRerunnableTaskWithProgress(outerProgress, selector, (progress, element, options, elements) => {1039 let result;1040 if (options.isArray) {1041 result = progress.injectedScript.expectArray(elements, options);1042 } else {1043 if (!element) {1044 // expect(locator).toBeHidden() passes when there is no element.1045 if (!options.isNot && options.expression === 'to.be.hidden') return {1046 matches: true1047 }; // expect(locator).not.toBeVisible() passes when there is no element.1048 if (options.isNot && options.expression === 'to.be.visible') return {1049 matches: false1050 }; // When none of the above applies, keep waiting for the element.1051 return progress.continuePolling;1052 }1053 result = progress.injectedScript.expectSingleElement(progress, element, options);1054 }1055 if (result.matches === options.isNot) {1056 // Keep waiting in these cases:1057 // expect(locator).conditionThatDoesNotMatch1058 // expect(locator).not.conditionThatDoesMatch1059 progress.setIntermediateResult(result.received);1060 if (!Array.isArray(result.received)) progress.log(` unexpected value "${result.received}"`);1061 return progress.continuePolling;1062 } // Reached the expected state!1063 return result;1064 }, { ...options,1065 isArray1066 }, {1067 strict: true,1068 querySelectorAll: isArray,1069 mainWorld,1070 omitAttached,1071 logScale: true,1072 ...options1073 });1074 }, timeout).catch(e => {1075 // Q: Why not throw upon isSessionClosedError(e) as in other places?1076 // A: We want user to receive a friendly message containing the last intermediate result.1077 if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorErrors.isInvalidSelectorError)(e)) throw e;1078 return {1079 received: controller.lastIntermediateResult(),1080 matches: options.isNot,1081 log: metadata.log1082 };1083 });1084 }1085 async _waitForFunctionExpression(metadata, expression, isFunction, arg, options, world = 'main') {1086 const controller = new _progress.ProgressController(metadata, this);1087 if (typeof options.pollingInterval === 'number') (0, _utils.assert)(options.pollingInterval > 0, 'Cannot poll with non-positive interval: ' + options.pollingInterval);1088 expression = js.normalizeEvaluationExpression(expression, isFunction);1089 const task = injectedScript => injectedScript.evaluateHandle((injectedScript, {1090 expression,1091 isFunction,1092 polling,1093 arg1094 }) => {1095 const predicate = arg => {1096 let result = self.eval(expression);1097 if (isFunction === true) {1098 result = result(arg);1099 } else if (isFunction === false) {1100 result = result;1101 } else {1102 // auto detect.1103 if (typeof result === 'function') result = result(arg);1104 }1105 return result;1106 };1107 if (typeof polling !== 'number') return injectedScript.pollRaf(progress => predicate(arg) || progress.continuePolling);1108 return injectedScript.pollInterval(polling, progress => predicate(arg) || progress.continuePolling);1109 }, {1110 expression,1111 isFunction,1112 polling: options.pollingInterval,1113 arg1114 });1115 return controller.run(progress => this._scheduleRerunnableHandleTask(progress, world, task), this._page._timeoutSettings.timeout(options));1116 }1117 async waitForFunctionValueInUtility(progress, pageFunction) {1118 const expression = `() => {1119 const result = (${pageFunction})();1120 if (!result)1121 return result;1122 return JSON.stringify(result);1123 }`;1124 const handle = await this._waitForFunctionExpression((0, _instrumentation.internalCallMetadata)(), expression, true, undefined, {1125 timeout: progress.timeUntilDeadline()1126 }, 'utility');1127 return JSON.parse(handle.rawValue());1128 }1129 async title() {1130 const context = await this._utilityContext();1131 return context.evaluate(() => document.title);1132 }1133 _onDetached() {1134 this._stopNetworkIdleTimer();1135 this._detached = true;1136 this._detachedCallback();1137 const error = new Error('Frame was detached');1138 for (const data of this._contextData.values()) {1139 if (data.context) data.context.contextDestroyed(error);1140 data.contextPromise.resolve(error);1141 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.terminate(error);1142 }1143 if (this._parentFrame) this._parentFrame._childFrames.delete(this);1144 this._parentFrame = null;1145 }1146 async _scheduleRerunnableTask(metadata, selector, body, taskData, options = {}) {1147 const controller = new _progress.ProgressController(metadata, this);1148 return controller.run(async progress => {1149 return await this._scheduleRerunnableTaskWithProgress(progress, selector, body, taskData, options);1150 }, this._page._timeoutSettings.timeout(options));1151 }1152 async _scheduleRerunnableTaskWithProgress(progress, selector, body, taskData, options = {}) {1153 const callbackText = body.toString();1154 return this.retryWithProgress(progress, selector, options, async selectorInFrame => {1155 // Be careful, |this| can be different from |frame|.1156 progress.log(`waiting for selector "${selector}"`);1157 const {1158 frame,1159 info1160 } = selectorInFrame || {1161 frame: this,1162 info: {1163 parsed: {1164 parts: [{1165 name: 'control',1166 body: 'return-empty',1167 source: 'control=return-empty'1168 }]1169 },1170 world: 'utility',1171 strict: !!options.strict1172 }1173 };1174 return await frame._scheduleRerunnableTaskInFrame(progress, info, callbackText, taskData, options);1175 });1176 }1177 async _scheduleRerunnableTaskInFrame(progress, info, callbackText, taskData, options) {1178 progress.throwIfAborted();1179 const data = this._contextData.get(options.mainWorld ? 'main' : info.world); // This potentially runs in a sub-frame.1180 {1181 const rerunnableTask = new RerunnableTask(data, progress, injectedScript => {1182 return injectedScript.evaluateHandle((injected, {1183 info,1184 taskData,1185 callbackText,1186 querySelectorAll,1187 logScale,1188 omitAttached,1189 snapshotName1190 }) => {1191 const callback = injected.eval(callbackText);1192 const poller = logScale ? injected.pollLogScale.bind(injected) : injected.pollRaf.bind(injected);1193 let markedElements = new Set();1194 return poller(progress => {1195 let element;1196 let elements = [];1197 if (querySelectorAll) {1198 elements = injected.querySelectorAll(info.parsed, document);1199 element = elements[0];1200 progress.logRepeating(` selector resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`);1201 } else {1202 element = injected.querySelector(info.parsed, document, info.strict);1203 elements = element ? [element] : [];1204 if (element) progress.logRepeating(` selector resolved to ${injected.previewNode(element)}`);1205 }1206 if (!element && !omitAttached) return progress.continuePolling;1207 if (snapshotName) {1208 const previouslyMarkedElements = markedElements;1209 markedElements = new Set(elements);1210 for (const e of previouslyMarkedElements) {1211 if (!markedElements.has(e)) e.removeAttribute('__playwright_target__');1212 }1213 for (const e of markedElements) {1214 if (!previouslyMarkedElements.has(e)) e.setAttribute('__playwright_target__', snapshotName);1215 }1216 }1217 return callback(progress, element, taskData, elements);1218 });1219 }, {1220 info,1221 taskData,1222 callbackText,1223 querySelectorAll: options.querySelectorAll,1224 logScale: options.logScale,1225 omitAttached: options.omitAttached,1226 snapshotName: progress.metadata.afterSnapshot1227 });1228 }, true);1229 if (this._detached) rerunnableTask.terminate(new Error('Frame got detached.'));1230 if (data.context) rerunnableTask.rerun(data.context);1231 return await rerunnableTask.promise;1232 }1233 }1234 _scheduleRerunnableHandleTask(progress, world, task) {1235 const data = this._contextData.get(world);1236 const rerunnableTask = new RerunnableTask(data, progress, task, false1237 /* returnByValue */1238 );1239 if (this._detached) rerunnableTask.terminate(new Error('waitForFunction failed: frame got detached.'));1240 if (data.context) rerunnableTask.rerun(data.context);1241 return rerunnableTask.handlePromise;1242 }1243 _setContext(world, context) {1244 const data = this._contextData.get(world);1245 data.context = context;1246 if (context) {1247 data.contextPromise.resolve(context);1248 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.rerun(context);1249 } else {1250 data.contextPromise = new _async.ManualPromise();1251 }1252 }1253 _contextCreated(world, context) {1254 const data = this._contextData.get(world); // In case of multiple sessions to the same target, there's a race between1255 // connections so we might end up creating multiple isolated worlds.1256 // We can use either.1257 if (data.context) {1258 data.context.contextDestroyed(new Error('Execution context was destroyed, most likely because of a navigation'));1259 this._setContext(world, null);1260 }1261 this._setContext(world, context);1262 }1263 _contextDestroyed(context) {1264 // Sometimes we get this after detach, in which case we should not reset1265 // our already destroyed contexts to something that will never resolve.1266 if (this._detached) return;1267 context.contextDestroyed(new Error('Execution context was destroyed, most likely because of a navigation'));1268 for (const [world, data] of this._contextData) {1269 if (data.context === context) this._setContext(world, null);1270 }1271 }1272 _startNetworkIdleTimer() {1273 (0, _utils.assert)(!this._networkIdleTimer); // We should not start a timer and report networkidle in detached frames.1274 // This happens at least in Firefox for child frames, where we may get requestFinished1275 // after the frame was detached - probably a race in the Firefox itself.1276 if (this._firedLifecycleEvents.has('networkidle') || this._detached) return;1277 this._networkIdleTimer = setTimeout(() => this._onLifecycleEvent('networkidle'), 500);1278 }1279 _stopNetworkIdleTimer() {1280 if (this._networkIdleTimer) clearTimeout(this._networkIdleTimer);1281 this._networkIdleTimer = undefined;1282 }1283 async extendInjectedScript(source, arg) {1284 const context = await this._context('main');1285 const injectedScriptHandle = await context.injectedScript();1286 return injectedScriptHandle.evaluateHandle((injectedScript, {1287 source,1288 arg1289 }) => {1290 return injectedScript.extend(source, arg);1291 }, {1292 source,1293 arg1294 });1295 }1296 async _resolveFrameForSelector(progress, selector, options, scope) {1297 const elementPath = [];1298 progress.cleanupWhenAborted(() => {1299 // Do not await here to avoid being blocked, either by stalled1300 // page (e.g. alert) or unresolved navigation in Chromium.1301 for (const element of elementPath) element.dispose();1302 });1303 let frame = this;1304 const frameChunks = (0, _selectorParser.splitSelectorByFrame)(selector);1305 for (let i = 0; i < frameChunks.length - 1 && progress.isRunning(); ++i) {1306 const info = this._page.parseSelector(frameChunks[i], options);1307 const task = dom.waitForSelectorTask(info, 'attached', false, i === 0 ? scope : undefined);1308 progress.log(` waiting for frame "${(0, _selectorParser.stringifySelector)(frameChunks[i])}"`);1309 const handle = i === 0 && scope ? await frame._runWaitForSelectorTaskOnce(progress, (0, _selectorParser.stringifySelector)(info.parsed), info.world, task) : await frame._scheduleRerunnableHandleTask(progress, info.world, task);1310 const element = handle.asElement();1311 const isIframe = await element.isIframeElement();1312 if (isIframe === 'error:notconnected') return null; // retry1313 if (!isIframe) throw new Error(`Selector "${(0, _selectorParser.stringifySelector)(info.parsed)}" resolved to ${element.preview()}, <iframe> was expected`);1314 frame = await element.contentFrame();1315 element.dispose();1316 if (!frame) return null; // retry1317 }1318 return {1319 frame,1320 info: this._page.parseSelector(frameChunks[frameChunks.length - 1], options)1321 };1322 }1323 async resolveFrameForSelectorNoWait(selector, options = {}, scope) {1324 let frame = this;1325 const frameChunks = (0, _selectorParser.splitSelectorByFrame)(selector);1326 for (let i = 0; i < frameChunks.length - 1; ++i) {1327 const info = this._page.parseSelector(frameChunks[i], options);1328 const element = await this._page.selectors.query(frame, info, i === 0 ? scope : undefined);1329 if (!element) return null;1330 frame = await element.contentFrame();1331 element.dispose();1332 if (!frame) throw new Error(`Selector "${(0, _selectorParser.stringifySelector)(info.parsed)}" resolved to ${element.preview()}, <iframe> was expected`);1333 }1334 return {1335 frame,1336 info: this._page.parseSelector(frameChunks[frameChunks.length - 1], options)1337 };1338 }1339 async _runWaitForSelectorTaskOnce(progress, selector, world, task) {1340 const context = await this._context(world);1341 const injected = await context.injectedScript();1342 try {1343 const pollHandler = new dom.InjectedScriptPollHandler(progress, await task(injected));1344 const result = await pollHandler.finishHandle();1345 progress.cleanupWhenAborted(() => result.dispose());1346 return result;1347 } catch (e) {1348 throw new Error(`Error: frame navigated while waiting for selector "${selector}"`);1349 }1350 }1351}1352exports.Frame = Frame;1353Frame.Events = {1354 Navigation: 'navigation',1355 AddLifecycle: 'addlifecycle',1356 RemoveLifecycle: 'removelifecycle'1357};1358class RerunnableTask {1359 constructor(data, progress, task, returnByValue) {1360 this.promise = void 0;1361 this.handlePromise = void 0;1362 this._task = void 0;1363 this._progress = void 0;1364 this._returnByValue = void 0;1365 this._contextData = void 0;1366 this._task = task;1367 this._progress = progress;1368 this._returnByValue = returnByValue;1369 if (returnByValue) this.promise = new _async.ManualPromise();else this.handlePromise = new _async.ManualPromise();1370 this._contextData = data;1371 this._contextData.rerunnableTasks.add(this);1372 }1373 terminate(error) {1374 this._reject(error);1375 }1376 _resolve(value) {1377 if (this.promise) this.promise.resolve(value);1378 if (this.handlePromise) this.handlePromise.resolve(value);1379 }1380 _reject(error) {1381 if (this.promise) this.promise.reject(error);1382 if (this.handlePromise) this.handlePromise.reject(error);1383 }1384 async rerun(context) {1385 try {1386 const injectedScript = await context.injectedScript();1387 const pollHandler = new dom.InjectedScriptPollHandler(this._progress, await this._task(injectedScript));1388 const result = this._returnByValue ? await pollHandler.finish() : await pollHandler.finishHandle();1389 this._contextData.rerunnableTasks.delete(this);1390 this._resolve(result);1391 } catch (e) {1392 if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) {1393 this._contextData.rerunnableTasks.delete(this);1394 this._reject(e);1395 } // Unlike other places, we don't check frame for being detached since the whole scope of this1396 // evaluation is within the frame's execution context. So we only let JavaScript errors and1397 // session termination errors go through.1398 // We will try again in the new execution context.1399 }1400 }1401}1402class SignalBarrier {1403 constructor(progress) {1404 this._progress = void 0;1405 this._protectCount = 0;1406 this._promise = new _async.ManualPromise();1407 this._progress = progress;1408 this.retain();1409 }1410 waitFor() {1411 this.release();1412 return this._promise;1413 }1414 async addFrameNavigation(frame) {1415 // Auto-wait top-level navigations only.1416 if (frame.parentFrame()) return;1417 this.retain();1418 const waiter = _helper.helper.waitForEvent(null, frame, Frame.Events.Navigation, e => {1419 if (!e.error && this._progress) this._progress.log(` navigated to "${frame._url}"`);1420 return true;1421 });1422 await Promise.race([frame._page._disconnectedPromise, frame._page._crashedPromise, frame._detachedPromise, waiter.promise]).catch(e => {});1423 waiter.dispose();1424 this.release();1425 }1426 retain() {1427 ++this._protectCount;1428 }1429 release() {1430 --this._protectCount;1431 if (!this._protectCount) this._promise.resolve();1432 }1433}1434function verifyLifecycle(name, waitUntil) {1435 if (waitUntil === 'networkidle0') waitUntil = 'networkidle';1436 if (!types.kLifecycleEvents.has(waitUntil)) throw new Error(`${name}: expected one of (load|domcontentloaded|networkidle|commit)`);1437 return waitUntil;...

Full Screen

Full Screen

page.js

Source:page.js Github

copy

Full Screen

1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.Worker = exports.PageBinding = exports.Page = void 0;6var frames = _interopRequireWildcard(require("./frames"));7var input = _interopRequireWildcard(require("./input"));8var js = _interopRequireWildcard(require("./javascript"));9var network = _interopRequireWildcard(require("./network"));10var _screenshotter = require("./screenshotter");11var _timeoutSettings = require("../utils/timeoutSettings");12var _browserContext = require("./browserContext");13var _console = require("./console");14var accessibility = _interopRequireWildcard(require("./accessibility"));15var _fileChooser = require("./fileChooser");16var _progress = require("./progress");17var _utils = require("../utils/utils");18var _async = require("../utils/async");19var _debugLogger = require("../utils/debugLogger");20var _comparators = require("../utils/comparators");21var _instrumentation = require("./instrumentation");22var _selectorParser = require("./common/selectorParser");23function _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); }24function _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; }25/**26 * Copyright 2017 Google Inc. All rights reserved.27 * Modifications copyright (c) Microsoft Corporation.28 *29 * Licensed under the Apache License, Version 2.0 (the "License");30 * you may not use this file except in compliance with the License.31 * You may obtain a copy of the License at32 *33 * http://www.apache.org/licenses/LICENSE-2.034 *35 * Unless required by applicable law or agreed to in writing, software36 * distributed under the License is distributed on an "AS IS" BASIS,37 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.38 * See the License for the specific language governing permissions and39 * limitations under the License.40 */41class Page extends _instrumentation.SdkObject {42 constructor(delegate, browserContext) {43 super(browserContext, 'page');44 this._closedState = 'open';45 this._closedPromise = new _async.ManualPromise();46 this._disconnected = false;47 this._initialized = false;48 this._disconnectedPromise = new _async.ManualPromise();49 this._crashedPromise = new _async.ManualPromise();50 this._browserContext = void 0;51 this.keyboard = void 0;52 this.mouse = void 0;53 this.touchscreen = void 0;54 this._timeoutSettings = void 0;55 this._delegate = void 0;56 this._state = void 0;57 this._pageBindings = new Map();58 this._evaluateOnNewDocumentSources = [];59 this._screenshotter = void 0;60 this._frameManager = void 0;61 this.accessibility = void 0;62 this._workers = new Map();63 this.pdf = void 0;64 this.coverage = void 0;65 this._clientRequestInterceptor = void 0;66 this._serverRequestInterceptor = void 0;67 this._ownedContext = void 0;68 this.selectors = void 0;69 this._pageIsError = void 0;70 this._video = null;71 this._opener = void 0;72 this._frameThrottler = new FrameThrottler(10, 200);73 this.attribution.page = this;74 this._delegate = delegate;75 this._browserContext = browserContext;76 this._state = {77 emulatedSize: browserContext._options.viewport ? {78 viewport: browserContext._options.viewport,79 screen: browserContext._options.screen || browserContext._options.viewport80 } : null,81 mediaType: null,82 colorScheme: browserContext._options.colorScheme !== undefined ? browserContext._options.colorScheme : 'light',83 reducedMotion: browserContext._options.reducedMotion !== undefined ? browserContext._options.reducedMotion : 'no-preference',84 forcedColors: browserContext._options.forcedColors !== undefined ? browserContext._options.forcedColors : 'none',85 extraHTTPHeaders: null86 };87 this.accessibility = new accessibility.Accessibility(delegate.getAccessibilityTree.bind(delegate));88 this.keyboard = new input.Keyboard(delegate.rawKeyboard, this);89 this.mouse = new input.Mouse(delegate.rawMouse, this);90 this.touchscreen = new input.Touchscreen(delegate.rawTouchscreen, this);91 this._timeoutSettings = new _timeoutSettings.TimeoutSettings(browserContext._timeoutSettings);92 this._screenshotter = new _screenshotter.Screenshotter(this);93 this._frameManager = new frames.FrameManager(this);94 if (delegate.pdf) this.pdf = delegate.pdf.bind(delegate);95 this.coverage = delegate.coverage ? delegate.coverage() : null;96 this.selectors = browserContext.selectors();97 this.instrumentation.onPageOpen(this);98 }99 async initOpener(opener) {100 if (!opener) return;101 const openerPage = await opener.pageOrError();102 if (openerPage instanceof Page && !openerPage.isClosed()) this._opener = openerPage;103 }104 reportAsNew(error) {105 if (error) {106 // Initialization error could have happened because of107 // context/browser closure. Just ignore the page.108 if (this._browserContext.isClosingOrClosed()) return;109 this._setIsError(error);110 }111 this._initialized = true;112 this._browserContext.emit(_browserContext.BrowserContext.Events.Page, this); // I may happen that page iniatialization finishes after Close event has already been sent,113 // in that case we fire another Close event to ensure that each reported Page will have114 // corresponding Close event after it is reported on the context.115 if (this.isClosed()) this.emit(Page.Events.Close);116 }117 initializedOrUndefined() {118 return this._initialized ? this : undefined;119 }120 async _doSlowMo() {121 const slowMo = this._browserContext._browser.options.slowMo;122 if (!slowMo) return;123 await new Promise(x => setTimeout(x, slowMo));124 }125 _didClose() {126 this.instrumentation.onPageClose(this);127 this._frameManager.dispose();128 this._frameThrottler.setEnabled(false);129 (0, _utils.assert)(this._closedState !== 'closed', 'Page closed twice');130 this._closedState = 'closed';131 this.emit(Page.Events.Close);132 this._closedPromise.resolve();133 }134 _didCrash() {135 this.instrumentation.onPageClose(this);136 this._frameManager.dispose();137 this._frameThrottler.setEnabled(false);138 this.emit(Page.Events.Crash);139 this._crashedPromise.resolve(new Error('Page crashed'));140 }141 _didDisconnect() {142 this.instrumentation.onPageClose(this);143 this._frameManager.dispose();144 this._frameThrottler.setEnabled(false);145 (0, _utils.assert)(!this._disconnected, 'Page disconnected twice');146 this._disconnected = true;147 this._disconnectedPromise.resolve(new Error('Page closed'));148 }149 async _onFileChooserOpened(handle) {150 let multiple;151 try {152 multiple = await handle.evaluate(element => !!element.multiple);153 } catch (e) {154 // Frame/context may be gone during async processing. Do not throw.155 return;156 }157 if (!this.listenerCount(Page.Events.FileChooser)) {158 handle.dispose();159 return;160 }161 const fileChooser = new _fileChooser.FileChooser(this, handle, multiple);162 this.emit(Page.Events.FileChooser, fileChooser);163 }164 context() {165 return this._browserContext;166 }167 opener() {168 return this._opener;169 }170 mainFrame() {171 return this._frameManager.mainFrame();172 }173 frames() {174 return this._frameManager.frames();175 }176 setDefaultNavigationTimeout(timeout) {177 this._timeoutSettings.setDefaultNavigationTimeout(timeout);178 }179 setDefaultTimeout(timeout) {180 this._timeoutSettings.setDefaultTimeout(timeout);181 }182 async exposeBinding(name, needsHandle, playwrightBinding) {183 if (this._pageBindings.has(name)) throw new Error(`Function "${name}" has been already registered`);184 if (this._browserContext._pageBindings.has(name)) throw new Error(`Function "${name}" has been already registered in the browser context`);185 const binding = new PageBinding(name, playwrightBinding, needsHandle);186 this._pageBindings.set(name, binding);187 await this._delegate.exposeBinding(binding);188 }189 setExtraHTTPHeaders(headers) {190 this._state.extraHTTPHeaders = headers;191 return this._delegate.updateExtraHTTPHeaders();192 }193 async _onBindingCalled(payload, context) {194 if (this._disconnected || this._closedState === 'closed') return;195 await PageBinding.dispatch(this, payload, context);196 }197 _addConsoleMessage(type, args, location, text) {198 const message = new _console.ConsoleMessage(this, type, text, args, location);199 const intercepted = this._frameManager.interceptConsoleMessage(message);200 if (intercepted || !this.listenerCount(Page.Events.Console)) args.forEach(arg => arg.dispose());else this.emit(Page.Events.Console, message);201 }202 async reload(metadata, options) {203 const controller = new _progress.ProgressController(metadata, this);204 return controller.run(progress => this.mainFrame().raceNavigationAction(async () => {205 // Note: waitForNavigation may fail before we get response to reload(),206 // so we should await it immediately.207 const [response] = await Promise.all([this.mainFrame()._waitForNavigation(progress, options), this._delegate.reload()]);208 await this._doSlowMo();209 return response;210 }), this._timeoutSettings.navigationTimeout(options));211 }212 async goBack(metadata, options) {213 const controller = new _progress.ProgressController(metadata, this);214 return controller.run(progress => this.mainFrame().raceNavigationAction(async () => {215 // Note: waitForNavigation may fail before we get response to goBack,216 // so we should catch it immediately.217 let error;218 const waitPromise = this.mainFrame()._waitForNavigation(progress, options).catch(e => {219 error = e;220 return null;221 });222 const result = await this._delegate.goBack();223 if (!result) return null;224 const response = await waitPromise;225 if (error) throw error;226 await this._doSlowMo();227 return response;228 }), this._timeoutSettings.navigationTimeout(options));229 }230 async goForward(metadata, options) {231 const controller = new _progress.ProgressController(metadata, this);232 return controller.run(progress => this.mainFrame().raceNavigationAction(async () => {233 // Note: waitForNavigation may fail before we get response to goForward,234 // so we should catch it immediately.235 let error;236 const waitPromise = this.mainFrame()._waitForNavigation(progress, options).catch(e => {237 error = e;238 return null;239 });240 const result = await this._delegate.goForward();241 if (!result) return null;242 const response = await waitPromise;243 if (error) throw error;244 await this._doSlowMo();245 return response;246 }), this._timeoutSettings.navigationTimeout(options));247 }248 async emulateMedia(options) {249 if (options.media !== undefined) this._state.mediaType = options.media;250 if (options.colorScheme !== undefined) this._state.colorScheme = options.colorScheme;251 if (options.reducedMotion !== undefined) this._state.reducedMotion = options.reducedMotion;252 if (options.forcedColors !== undefined) this._state.forcedColors = options.forcedColors;253 await this._delegate.updateEmulateMedia();254 await this._doSlowMo();255 }256 async setViewportSize(viewportSize) {257 this._state.emulatedSize = {258 viewport: { ...viewportSize259 },260 screen: { ...viewportSize261 }262 };263 await this._delegate.setEmulatedSize(this._state.emulatedSize);264 await this._doSlowMo();265 }266 viewportSize() {267 var _this$_state$emulated;268 return ((_this$_state$emulated = this._state.emulatedSize) === null || _this$_state$emulated === void 0 ? void 0 : _this$_state$emulated.viewport) || null;269 }270 async bringToFront() {271 await this._delegate.bringToFront();272 }273 async _addInitScriptExpression(source) {274 this._evaluateOnNewDocumentSources.push(source);275 await this._delegate.evaluateOnNewDocument(source);276 }277 _needsRequestInterception() {278 return !!this._clientRequestInterceptor || !!this._serverRequestInterceptor || !!this._browserContext._requestInterceptor;279 }280 async _setClientRequestInterceptor(handler) {281 this._clientRequestInterceptor = handler;282 await this._delegate.updateRequestInterception();283 }284 async _setServerRequestInterceptor(handler) {285 this._serverRequestInterceptor = handler;286 await this._delegate.updateRequestInterception();287 }288 _requestStarted(request, routeDelegate) {289 const route = new network.Route(request, routeDelegate);290 if (this._serverRequestInterceptor) {291 this._serverRequestInterceptor(route, request);292 return;293 }294 if (this._clientRequestInterceptor) {295 this._clientRequestInterceptor(route, request);296 return;297 }298 if (this._browserContext._requestInterceptor) {299 this._browserContext._requestInterceptor(route, request);300 return;301 }302 route.continue();303 }304 async expectScreenshot(metadata, options = {}) {305 const locator = options.locator;306 const rafrafScreenshot = locator ? async (progress, timeout) => {307 return await locator.frame.rafrafTimeoutScreenshotElementWithProgress(progress, locator.selector, timeout, options.screenshotOptions || {});308 } : async (progress, timeout) => {309 await this.mainFrame().rafrafTimeout(timeout);310 return await this._screenshotter.screenshotPage(progress, options.screenshotOptions || {});311 };312 const comparator = (0, _comparators.getComparator)('image/png');313 const controller = new _progress.ProgressController(metadata, this);314 const isGeneratingNewScreenshot = !options.expected;315 if (isGeneratingNewScreenshot && options.isNot) return {316 errorMessage: '"not" matcher requires expected result'317 };318 let intermediateResult = undefined;319 return controller.run(async progress => {320 let actual;321 let previous;322 const pollIntervals = [0, 100, 250, 500];323 while (true) {324 var _pollIntervals$shift;325 progress.throwIfAborted();326 if (this.isClosed()) throw new Error('The page has closed');327 let comparatorResult;328 const screenshotTimeout = (_pollIntervals$shift = pollIntervals.shift()) !== null && _pollIntervals$shift !== void 0 ? _pollIntervals$shift : 1000;329 if (isGeneratingNewScreenshot) {330 previous = actual;331 actual = await rafrafScreenshot(progress, screenshotTimeout).catch(e => undefined);332 comparatorResult = actual && previous ? comparator(actual, previous, options.comparatorOptions) : undefined;333 } else {334 actual = await rafrafScreenshot(progress, screenshotTimeout).catch(e => undefined);335 comparatorResult = actual ? comparator(actual, options.expected, options.comparatorOptions) : undefined;336 }337 if (comparatorResult !== undefined && !!comparatorResult === !!options.isNot) break;338 if (comparatorResult) intermediateResult = {339 errorMessage: comparatorResult.errorMessage,340 diff: comparatorResult.diff,341 actual,342 previous343 };344 }345 return isGeneratingNewScreenshot ? {346 actual347 } : {};348 }, this._timeoutSettings.timeout(options)).catch(e => {349 var _intermediateResult$e, _intermediateResult;350 // Q: Why not throw upon isSessionClosedError(e) as in other places?351 // A: We want user to receive a friendly diff between actual and expected/previous.352 if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorParser.isInvalidSelectorError)(e)) throw e;353 return {354 log: metadata.log,355 ...intermediateResult,356 errorMessage: (_intermediateResult$e = (_intermediateResult = intermediateResult) === null || _intermediateResult === void 0 ? void 0 : _intermediateResult.errorMessage) !== null && _intermediateResult$e !== void 0 ? _intermediateResult$e : e.message357 };358 });359 }360 async screenshot(metadata, options = {}) {361 const controller = new _progress.ProgressController(metadata, this);362 return controller.run(progress => this._screenshotter.screenshotPage(progress, options), this._timeoutSettings.timeout(options));363 }364 async close(metadata, options) {365 if (this._closedState === 'closed') return;366 const runBeforeUnload = !!options && !!options.runBeforeUnload;367 if (this._closedState !== 'closing') {368 this._closedState = 'closing';369 (0, _utils.assert)(!this._disconnected, 'Target closed'); // This might throw if the browser context containing the page closes370 // while we are trying to close the page.371 await this._delegate.closePage(runBeforeUnload).catch(e => _debugLogger.debugLogger.log('error', e));372 }373 if (!runBeforeUnload) await this._closedPromise;374 if (this._ownedContext) await this._ownedContext.close(metadata);375 }376 _setIsError(error) {377 this._pageIsError = error;378 if (!this._frameManager.mainFrame()) this._frameManager.frameAttached('<dummy>', null);379 }380 isClosed() {381 return this._closedState === 'closed';382 }383 _addWorker(workerId, worker) {384 this._workers.set(workerId, worker);385 this.emit(Page.Events.Worker, worker);386 }387 _removeWorker(workerId) {388 const worker = this._workers.get(workerId);389 if (!worker) return;390 worker.didClose();391 this._workers.delete(workerId);392 }393 _clearWorkers() {394 for (const [workerId, worker] of this._workers) {395 worker.didClose();396 this._workers.delete(workerId);397 }398 }399 async _setFileChooserIntercepted(enabled) {400 await this._delegate.setFileChooserIntercepted(enabled);401 }402 frameNavigatedToNewDocument(frame) {403 this.emit(Page.Events.InternalFrameNavigatedToNewDocument, frame);404 const url = frame.url();405 if (!url.startsWith('http')) return;406 const purl = network.parsedURL(url);407 if (purl) this._browserContext.addVisitedOrigin(purl.origin);408 }409 allBindings() {410 return [...this._browserContext._pageBindings.values(), ...this._pageBindings.values()];411 }412 getBinding(name) {413 return this._pageBindings.get(name) || this._browserContext._pageBindings.get(name);414 }415 setScreencastOptions(options) {416 this._delegate.setScreencastOptions(options).catch(e => _debugLogger.debugLogger.log('error', e));417 this._frameThrottler.setEnabled(!!options);418 }419 throttleScreencastFrameAck(ack) {420 // Don't ack immediately, tracing has smart throttling logic that is implemented here.421 this._frameThrottler.ack(ack);422 }423 temporarlyDisableTracingScreencastThrottling() {424 this._frameThrottler.recharge();425 }426 firePageError(error) {427 this.emit(Page.Events.PageError, error);428 }429 parseSelector(selector, options) {430 const strict = typeof (options === null || options === void 0 ? void 0 : options.strict) === 'boolean' ? options.strict : !!this.context()._options.strictSelectors;431 return this.selectors.parseSelector(selector, strict);432 }433 async hideHighlight() {434 await Promise.all(this.frames().map(frame => frame.hideHighlight().catch(() => {})));435 }436}437exports.Page = Page;438Page.Events = {439 Close: 'close',440 Crash: 'crash',441 Console: 'console',442 Dialog: 'dialog',443 Download: 'download',444 FileChooser: 'filechooser',445 DOMContentLoaded: 'domcontentloaded',446 // Can't use just 'error' due to node.js special treatment of error events.447 // @see https://nodejs.org/api/events.html#events_error_events448 PageError: 'pageerror',449 FrameAttached: 'frameattached',450 FrameDetached: 'framedetached',451 InternalFrameNavigatedToNewDocument: 'internalframenavigatedtonewdocument',452 Load: 'load',453 ScreencastFrame: 'screencastframe',454 Video: 'video',455 WebSocket: 'websocket',456 Worker: 'worker'457};458class Worker extends _instrumentation.SdkObject {459 constructor(parent, url) {460 super(parent, 'worker');461 this._url = void 0;462 this._executionContextPromise = void 0;463 this._executionContextCallback = void 0;464 this._existingExecutionContext = null;465 this._url = url;466 this._executionContextCallback = () => {};467 this._executionContextPromise = new Promise(x => this._executionContextCallback = x);468 }469 _createExecutionContext(delegate) {470 this._existingExecutionContext = new js.ExecutionContext(this, delegate);471 this._executionContextCallback(this._existingExecutionContext);472 }473 url() {474 return this._url;475 }476 didClose() {477 if (this._existingExecutionContext) this._existingExecutionContext.contextDestroyed(new Error('Worker was closed'));478 this.emit(Worker.Events.Close, this);479 }480 async evaluateExpression(expression, isFunction, arg) {481 return js.evaluateExpression(await this._executionContextPromise, true482 /* returnByValue */483 , expression, isFunction, arg);484 }485 async evaluateExpressionHandle(expression, isFunction, arg) {486 return js.evaluateExpression(await this._executionContextPromise, false487 /* returnByValue */488 , expression, isFunction, arg);489 }490}491exports.Worker = Worker;492Worker.Events = {493 Close: 'close'494};495class PageBinding {496 constructor(name, playwrightFunction, needsHandle) {497 this.name = void 0;498 this.playwrightFunction = void 0;499 this.source = void 0;500 this.needsHandle = void 0;501 this.name = name;502 this.playwrightFunction = playwrightFunction;503 this.source = `(${addPageBinding.toString()})(${JSON.stringify(name)}, ${needsHandle})`;504 this.needsHandle = needsHandle;505 }506 static async dispatch(page, payload, context) {507 const {508 name,509 seq,510 args511 } = JSON.parse(payload);512 try {513 (0, _utils.assert)(context.world);514 const binding = page.getBinding(name);515 let result;516 if (binding.needsHandle) {517 const handle = await context.evaluateHandle(takeHandle, {518 name,519 seq520 }).catch(e => null);521 result = await binding.playwrightFunction({522 frame: context.frame,523 page,524 context: page._browserContext525 }, handle);526 } else {527 result = await binding.playwrightFunction({528 frame: context.frame,529 page,530 context: page._browserContext531 }, ...args);532 }533 context.evaluate(deliverResult, {534 name,535 seq,536 result537 }).catch(e => _debugLogger.debugLogger.log('error', e));538 } catch (error) {539 if ((0, _utils.isError)(error)) context.evaluate(deliverError, {540 name,541 seq,542 message: error.message,543 stack: error.stack544 }).catch(e => _debugLogger.debugLogger.log('error', e));else context.evaluate(deliverErrorValue, {545 name,546 seq,547 error548 }).catch(e => _debugLogger.debugLogger.log('error', e));549 }550 function takeHandle(arg) {551 const handle = globalThis[arg.name]['handles'].get(arg.seq);552 globalThis[arg.name]['handles'].delete(arg.seq);553 return handle;554 }555 function deliverResult(arg) {556 globalThis[arg.name]['callbacks'].get(arg.seq).resolve(arg.result);557 globalThis[arg.name]['callbacks'].delete(arg.seq);558 }559 function deliverError(arg) {560 const error = new Error(arg.message);561 error.stack = arg.stack;562 globalThis[arg.name]['callbacks'].get(arg.seq).reject(error);563 globalThis[arg.name]['callbacks'].delete(arg.seq);564 }565 function deliverErrorValue(arg) {566 globalThis[arg.name]['callbacks'].get(arg.seq).reject(arg.error);567 globalThis[arg.name]['callbacks'].delete(arg.seq);568 }569 }570}571exports.PageBinding = PageBinding;572function addPageBinding(bindingName, needsHandle) {573 const binding = globalThis[bindingName];574 if (binding.__installed) return;575 globalThis[bindingName] = (...args) => {576 const me = globalThis[bindingName];577 if (needsHandle && args.slice(1).some(arg => arg !== undefined)) throw new Error(`exposeBindingHandle supports a single argument, ${args.length} received`);578 let callbacks = me['callbacks'];579 if (!callbacks) {580 callbacks = new Map();581 me['callbacks'] = callbacks;582 }583 const seq = (me['lastSeq'] || 0) + 1;584 me['lastSeq'] = seq;585 let handles = me['handles'];586 if (!handles) {587 handles = new Map();588 me['handles'] = handles;589 }590 const promise = new Promise((resolve, reject) => callbacks.set(seq, {591 resolve,592 reject593 }));594 if (needsHandle) {595 handles.set(seq, args[0]);596 binding(JSON.stringify({597 name: bindingName,598 seq599 }));600 } else {601 binding(JSON.stringify({602 name: bindingName,603 seq,604 args605 }));606 }607 return promise;608 };609 globalThis[bindingName].__installed = true;610}611class FrameThrottler {612 constructor(nonThrottledFrames, interval) {613 this._acks = [];614 this._interval = void 0;615 this._nonThrottledFrames = void 0;616 this._budget = void 0;617 this._intervalId = void 0;618 this._nonThrottledFrames = nonThrottledFrames;619 this._budget = nonThrottledFrames;620 this._interval = interval;621 }622 setEnabled(enabled) {623 if (enabled) {624 if (this._intervalId) clearInterval(this._intervalId);625 this._intervalId = setInterval(() => this._tick(), this._interval);626 } else if (this._intervalId) {627 clearInterval(this._intervalId);628 this._intervalId = undefined;629 }630 }631 recharge() {632 // Send all acks, reset budget.633 for (const ack of this._acks) ack();634 this._acks = [];635 this._budget = this._nonThrottledFrames;636 }637 ack(ack) {638 // Either not engaged or video is also recording, don't throttle.639 if (!this._intervalId) {640 ack();641 return;642 } // Do we have enough budget to respond w/o throttling?643 if (--this._budget > 0) {644 ack();645 return;646 } // Schedule.647 this._acks.push(ack);648 }649 _tick() {650 var _this$_acks$shift;651 (_this$_acks$shift = this._acks.shift()) === null || _this$_acks$shift === void 0 ? void 0 : _this$_acks$shift();652 }...

Full Screen

Full Screen

cssParser.js

Source:cssParser.js Github

copy

Full Screen

...25 * limitations under the License.26 */27class InvalidSelectorError extends Error {}28exports.InvalidSelectorError = InvalidSelectorError;29function isInvalidSelectorError(error) {30 return error instanceof InvalidSelectorError;31} // Note: '>=' is used internally for text engine to preserve backwards compatibility.32function parseCSS(selector, customNames) {33 let tokens;34 try {35 tokens = css.tokenize(selector);36 if (!(tokens[tokens.length - 1] instanceof css.EOFToken)) tokens.push(new css.EOFToken());37 } catch (e) {38 const newMessage = e.message + ` while parsing selector "${selector}"`;39 const index = (e.stack || '').indexOf(e.message);40 if (index !== -1) e.stack = e.stack.substring(0, index) + newMessage + e.stack.substring(index + e.message.length);41 e.message = newMessage;42 throw e;43 }...

Full Screen

Full Screen

selectorParser.js

Source:selectorParser.js Github

copy

Full Screen

1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5Object.defineProperty(exports, "InvalidSelectorError", {6 enumerable: true,7 get: function () {8 return _cssParser.InvalidSelectorError;9 }10});11exports.allEngineNames = allEngineNames;12exports.customCSSNames = void 0;13Object.defineProperty(exports, "isInvalidSelectorError", {14 enumerable: true,15 get: function () {16 return _cssParser.isInvalidSelectorError;17 }18});19exports.parseSelector = parseSelector;20exports.splitSelectorByFrame = splitSelectorByFrame;21exports.stringifySelector = stringifySelector;22var _cssParser = require("./cssParser");23/**24 * Copyright (c) Microsoft Corporation.25 *26 * Licensed under the Apache License, Version 2.0 (the "License");27 * you may not use this file except in compliance with the License.28 * You may obtain a copy of the License at29 *30 * http://www.apache.org/licenses/LICENSE-2.031 *32 * Unless required by applicable law or agreed to in writing, software33 * distributed under the License is distributed on an "AS IS" BASIS,34 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.35 * See the License for the specific language governing permissions and36 * limitations under the License.37 */38const customCSSNames = new Set(['not', 'is', 'where', 'has', 'scope', 'light', 'visible', 'text', 'text-matches', 'text-is', 'has-text', 'above', 'below', 'right-of', 'left-of', 'near', 'nth-match']);39exports.customCSSNames = customCSSNames;40const kNestedSelectorNames = new Set(['has']);41function parseSelector(selector) {42 const result = parseSelectorString(selector);43 const parts = result.parts.map(part => {44 if (part.name === 'css' || part.name === 'css:light') {45 if (part.name === 'css:light') part.body = ':light(' + part.body + ')';46 const parsedCSS = (0, _cssParser.parseCSS)(part.body, customCSSNames);47 return {48 name: 'css',49 body: parsedCSS.selector,50 source: part.body51 };52 }53 if (kNestedSelectorNames.has(part.name)) {54 let innerSelector;55 try {56 const unescaped = JSON.parse(part.body);57 if (typeof unescaped !== 'string') throw new Error(`Malformed selector: ${part.name}=` + part.body);58 innerSelector = unescaped;59 } catch (e) {60 throw new Error(`Malformed selector: ${part.name}=` + part.body);61 }62 const result = {63 name: part.name,64 source: part.body,65 body: parseSelector(innerSelector)66 };67 if (result.body.parts.some(part => part.name === 'control' && part.body === 'enter-frame')) throw new Error(`Frames are not allowed inside "${part.name}" selectors`);68 return result;69 }70 return { ...part,71 source: part.body72 };73 });74 if (kNestedSelectorNames.has(parts[0].name)) throw new Error(`"${parts[0].name}" selector cannot be first`);75 return {76 capture: result.capture,77 parts78 };79}80function splitSelectorByFrame(selectorText) {81 const selector = parseSelector(selectorText);82 const result = [];83 let chunk = {84 parts: []85 };86 let chunkStartIndex = 0;87 for (let i = 0; i < selector.parts.length; ++i) {88 const part = selector.parts[i];89 if (part.name === 'control' && part.body === 'enter-frame') {90 if (!chunk.parts.length) throw new _cssParser.InvalidSelectorError('Selector cannot start with entering frame, select the iframe first');91 result.push(chunk);92 chunk = {93 parts: []94 };95 chunkStartIndex = i + 1;96 continue;97 }98 if (selector.capture === i) chunk.capture = i - chunkStartIndex;99 chunk.parts.push(part);100 }101 if (!chunk.parts.length) throw new _cssParser.InvalidSelectorError(`Selector cannot end with entering frame, while parsing selector ${selectorText}`);102 result.push(chunk);103 if (typeof selector.capture === 'number' && typeof result[result.length - 1].capture !== 'number') throw new _cssParser.InvalidSelectorError(`Can not capture the selector before diving into the frame. Only use * after the last frame has been selected`);104 return result;105}106function stringifySelector(selector) {107 if (typeof selector === 'string') return selector;108 return selector.parts.map((p, i) => {109 const prefix = p.name === 'css' ? '' : p.name + '=';110 return `${i === selector.capture ? '*' : ''}${prefix}${p.source}`;111 }).join(' >> ');112}113function allEngineNames(selector) {114 const result = new Set();115 const visit = selector => {116 for (const part of selector.parts) {117 result.add(part.name);118 if (kNestedSelectorNames.has(part.name)) visit(part.body);119 }120 };121 visit(selector);122 return result;123}124function parseSelectorString(selector) {125 let index = 0;126 let quote;127 let start = 0;128 const result = {129 parts: []130 };131 const append = () => {132 const part = selector.substring(start, index).trim();133 const eqIndex = part.indexOf('=');134 let name;135 let body;136 if (eqIndex !== -1 && part.substring(0, eqIndex).trim().match(/^[a-zA-Z_0-9-+:*]+$/)) {137 name = part.substring(0, eqIndex).trim();138 body = part.substring(eqIndex + 1);139 } else if (part.length > 1 && part[0] === '"' && part[part.length - 1] === '"') {140 name = 'text';141 body = part;142 } else if (part.length > 1 && part[0] === "'" && part[part.length - 1] === "'") {143 name = 'text';144 body = part;145 } else if (/^\(*\/\//.test(part) || part.startsWith('..')) {146 // If selector starts with '//' or '//' prefixed with multiple opening147 // parenthesis, consider xpath. @see https://github.com/microsoft/playwright/issues/817148 // If selector starts with '..', consider xpath as well.149 name = 'xpath';150 body = part;151 } else {152 name = 'css';153 body = part;154 }155 let capture = false;156 if (name[0] === '*') {157 capture = true;158 name = name.substring(1);159 }160 result.parts.push({161 name,162 body163 });164 if (capture) {165 if (result.capture !== undefined) throw new _cssParser.InvalidSelectorError(`Only one of the selectors can capture using * modifier`);166 result.capture = result.parts.length - 1;167 }168 };169 if (!selector.includes('>>')) {170 index = selector.length;171 append();172 return result;173 }174 while (index < selector.length) {175 const c = selector[index];176 if (c === '\\' && index + 1 < selector.length) {177 index += 2;178 } else if (c === quote) {179 quote = undefined;180 index++;181 } else if (!quote && (c === '"' || c === '\'' || c === '`')) {182 quote = c;183 index++;184 } else if (!quote && c === '>' && selector[index + 1] === '>') {185 append();186 index += 2;187 start = index;188 } else {189 index++;190 }191 }192 append();193 return result;...

Full Screen

Full Screen

selectorErrors.js

Source:selectorErrors.js Github

copy

Full Screen

...20 * limitations under the License.21 */22class InvalidSelectorError extends Error {}23exports.InvalidSelectorError = InvalidSelectorError;24function isInvalidSelectorError(error) {25 return error instanceof InvalidSelectorError;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 try {7 await page.click('div');8 } catch (e) {9 if (e instanceof Error && e.name === 'Error') {10 if (e.isInvalidSelectorError) {11 console.log('Invalid selector error!');12 }13 }14 }15 await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19 const browser = await chromium.launch();20 const context = await browser.newContext();21 const page = await context.newPage();22 try {23 await page.waitForSelector('div');24 } catch (e) {25 if (e instanceof Error && e.name === 'TimeoutError') {26 if (e.isTimeoutError) {27 console.log('Timeout error!');28 }29 }30 }31 await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35 const browser = await chromium.launch();36 const context = await browser.newContext();37 const page = await context.newPage();38 try {39 await page.evaluate(() => {40 throw new Error('Evaluation failed');41 });42 } catch (e) {43 if (e instanceof Error && e.name === 'Error') {44 if (e.isEvaluationFailedError) {45 console.log('Evaluation failed error!');46 }47 }48 }49 await browser.close();50})();51const { chromium } = require('playwright');52(async () => {53 const browser = await chromium.launch();54 const context = await browser.newContext();55 const page = await context.newPage();56 try {57 await page.click('div');58 } catch (e) {59 if (e instanceof Error && e.name === 'Error') {60 if (e.isSelectorMatchesMultipleElementsError) {61 console.log('Selector matches multiple elements error!');62 }

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isInvalidSelectorError } = require('playwright/lib/helper');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 try {7 await page.click('text=Get started');8 } catch (e) {9 if (isInvalidSelectorError(e)) {10 console.log('Invalid selector error');11 }12 }13 await browser.close();14})();15const { isInvalidSelectorError } = require('playwright/lib/helper');16const { chromium } = require('playwright');17(async () => {18 const browser = await chromium.launch();19 const page = await browser.newPage();20 try {21 await page.click('text=Get started');22 } catch (e) {23 if (isInvalidSelectorError(e)) {24 console.log('Invalid selector error');25 }26 }27 await browser.close();28})();29const { isInvalidSelectorError } = require('playwright/lib/helper');30const { chromium } = require('playwright');31(async () => {32 const browser = await chromium.launch();33 const page = await browser.newPage();34 try {35 await page.click('text=Get started');36 } catch (e) {37 if (isInvalidSelectorError(e)) {38 console.log('Invalid selector error');39 }40 }41 await browser.close();42})();43const { isInvalidSelectorError } = require('playwright/lib/helper');44const { chromium } = require('playwright');45(async () => {46 const browser = await chromium.launch();47 const page = await browser.newPage();48 try {49 await page.click('text=Get started');50 } catch (e) {51 if (isInvalidSelectorError(e)) {52 console.log('Invalid selector error');53 }

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const { isInvalidSelectorError } = require('playwright/lib/internal/errors');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 try {7 await page.$('invalid');8 } catch (error) {9 if (isInvalidSelectorError(error)) {10 console.log('Invalid selector error');11 }12 }13 await browser.close();14})();15isTimeoutError(error)16isNavigationError(error)17isEvaluationError(error)18isSelectorError(error)19isElementHandleError(error)20isJSHandleError(error)21isRequestError(error)22isResponseError(error)23isBrowserContextError(error)24isPageError(error)25isWorkerError(error)26isPlaywrightError(error)27isError(error)28isErrorWithMessage(error)29isErrorWithStack(error)30isErrorWithMetadata(error)31isErrorWithInternalProperties(error)32isErrorWithInternalDetails(error)33isErrorWithInternalFrames(er

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isInvalidSelectorError } = require('playwright/lib/utils/error');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 try {8 await page.waitForSelector('div');9 } catch (error) {10 if (isInvalidSelectorError(error)) {11 console.log('Invalid selector');12 } else {13 throw error;14 }15 }16 await browser.close();17})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright');2const { isInvalidSelectorError } = Playwright.InternalError;3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch();6 const page = await browser.newPage();7 try {8 await page.setContent('<h1>Test</h1>');9 await page.click('h1');10 } catch (error) {11 if (isInvalidSelectorError(error)) {12 console.log('Invalid selector');13 } else {14 console.log('Other error');15 }16 }17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch();22 const page = await browser.newPage();23 try {24 await page.setContent('<h1>Test</h1>');25 await page.click('h1');26 } catch (error) {27 if (error.isInvalidSelectorError) {28 console.log('Invalid selector');29 } else {30 console.log('Other error');31 }32 }33 await browser.close();34})();35const { chromium } = require('playwright');36(async () => {37 const browser = await chromium.launch();38 const page = await browser.newPage();39 try {40 await page.setContent('<h1>Test</h1>');41 await page.click('h1');42 } catch (error) {43 if (error.isPlaywrightError && error.name === 'PlaywrightError' && error.code === 'ERR_INVALID_SELECTOR') {44 console.log('Invalid selector');45 } else {46 console.log('Other error');47 }48 }49 await browser.close();50})();51const { chromium } = require('playwright');52(async () => {53 const browser = await chromium.launch();54 const page = await browser.newPage();55 try {56 await page.setContent('<h1>Test</h1>');57 await page.click('h1');58 } catch (error) {59 if (error instanceof Error && error.name === 'PlaywrightError' && error.code === 'ERR_INVALID_SELECTOR') {60 console.log('Invalid

Full Screen

Using AI Code Generation

copy

Full Screen

1const { InternalError } = require('playwright/lib/server/errors');2const { isInvalidSelectorError } = InternalError;3console.log(isInvalidSelectorError(new Error('Invalid selector')));4console.log(isInvalidSelectorError(new Error('Invalid selector: foo')));5console.log(isInvalidSelectorError(new Error('Invalid selector: foo bar')));6console.log(isInvalidSelectorError(new Error('Invalid selector: foo bar baz')));7console.log(isInvalidSelectorError(new Error('Invalid selector: foo bar baz qux')));

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isInvalidSelectorError } = require('playwright/lib/helper');2const { isInvalidSelectorError } = require('playwright/lib/helper');3class MyHelper extends Helper {4 async _before() {5 this.helpers = this.helpers || {};6 this.helpers.Playwright = this.helpers.Playwright || this.helpers['Playwright'];7 }8 async isInvalidSelectorError(error) {9 return isInvalidSelectorError(error);10 }11}12module.exports = MyHelper;13const { expect } = require('chai');14Feature('My Feature');15Scenario('My Scenario', async ({ I }) => {16 try {17 await I.click('I do not exist');18 } catch (e) {19 expect(await I.isInvalidSelectorError(e)).to.be.true;20 }21});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { isInvalidSelectorError } = require('playwright/lib/server/utils');2if (isInvalidSelectorError(error)) {3 console.log('Invalid Selector Error');4}5const { isInvalidSelectorError } = require('playwright/lib/server/utils');6if (isInvalidSelectorError(error)) {7 console.log('Invalid Selector Error');8}9const { isInvalidSelectorError } = require('playwright/lib/server/utils');10if (isInvalidSelectorError(error)) {11 console.log('Invalid Selector Error');12}13const { isInvalidSelectorError } = require('playwright/lib/server/utils');14if (isInvalidSelectorError(error)) {15 console.log('Invalid Selector Error');16}17const { isInvalidSelectorError } = require('playwright/lib/server/utils');18if (isInvalidSelectorError(error)) {19 console.log('Invalid Selector Error');20}21const { isInvalidSelectorError } = require('playwright/lib/server/utils');22if (isInvalidSelectorError(error)) {23 console.log('Invalid Selector Error');24}25const { isInvalidSelectorError } = require('playwright/lib/server/utils');26if (isInvalidSelectorError(error)) {27 console.log('Invalid Selector Error');28}29const { isInvalidSelectorError } = require('playwright/lib/server/utils');30if (isInvalidSelectorError(error)) {31 console.log('Invalid Selector Error');32}33const { isInvalidSelectorError } = require('playwright/lib/server/utils');34if (isInvalidSelectorError(error)) {35 console.log('Invalid Selector Error');36}37const { isInvalidSelectorError } = require('playwright/lib/server/utils');38if (isInvalidSelectorError(error)) {39 console.log('Invalid Selector Error

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright');2const { InternalError } = Playwright;3const error = new InternalError('error message');4const { chromium } = require('playwright');5(async () => {6 const browser = await chromium.launch();7 const context = await browser.newContext();8 try {9 await context.waitForSelector('div', { timeout: 1000 });10 } catch (error) {11 if (error.isInvalidSelectorError()) {12 console.log('Invalid selector error');13 } else {14 console.log('Other error');15 }16 }17 await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21 const browser = await chromium.launch();22 const context = await browser.newContext();23 const page = await context.newPage();24 try {25 await page.click('non-existent-selector');26 } catch (error) {27 if (error.isTimeoutError()) {28 console.log('Timeout error');29 } else if (error.isElementHandleError()) {30 console.log('ElementHandle error');31 } else {32 console.log('Other error');33 }34 }35 await browser.close();36})();

Full Screen

Playwright tutorial

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.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

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

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful