How to use addFrameNavigation method in Playwright Internal

Best JavaScript code snippet using playwright-internal

frames.js

Source:frames.js Github

copy

Full Screen

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

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const {chromium} = require('playwright');2(async () => {3 const browser = await chromium.launch({headless: false});4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.addInitScript(() => {7 window.__playwright__ = {8 addFrameNavigation: (url) => {9 window.addEventListener('load', () => {10 if (window.location.href === url) {11 window.__playwright__ = undefined;12 window.dispatchEvent(new CustomEvent('frameNavigated'));13 }14 });15 }16 };17 });18 await page.waitForEvent('frameNavigated');19 console.log('Frame navigated');20 await browser.close();21})();22const {chromium} = require('playwright');23(async () => {24 const browser = await chromium.launch({headless: false});25 const context = await browser.newContext();26 const page = await context.newPage();27 await page.addInitScript(() => {28 window.__playwright__ = {29 addFrameNavigation: (url) => {30 window.addEventListener('load', () => {31 if (window.location.href === url) {32 window.__playwright__ = undefined;33 window.dispatchEvent(new CustomEvent('frameNavigated'));34 }35 });36 }37 };38 });39 await page.waitForEvent('frameNavigated');40 console.log('Frame navigated');41 await browser.close();42})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { addFrameNavigation } = require('playwright/lib/internal/frames');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 await page.waitForLoadState();8 console.log(page.url());9})();10const { helper } = require('./helper');11const { assert } = helper;12const { Page } = require('./page');13const { JSHandle } = require('./jsHandle');14const { TimeoutError } = require('./errors');15const { Events } = require('./events');16class Frame {17 async addFrameNavigation(frame, url) {18 await frame._page._delegate.navigateFrame(frame, url);19 }20}21module.exports = { Frame };

Full Screen

Using AI Code Generation

copy

Full Screen

1const { addFrameNavigation } = require('@playwright/test/lib/server/frames');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 await page.evaluate(addFrameNavigation, page.frames()[0]);5 await page.frames()[0].waitForNavigation();6 await page.frames()[0].waitForNavigation();7});8const { addFrameNavigation } = require('@playwright/test/lib/server/frames');9const { test } = require('@playwright/test');10test('test', async ({ page }) => {11 await page.evaluate(addFrameNavigation, page.frames()[0]);12});13const { waitForLoadState } = require('@playwright/test/lib/server/page');14const { test } = require('@playwright/test');15test('test', async ({ page }) => {16 await page.evaluate(waitForLoadState, 'domcontentloaded');17 await page.evaluate(waitForLoadState, 'networkidle');18});19const { addFrameNavigation, waitForLoadState } = require('@playwright/test/lib/server/frames');20module.exports = {21 use: {22 },23};24const { test } = require

Full Screen

Using AI Code Generation

copy

Full Screen

1const { addFrameNavigation } = require('playwright/lib/server/chromium/crNetworkManager');2const { chromium } = require('playwright');3const browser = await chromium.launch();4const context = await browser.newContext();5const page = await context.newPage();6await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { addFrameNavigation } = require('@playwright/test/lib/internal/page');2const frame = page.frames()[1];3await frame.waitForLoadState('load');4console.log(await frame.title());5const { addFrameNavigation } = require('@playwright/test/lib/internal/browserContext');6await frame.waitForLoadState('load');7console.log(await frame.title());8const { addFrameNavigation } = require('@playwright/test/lib/internal/browser');9await frame.waitForLoadState('load');10console.log(await frame.title());

Full Screen

Using AI Code Generation

copy

Full Screen

1await context.addFrameNavigation({ url: newUrl, name: "frame1" });2const value = await frame1.evaluate(() => {3 return document.querySelector("input").value;4});5console.log(value);6await frame1.evaluate((value) => {7 document.querySelector("input").value = value;8}, "new value");9const value2 = await frame1.evaluate(() => {10 return document.querySelector("input").value;11});12console.log(value2);13await frame1.evaluate((value) => {14 document.querySelector("input").value = value;15}, "new value");16const value3 = await frame1.evaluate(() => {17 return document.querySelector("input").value;18});19console.log(value3);20await frame1.evaluate((value) => {21 document.querySelector("input").value = value;22}, "new value");23const value4 = await frame1.evaluate(() => {24 return document.querySelector("input").value;25});26console.log(value4);27await frame1.evaluate((value) => {28 document.querySelector("input").value = value;29}, "new value");30const value5 = await frame1.evaluate(() => {31 return document.querySelector("input").value;32});33console.log(value5);

Full Screen

Using AI Code Generation

copy

Full Screen

1const frame = await page.frames()[1];2await frame.fill("input[name=q]", "playwright");3await frame.click("input[value=Google Search]");4await frame.click("text=Playwright - GitHub");5await frame.waitForLoadState("domcontentloaded");6await frame.click("text=Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API");7await frame.waitForLoadState("domcontentloaded");8await frame.click("text=Documentation");9await frame.waitForLoadState("domcontentloaded");10await frame.click("text=API");11await frame.waitForLoadState("domcontentloaded");12await frame.click("text=Page");13await frame.waitForLoadState("domcontentloaded");14const frame = await page.frames()[1];15await frame.fill("input[name=q]", "playwright");16await frame.click("input[value=Google Search]");17await frame.click("text=Playwright - GitHub");18await frame.waitForLoadState("domcontentloaded");19await frame.click("text=Playwright is a Node library to automate Chromium, Firefox and WebKit with a single API");20await frame.waitForLoadState("domcontentloaded");21await frame.click("text=Documentation");22await frame.waitForLoadState("domcontentloaded");23await frame.click("text=API");24await frame.waitForLoadState("domcontentloaded");25await frame.click("text=Page");26await frame.waitForLoadState("domcontentloaded");27const frame = await page.frames()[1];28await frame.fill("input[name=q]", "playwright");29await frame.click("input[value=Google Search]");30await frame.click("text=Playwright - GitHub");31await frame.waitForLoadState("dom

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