Best JavaScript code snippet using playwright-internal
electron.js
Source:electron.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.ElectronApplication = exports.Electron = void 0;6var _fs = _interopRequireDefault(require("fs"));7var _os = _interopRequireDefault(require("os"));8var _path = _interopRequireDefault(require("path"));9var _crBrowser = require("../chromium/crBrowser");10var _crConnection = require("../chromium/crConnection");11var _crExecutionContext = require("../chromium/crExecutionContext");12var js = _interopRequireWildcard(require("../javascript"));13var _timeoutSettings = require("../../common/timeoutSettings");14var _utils = require("../../utils");15var _transport = require("../transport");16var _processLauncher = require("../../utils/processLauncher");17var _browserContext = require("../browserContext");18var _progress = require("../progress");19var _helper = require("../helper");20var _eventsHelper = require("../../utils/eventsHelper");21var readline = _interopRequireWildcard(require("readline"));22var _debugLogger = require("../../common/debugLogger");23var _instrumentation = require("../instrumentation");24function _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); }25function _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; }26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }27/**28 * Copyright (c) Microsoft Corporation.29 *30 * Licensed under the Apache License, Version 2.0 (the "License");31 * you may not use this file except in compliance with the License.32 * You may obtain a copy of the License at33 *34 * http://www.apache.org/licenses/LICENSE-2.035 *36 * Unless required by applicable law or agreed to in writing, software37 * distributed under the License is distributed on an "AS IS" BASIS,38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.39 * See the License for the specific language governing permissions and40 * limitations under the License.41 */42const ARTIFACTS_FOLDER = _path.default.join(_os.default.tmpdir(), 'playwright-artifacts-');43class ElectronApplication extends _instrumentation.SdkObject {44 constructor(parent, browser, nodeConnection, process) {45 super(parent, 'electron-app');46 this._browserContext = void 0;47 this._nodeConnection = void 0;48 this._nodeSession = void 0;49 this._nodeExecutionContext = void 0;50 this._nodeElectronHandlePromise = void 0;51 this._timeoutSettings = new _timeoutSettings.TimeoutSettings();52 this._process = void 0;53 this._process = process;54 this._browserContext = browser._defaultContext;55 this._browserContext.on(_browserContext.BrowserContext.Events.Close, () => {56 // Emit application closed after context closed.57 Promise.resolve().then(() => this.emit(ElectronApplication.Events.Close));58 });59 this._nodeConnection = nodeConnection;60 this._nodeSession = nodeConnection.rootSession;61 this._nodeElectronHandlePromise = new Promise(f => {62 this._nodeSession.on('Runtime.executionContextCreated', async event => {63 if (event.context.auxData && event.context.auxData.isDefault) {64 this._nodeExecutionContext = new js.ExecutionContext(this, new _crExecutionContext.CRExecutionContext(this._nodeSession, event.context));65 f(await js.evaluate(this._nodeExecutionContext, false66 /* returnByValue */67 , `process.mainModule.require('electron')`));68 }69 });70 });71 this._browserContext.setCustomCloseHandler(async () => {72 const electronHandle = await this._nodeElectronHandlePromise;73 await electronHandle.evaluate(({74 app75 }) => app.quit());76 });77 this._nodeSession.send('Runtime.enable', {}).catch(e => {});78 }79 process() {80 return this._process;81 }82 context() {83 return this._browserContext;84 }85 async close() {86 const progressController = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), this);87 const closed = progressController.run(progress => _helper.helper.waitForEvent(progress, this, ElectronApplication.Events.Close).promise);88 await this._browserContext.close((0, _instrumentation.serverSideCallMetadata)());89 this._nodeConnection.close();90 await closed;91 }92 async browserWindow(page) {93 // Assume CRPage as Electron is always Chromium.94 const targetId = page._delegate._targetId;95 const electronHandle = await this._nodeElectronHandlePromise;96 return await electronHandle.evaluateHandle(({97 BrowserWindow,98 webContents99 }, targetId) => {100 const wc = webContents.fromDevToolsTargetId(targetId);101 return BrowserWindow.fromWebContents(wc);102 }, targetId);103 }104}105exports.ElectronApplication = ElectronApplication;106ElectronApplication.Events = {107 Close: 'close'108};109class Electron extends _instrumentation.SdkObject {110 constructor(playwrightOptions) {111 super(playwrightOptions.rootSdkObject, 'electron');112 this._playwrightOptions = void 0;113 this._playwrightOptions = playwrightOptions;114 }115 async launch(options) {116 const {117 args = []118 } = options;119 const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), this);120 controller.setLogName('browser');121 return controller.run(async progress => {122 let app = undefined;123 const electronArguments = ['--inspect=0', '--remote-debugging-port=0', ...args];124 if (_os.default.platform() === 'linux') {125 const runningAsRoot = process.geteuid && process.geteuid() === 0;126 if (runningAsRoot && electronArguments.indexOf('--no-sandbox') === -1) electronArguments.push('--no-sandbox');127 }128 const artifactsDir = await _fs.default.promises.mkdtemp(ARTIFACTS_FOLDER);129 const browserLogsCollector = new _debugLogger.RecentLogsCollector();130 const env = options.env ? (0, _processLauncher.envArrayToObject)(options.env) : process.env;131 let command;132 if (options.executablePath) {133 command = options.executablePath;134 } else {135 try {136 // By default we fallback to the Electron App executable path.137 // 'electron/index.js' resolves to the actual Electron App.138 command = require('electron/index.js');139 } catch (error) {140 if ((error === null || error === void 0 ? void 0 : error.code) === 'MODULE_NOT_FOUND') {141 throw new Error('\n' + (0, _utils.wrapInASCIIBox)(['Electron executablePath not found!', 'Please install it using `npm install -D electron` or set the executablePath to your Electron executable.'].join('\n'), 1));142 }143 throw error;144 }145 } // When debugging Playwright test that runs Electron, NODE_OPTIONS146 // will make the debugger attach to Electron's Node. But Playwright147 // also needs to attach to drive the automation. Disable external debugging.148 delete env.NODE_OPTIONS;149 const {150 launchedProcess,151 gracefullyClose,152 kill153 } = await (0, _processLauncher.launchProcess)({154 command,155 args: electronArguments,156 env,157 log: message => {158 progress.log(message);159 browserLogsCollector.log(message);160 },161 stdio: 'pipe',162 cwd: options.cwd,163 tempDirectories: [artifactsDir],164 attemptToGracefullyClose: () => app.close(),165 handleSIGINT: true,166 handleSIGTERM: true,167 handleSIGHUP: true,168 onExit: () => {}169 });170 const waitForXserverError = new Promise(async (resolve, reject) => {171 waitForLine(progress, launchedProcess, /Unable to open X display/).then(() => reject(new Error(['Unable to open X display!', `================================`, 'Most likely this is because there is no X server available.', "Use 'xvfb-run' on Linux to launch your tests with an emulated display server.", "For example: 'xvfb-run npm run test:e2e'", `================================`, progress.metadata.log].join('\n')))).catch(() => {});172 });173 const nodeMatch = await waitForLine(progress, launchedProcess, /^Debugger listening on (ws:\/\/.*)$/);174 const nodeTransport = await _transport.WebSocketTransport.connect(progress, nodeMatch[1]);175 const nodeConnection = new _crConnection.CRConnection(nodeTransport, _helper.helper.debugProtocolLogger(), browserLogsCollector); // Immediately release exiting process under debug.176 waitForLine(progress, launchedProcess, /Waiting for the debugger to disconnect\.\.\./).then(() => {177 nodeTransport.close();178 }).catch(() => {});179 const chromeMatch = await Promise.race([waitForLine(progress, launchedProcess, /^DevTools listening on (ws:\/\/.*)$/), waitForXserverError]);180 const chromeTransport = await _transport.WebSocketTransport.connect(progress, chromeMatch[1]);181 const browserProcess = {182 onclose: undefined,183 process: launchedProcess,184 close: gracefullyClose,185 kill186 };187 const contextOptions = { ...options,188 noDefaultViewport: true189 };190 const browserOptions = { ...this._playwrightOptions,191 name: 'electron',192 isChromium: true,193 headful: true,194 persistent: contextOptions,195 browserProcess,196 protocolLogger: _helper.helper.debugProtocolLogger(),197 browserLogsCollector,198 artifactsDir,199 downloadsPath: artifactsDir,200 tracesDir: artifactsDir201 };202 (0, _browserContext.validateBrowserContextOptions)(contextOptions, browserOptions);203 const browser = await _crBrowser.CRBrowser.connect(chromeTransport, browserOptions);204 app = new ElectronApplication(this, browser, nodeConnection, launchedProcess);205 return app;206 }, _timeoutSettings.TimeoutSettings.timeout(options));207 }208}209exports.Electron = Electron;210function waitForLine(progress, process, regex) {211 return new Promise((resolve, reject) => {212 const rl = readline.createInterface({213 input: process.stderr214 });215 const failError = new Error('Process failed to launch!');216 const listeners = [_eventsHelper.eventsHelper.addEventListener(rl, 'line', onLine), _eventsHelper.eventsHelper.addEventListener(rl, 'close', reject.bind(null, failError)), _eventsHelper.eventsHelper.addEventListener(process, 'exit', reject.bind(null, failError)), // It is Ok to remove error handler because we did not create process and there is another listener.217 _eventsHelper.eventsHelper.addEventListener(process, 'error', reject.bind(null, failError))];218 progress.cleanupWhenAborted(cleanup);219 function onLine(line) {220 const match = line.match(regex);221 if (!match) return;222 cleanup();223 resolve(match);224 }225 function cleanup() {226 _eventsHelper.eventsHelper.removeEventListeners(listeners);227 }228 });...
recorderApp.js
Source:recorderApp.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.RecorderApp = void 0;6var _fs = _interopRequireDefault(require("fs"));7var _path = _interopRequireDefault(require("path"));8var _progress = require("../progress");9var _events = require("events");10var _instrumentation = require("../instrumentation");11var _utils = require("../../utils");12var mime = _interopRequireWildcard(require("mime"));13var _crApp = require("../chromium/crApp");14var _registry = require("../registry");15function _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); }16function _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; }17function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }18/**19 * Copyright (c) Microsoft Corporation.20 *21 * Licensed under the Apache License, Version 2.0 (the "License");22 * you may not use this file except in compliance with the License.23 * You may obtain a copy of the License at24 *25 * http://www.apache.org/licenses/LICENSE-2.026 *27 * Unless required by applicable law or agreed to in writing, software28 * distributed under the License is distributed on an "AS IS" BASIS,29 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.30 * See the License for the specific language governing permissions and31 * limitations under the License.32 */33class RecorderApp extends _events.EventEmitter {34 constructor(page, wsEndpoint) {35 super();36 this._page = void 0;37 this.wsEndpoint = void 0;38 this.setMaxListeners(0);39 this._page = page;40 this.wsEndpoint = wsEndpoint;41 }42 async close() {43 await this._page.context().close((0, _instrumentation.serverSideCallMetadata)());44 }45 async _init() {46 await (0, _crApp.installAppIcon)(this._page);47 await this._page._setServerRequestInterceptor(async route => {48 if (route.request().url().startsWith('https://playwright/')) {49 const uri = route.request().url().substring('https://playwright/'.length);50 const file = require.resolve('../../webpack/recorder/' + uri);51 const buffer = await _fs.default.promises.readFile(file);52 await route.fulfill({53 status: 200,54 headers: [{55 name: 'Content-Type',56 value: mime.getType(_path.default.extname(file)) || 'application/octet-stream'57 }],58 body: buffer.toString('base64'),59 isBase64: true60 });61 return;62 }63 await route.continue();64 });65 await this._page.exposeBinding('dispatch', false, (_, data) => this.emit('event', data));66 this._page.once('close', () => {67 this.emit('close');68 this._page.context().close((0, _instrumentation.serverSideCallMetadata)()).catch(() => {});69 });70 const mainFrame = this._page.mainFrame();71 await mainFrame.goto((0, _instrumentation.serverSideCallMetadata)(), 'https://playwright/index.html');72 }73 static async open(sdkLanguage, headed) {74 if (process.env.PW_CODEGEN_NO_INSPECTOR) return new HeadlessRecorderApp();75 const recorderPlaywright = require('../playwright').createPlaywright('javascript', true);76 const args = ['--app=data:text/html,', '--window-size=600,600', '--window-position=1020,10', '--test-type='];77 if (process.env.PWTEST_RECORDER_PORT) args.push(`--remote-debugging-port=${process.env.PWTEST_RECORDER_PORT}`);78 const context = await recorderPlaywright.chromium.launchPersistentContext((0, _instrumentation.serverSideCallMetadata)(), '', {79 channel: (0, _registry.findChromiumChannel)(sdkLanguage),80 args,81 noDefaultViewport: true,82 ignoreDefaultArgs: ['--enable-automation'],83 headless: !!process.env.PWTEST_CLI_HEADLESS || (0, _utils.isUnderTest)() && !headed,84 useWebSocket: !!process.env.PWTEST_RECORDER_PORT85 });86 const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), context._browser);87 await controller.run(async progress => {88 await context._browser._defaultContext._loadDefaultContextAsIs(progress);89 });90 const [page] = context.pages();91 const result = new RecorderApp(page, context._browser.options.wsEndpoint);92 await result._init();93 return result;94 }95 async setMode(mode) {96 await this._page.mainFrame().evaluateExpression((mode => {97 window.playwrightSetMode(mode);98 }).toString(), true, mode, 'main').catch(() => {});99 }100 async setFile(file) {101 await this._page.mainFrame().evaluateExpression((file => {102 window.playwrightSetFile(file);103 }).toString(), true, file, 'main').catch(() => {});104 }105 async setPaused(paused) {106 await this._page.mainFrame().evaluateExpression((paused => {107 window.playwrightSetPaused(paused);108 }).toString(), true, paused, 'main').catch(() => {});109 }110 async setSources(sources) {111 await this._page.mainFrame().evaluateExpression((sources => {112 window.playwrightSetSources(sources);113 }).toString(), true, sources, 'main').catch(() => {}); // Testing harness for runCLI mode.114 {115 if (process.env.PWTEST_CLI_EXIT && sources.length) {116 process.stdout.write('\n-------------8<-------------\n');117 process.stdout.write(sources[0].text);118 process.stdout.write('\n-------------8<-------------\n');119 }120 }121 }122 async setSelector(selector, focus) {123 await this._page.mainFrame().evaluateExpression((arg => {124 window.playwrightSetSelector(arg.selector, arg.focus);125 }).toString(), true, {126 selector,127 focus128 }, 'main').catch(() => {});129 }130 async updateCallLogs(callLogs) {131 await this._page.mainFrame().evaluateExpression((callLogs => {132 window.playwrightUpdateLogs(callLogs);133 }).toString(), true, callLogs, 'main').catch(() => {});134 }135 async bringToFront() {136 await this._page.bringToFront();137 }138}139exports.RecorderApp = RecorderApp;140class HeadlessRecorderApp extends _events.EventEmitter {141 async close() {}142 async setPaused(paused) {}143 async setMode(mode) {}144 async setFile(file) {}145 async setSelector(selector, focus) {}146 async updateCallLogs(callLogs) {}147 bringToFront() {}148 async setSources(sources) {}...
videoRecorder.js
Source:videoRecorder.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.VideoRecorder = void 0;6var _utils = require("../../utils");7var _page = require("../page");8var _processLauncher = require("../../utils/processLauncher");9var _progress = require("../progress");10var _instrumentation = require("../instrumentation");11/**12 * Copyright (c) Microsoft Corporation.13 *14 * Licensed under the Apache License, Version 2.0 (the "License");15 * you may not use this file except in compliance with the License.16 * You may obtain a copy of the License at17 *18 * http://www.apache.org/licenses/LICENSE-2.019 *20 * Unless required by applicable law or agreed to in writing, software21 * distributed under the License is distributed on an "AS IS" BASIS,22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.23 * See the License for the specific language governing permissions and24 * limitations under the License.25 */26const fps = 25;27class VideoRecorder {28 static async launch(page, ffmpegPath, options) {29 if (!options.outputFile.endsWith('.webm')) throw new Error('File must have .webm extension');30 const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), page);31 controller.setLogName('browser');32 return await controller.run(async progress => {33 const recorder = new VideoRecorder(page, ffmpegPath, progress);34 await recorder._launch(options);35 return recorder;36 });37 }38 constructor(page, ffmpegPath, progress) {39 this._process = null;40 this._gracefullyClose = null;41 this._lastWritePromise = Promise.resolve();42 this._lastFrameTimestamp = 0;43 this._lastFrameBuffer = null;44 this._lastWriteTimestamp = 0;45 this._progress = void 0;46 this._frameQueue = [];47 this._isStopped = false;48 this._ffmpegPath = void 0;49 this._progress = progress;50 this._ffmpegPath = ffmpegPath;51 page.on(_page.Page.Events.ScreencastFrame, frame => this.writeFrame(frame.buffer, frame.timestamp));52 }53 async _launch(options) {54 // How to tune the codec:55 // 1. Read vp8 documentation to figure out the options.56 // https://www.webmproject.org/docs/encoder-parameters/57 // 2. Use the following command to map the options to ffmpeg arguments.58 // $ ./third_party/ffmpeg/ffmpeg-mac -h encoder=vp859 // 3. A bit more about passing vp8 options to ffmpeg.60 // https://trac.ffmpeg.org/wiki/Encode/VP861 // 4. Tuning for VP9:62 // https://developers.google.com/media/vp9/live-encoding63 //64 // How to stress-test video recording (runs 10 recorders in parallel to book all cpus available):65 // $ node ./utils/video_stress.js66 //67 // We use the following vp8 options:68 // "-qmin 0 -qmax 50" - quality variation from 0 to 50.69 // Suggested here: https://trac.ffmpeg.org/wiki/Encode/VP870 // "-crf 8" - constant quality mode, 4-63, lower means better quality.71 // "-deadline realtime -speed 8" - do not use too much cpu to keep up with incoming frames.72 // "-b:v 1M" - video bitrate. Default value is too low for vp873 // Suggested here: https://trac.ffmpeg.org/wiki/Encode/VP874 // Note that we can switch to "-qmin 20 -qmax 50 -crf 30" for smaller video size but worse quality.75 //76 // We use "pad" and "crop" video filters (-vf option) to resize incoming frames77 // that might be of the different size to the desired video size.78 // https://ffmpeg.org/ffmpeg-filters.html#pad-179 // https://ffmpeg.org/ffmpeg-filters.html#crop80 //81 // We use "image2pipe" mode to pipe frames and get a single video - https://trac.ffmpeg.org/wiki/Slideshow82 // "-f image2pipe -c:v mjpeg -i -" forces input to be read from standard input, and forces83 // mjpeg input image format.84 // "-avioflags direct" reduces general buffering.85 // "-fpsprobesize 0 -probesize 32 -analyzeduration 0" reduces initial buffering86 // while analyzing input fps and other stats.87 //88 // "-y" means overwrite output.89 // "-an" means no audio.90 // "-threads 1" means using one thread. This drastically reduces stalling when91 // cpu is overbooked. By default vp8 tries to use all available threads?92 const w = options.width;93 const h = options.height;94 const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i - -y -an -r ${fps} -c:v vp8 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 -vf pad=${w}:${h}:0:0:gray,crop=${w}:${h}:0:0`.split(' ');95 args.push(options.outputFile);96 const progress = this._progress;97 const {98 launchedProcess,99 gracefullyClose100 } = await (0, _processLauncher.launchProcess)({101 command: this._ffmpegPath,102 args,103 stdio: 'stdin',104 log: message => progress.log(message),105 tempDirectories: [],106 attemptToGracefullyClose: async () => {107 progress.log('Closing stdin...');108 launchedProcess.stdin.end();109 },110 onExit: (exitCode, signal) => {111 progress.log(`ffmpeg onkill exitCode=${exitCode} signal=${signal}`);112 }113 });114 launchedProcess.stdin.on('finish', () => {115 progress.log('ffmpeg finished input.');116 });117 launchedProcess.stdin.on('error', () => {118 progress.log('ffmpeg error.');119 });120 this._process = launchedProcess;121 this._gracefullyClose = gracefullyClose;122 }123 writeFrame(frame, timestamp) {124 (0, _utils.assert)(this._process);125 if (this._isStopped) return;126 this._progress.log(`writing frame ` + timestamp);127 if (this._lastFrameBuffer) {128 const durationSec = timestamp - this._lastFrameTimestamp;129 const repeatCount = Math.max(1, Math.round(fps * durationSec));130 for (let i = 0; i < repeatCount; ++i) this._frameQueue.push(this._lastFrameBuffer);131 this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames());132 }133 this._lastFrameBuffer = frame;134 this._lastFrameTimestamp = timestamp;135 this._lastWriteTimestamp = (0, _utils.monotonicTime)();136 }137 async _sendFrames() {138 while (this._frameQueue.length) await this._sendFrame(this._frameQueue.shift());139 }140 async _sendFrame(frame) {141 return new Promise(f => this._process.stdin.write(frame, f)).then(error => {142 if (error) this._progress.log(`ffmpeg failed to write: ${error}`);143 });144 }145 async stop() {146 if (this._isStopped) return;147 this.writeFrame(Buffer.from([]), this._lastFrameTimestamp + ((0, _utils.monotonicTime)() - this._lastWriteTimestamp) / 1000);148 this._isStopped = true;149 await this._lastWritePromise;150 await this._gracefullyClose();151 }152}...
playwrightConnection.js
Source:playwrightConnection.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.PlaywrightConnection = void 0;6var _server = require("../server");7var _browser = require("../server/browser");8var _instrumentation = require("../server/instrumentation");9var _processLauncher = require("../utils/processLauncher");10var _socksProxy = require("../common/socksProxy");11/**12 * Copyright (c) Microsoft Corporation.13 *14 * Licensed under the Apache License, Version 2.0 (the "License");15 * you may not use this file except in compliance with the License.16 * You may obtain a copy of the License at17 *18 * http://www.apache.org/licenses/LICENSE-2.019 *20 * Unless required by applicable law or agreed to in writing, software21 * distributed under the License is distributed on an "AS IS" BASIS,22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.23 * See the License for the specific language governing permissions and24 * limitations under the License.25 */26class PlaywrightConnection {27 constructor(ws, enableSocksProxy, browserAlias, headless, browser, log, onClose) {28 this._ws = void 0;29 this._onClose = void 0;30 this._dispatcherConnection = void 0;31 this._cleanups = [];32 this._debugLog = void 0;33 this._disconnected = false;34 this._ws = ws;35 this._onClose = onClose;36 this._debugLog = log;37 this._dispatcherConnection = new _server.DispatcherConnection();38 this._dispatcherConnection.onmessage = message => {39 if (ws.readyState !== ws.CLOSING) ws.send(JSON.stringify(message));40 };41 ws.on('message', message => {42 this._dispatcherConnection.dispatch(JSON.parse(Buffer.from(message).toString()));43 });44 ws.on('close', () => this._onDisconnect());45 ws.on('error', error => this._onDisconnect(error));46 new _server.Root(this._dispatcherConnection, async scope => {47 if (browser) return await this._initPreLaunchedBrowserMode(scope, browser);48 if (!browserAlias) return await this._initPlaywrightConnectMode(scope, enableSocksProxy);49 return await this._initLaunchBrowserMode(scope, enableSocksProxy, browserAlias, headless);50 });51 }52 async _initPlaywrightConnectMode(scope, enableSocksProxy) {53 this._debugLog(`engaged playwright.connect mode`);54 const playwright = (0, _server.createPlaywright)('javascript'); // Close all launched browsers on disconnect.55 this._cleanups.push(() => (0, _processLauncher.gracefullyCloseAll)());56 const socksProxy = enableSocksProxy ? await this._enableSocksProxy(playwright) : undefined;57 return new _server.PlaywrightDispatcher(scope, playwright, socksProxy);58 }59 async _initLaunchBrowserMode(scope, enableSocksProxy, browserAlias, headless) {60 this._debugLog(`engaged launch mode for "${browserAlias}"`);61 const executable = _server.registry.findExecutable(browserAlias);62 if (!executable || !executable.browserName) throw new Error(`Unsupported browser "${browserAlias}`);63 const playwright = (0, _server.createPlaywright)('javascript');64 const socksProxy = enableSocksProxy ? await this._enableSocksProxy(playwright) : undefined;65 const browser = await playwright[executable.browserName].launch((0, _instrumentation.serverSideCallMetadata)(), {66 channel: executable.type === 'browser' ? undefined : executable.name,67 headless68 }); // Close the browser on disconnect.69 // TODO: it is technically possible to launch more browsers over protocol.70 this._cleanups.push(() => browser.close());71 browser.on(_browser.Browser.Events.Disconnected, () => {72 // Underlying browser did close for some reason - force disconnect the client.73 this.close({74 code: 1001,75 reason: 'Browser closed'76 });77 });78 return new _server.PlaywrightDispatcher(scope, playwright, socksProxy, browser);79 }80 async _initPreLaunchedBrowserMode(scope, browser) {81 this._debugLog(`engaged pre-launched mode`);82 browser.on(_browser.Browser.Events.Disconnected, () => {83 // Underlying browser did close for some reason - force disconnect the client.84 this.close({85 code: 1001,86 reason: 'Browser closed'87 });88 });89 const playwright = browser.options.rootSdkObject;90 const playwrightDispatcher = new _server.PlaywrightDispatcher(scope, playwright, undefined, browser); // In pre-launched mode, keep the browser and just cleanup new contexts.91 // TODO: it is technically possible to launch more browsers over protocol.92 this._cleanups.push(() => playwrightDispatcher.cleanup());93 return playwrightDispatcher;94 }95 async _enableSocksProxy(playwright) {96 const socksProxy = new _socksProxy.SocksProxy();97 playwright.options.socksProxyPort = await socksProxy.listen(0);98 this._debugLog(`started socks proxy on port ${playwright.options.socksProxyPort}`);99 this._cleanups.push(() => socksProxy.close());100 return socksProxy;101 }102 async _onDisconnect(error) {103 this._disconnected = true;104 this._debugLog(`disconnected. error: ${error}`); // Avoid sending any more messages over closed socket.105 this._dispatcherConnection.onmessage = () => {};106 this._debugLog(`starting cleanup`);107 for (const cleanup of this._cleanups) await cleanup().catch(() => {});108 this._onClose();109 this._debugLog(`finished cleanup`);110 }111 async close(reason) {112 if (this._disconnected) return;113 this._debugLog(`force closing connection: ${(reason === null || reason === void 0 ? void 0 : reason.reason) || ''} (${(reason === null || reason === void 0 ? void 0 : reason.code) || 0})`);114 try {115 this._ws.close(reason === null || reason === void 0 ? void 0 : reason.code, reason === null || reason === void 0 ? void 0 : reason.reason);116 } catch (e) {}117 }118}...
traceViewer.js
Source:traceViewer.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.showTraceViewer = showTraceViewer;6var _path = _interopRequireDefault(require("path"));7var _fs = _interopRequireDefault(require("fs"));8var consoleApiSource = _interopRequireWildcard(require("../../../generated/consoleApiSource"));9var _httpServer = require("../../../utils/httpServer");10var _registry = require("../../registry");11var _utils = require("../../../utils");12var _crApp = require("../../chromium/crApp");13var _instrumentation = require("../../instrumentation");14var _playwright = require("../../playwright");15var _progress = require("../../progress");16function _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); }17function _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; }18function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }19/**20 * Copyright (c) Microsoft Corporation.21 *22 * Licensed under the Apache License, Version 2.0 (the "License");23 * you may not use this file except in compliance with the License.24 * You may obtain a copy of the License at25 *26 * http://www.apache.org/licenses/LICENSE-2.027 *28 * Unless required by applicable law or agreed to in writing, software29 * distributed under the License is distributed on an "AS IS" BASIS,30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.31 * See the License for the specific language governing permissions and32 * limitations under the License.33 */34async function showTraceViewer(traceUrls, browserName, headless = false, port) {35 for (const traceUrl of traceUrls) {36 if (!traceUrl.startsWith('http://') && !traceUrl.startsWith('https://') && !_fs.default.existsSync(traceUrl)) {37 // eslint-disable-next-line no-console38 console.error(`Trace file ${traceUrl} does not exist!`);39 process.exit(1);40 }41 }42 const server = new _httpServer.HttpServer();43 server.routePrefix('/trace', (request, response) => {44 const url = new URL('http://localhost' + request.url);45 const relativePath = url.pathname.slice('/trace'.length);46 if (relativePath.startsWith('/file')) {47 try {48 return server.serveFile(request, response, url.searchParams.get('path'));49 } catch (e) {50 return false;51 }52 }53 const absolutePath = _path.default.join(__dirname, '..', '..', '..', 'webpack', 'traceViewer', ...relativePath.split('/'));54 return server.serveFile(request, response, absolutePath);55 });56 const urlPrefix = await server.start(port);57 const traceViewerPlaywright = (0, _playwright.createPlaywright)('javascript', true);58 const traceViewerBrowser = (0, _utils.isUnderTest)() ? 'chromium' : browserName;59 const args = traceViewerBrowser === 'chromium' ? ['--app=data:text/html,', '--window-size=1280,800', '--test-type='] : [];60 if ((0, _utils.isUnderTest)()) args.push(`--remote-debugging-port=0`);61 const context = await traceViewerPlaywright[traceViewerBrowser].launchPersistentContext((0, _instrumentation.serverSideCallMetadata)(), '', {62 // TODO: store language in the trace.63 channel: (0, _registry.findChromiumChannel)(traceViewerPlaywright.options.sdkLanguage),64 args,65 noDefaultViewport: true,66 ignoreDefaultArgs: ['--enable-automation'],67 headless,68 useWebSocket: (0, _utils.isUnderTest)()69 });70 const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), context._browser);71 await controller.run(async progress => {72 await context._browser._defaultContext._loadDefaultContextAsIs(progress);73 });74 await context.extendInjectedScript(consoleApiSource.source);75 const [page] = context.pages();76 if (traceViewerBrowser === 'chromium') await (0, _crApp.installAppIcon)(page);77 if ((0, _utils.isUnderTest)()) page.on('close', () => context.close((0, _instrumentation.serverSideCallMetadata)()).catch(() => {}));else page.on('close', () => process.exit());78 const searchQuery = traceUrls.length ? '?' + traceUrls.map(t => `trace=${t}`).join('&') : '';79 await page.mainFrame().goto((0, _instrumentation.serverSideCallMetadata)(), urlPrefix + `/trace/index.html${searchQuery}`);80 return context;...
browserDispatcher.js
Source:browserDispatcher.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.ConnectedBrowserDispatcher = exports.BrowserDispatcher = void 0;6var _browser = require("../browser");7var _browserContextDispatcher = require("./browserContextDispatcher");8var _cdpSessionDispatcher = require("./cdpSessionDispatcher");9var _dispatcher = require("./dispatcher");10var _instrumentation = require("../instrumentation");11var _browserContext = require("../browserContext");12var _selectors = require("../selectors");13/**14 * Copyright (c) Microsoft Corporation.15 *16 * Licensed under the Apache License, Version 2.0 (the 'License");17 * you may not use this file except in compliance with the License.18 * You may obtain a copy of the License at19 *20 * http://www.apache.org/licenses/LICENSE-2.021 *22 * Unless required by applicable law or agreed to in writing, software23 * distributed under the License is distributed on an "AS IS" BASIS,24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.25 * See the License for the specific language governing permissions and26 * limitations under the License.27 */28class BrowserDispatcher extends _dispatcher.Dispatcher {29 constructor(scope, browser) {30 super(scope, browser, 'Browser', {31 version: browser.version(),32 name: browser.options.name33 }, true);34 this._type_Browser = true;35 browser.on(_browser.Browser.Events.Disconnected, () => this._didClose());36 }37 _didClose() {38 this._dispatchEvent('close');39 this._dispose();40 }41 async newContext(params, metadata) {42 const context = await this._object.newContext(metadata, params);43 return {44 context: new _browserContextDispatcher.BrowserContextDispatcher(this._scope, context)45 };46 }47 async close() {48 await this._object.close();49 }50 async killForTests() {51 await this._object.killForTests();52 }53 async newBrowserCDPSession() {54 if (!this._object.options.isChromium) throw new Error(`CDP session is only available in Chromium`);55 const crBrowser = this._object;56 return {57 session: new _cdpSessionDispatcher.CDPSessionDispatcher(this._scope, await crBrowser.newBrowserCDPSession())58 };59 }60 async startTracing(params) {61 if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);62 const crBrowser = this._object;63 await crBrowser.startTracing(params.page ? params.page._object : undefined, params);64 }65 async stopTracing() {66 if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);67 const crBrowser = this._object;68 const buffer = await crBrowser.stopTracing();69 return {70 binary: buffer.toString('base64')71 };72 }73} // This class implements multiplexing browser dispatchers over a single Browser instance.74exports.BrowserDispatcher = BrowserDispatcher;75class ConnectedBrowserDispatcher extends _dispatcher.Dispatcher {76 constructor(scope, browser) {77 super(scope, browser, 'Browser', {78 version: browser.version(),79 name: browser.options.name80 }, true); // When we have a remotely-connected browser, each client gets a fresh Selector instance,81 // so that two clients do not interfere between each other.82 this._type_Browser = true;83 this._contexts = new Set();84 this.selectors = void 0;85 this.selectors = new _selectors.Selectors();86 }87 async newContext(params, metadata) {88 if (params.recordVideo) params.recordVideo.dir = this._object.options.artifactsDir;89 const context = await this._object.newContext(metadata, params);90 this._contexts.add(context);91 context.setSelectors(this.selectors);92 context.on(_browserContext.BrowserContext.Events.Close, () => this._contexts.delete(context));93 return {94 context: new _browserContextDispatcher.BrowserContextDispatcher(this._scope, context)95 };96 }97 async close() {// Client should not send us Browser.close.98 }99 async killForTests() {// Client should not send us Browser.killForTests.100 }101 async newBrowserCDPSession() {102 if (!this._object.options.isChromium) throw new Error(`CDP session is only available in Chromium`);103 const crBrowser = this._object;104 return {105 session: new _cdpSessionDispatcher.CDPSessionDispatcher(this._scope, await crBrowser.newBrowserCDPSession())106 };107 }108 async startTracing(params) {109 if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);110 const crBrowser = this._object;111 await crBrowser.startTracing(params.page ? params.page._object : undefined, params);112 }113 async stopTracing() {114 if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);115 const crBrowser = this._object;116 const buffer = await crBrowser.stopTracing();117 return {118 binary: buffer.toString('base64')119 };120 }121 async cleanupContexts() {122 await Promise.all(Array.from(this._contexts).map(context => context.close((0, _instrumentation.serverSideCallMetadata)())));123 }124}...
browserServerImpl.js
Source:browserServerImpl.js
1"use strict";2Object.defineProperty(exports, "__esModule", {3 value: true4});5exports.BrowserServerLauncherImpl = void 0;6var _ws = require("ws");7var _clientHelper = require("./client/clientHelper");8var _utils = require("./utils");9var _instrumentation = require("./server/instrumentation");10var _playwright = require("./server/playwright");11var _playwrightServer = require("./remote/playwrightServer");12var _helper = require("./server/helper");13var _stackTrace = require("./utils/stackTrace");14/**15 * Copyright (c) Microsoft Corporation.16 *17 * Licensed under the Apache License, Version 2.0 (the 'License");18 * you may not use this file except in compliance with the License.19 * You may obtain a copy of the License at20 *21 * http://www.apache.org/licenses/LICENSE-2.022 *23 * Unless required by applicable law or agreed to in writing, software24 * distributed under the License is distributed on an "AS IS" BASIS,25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.26 * See the License for the specific language governing permissions and27 * limitations under the License.28 */29class BrowserServerLauncherImpl {30 constructor(browserName) {31 this._browserName = void 0;32 this._browserName = browserName;33 }34 async launchServer(options = {}) {35 const playwright = (0, _playwright.createPlaywright)('javascript'); // 1. Pre-launch the browser36 const metadata = (0, _instrumentation.serverSideCallMetadata)();37 const browser = await playwright[this._browserName].launch(metadata, { ...options,38 ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,39 ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),40 env: options.env ? (0, _clientHelper.envObjectToArray)(options.env) : undefined41 }, toProtocolLogger(options.logger)).catch(e => {42 const log = _helper.helper.formatBrowserLogs(metadata.log);43 (0, _stackTrace.rewriteErrorMessage)(e, `${e.message} Failed to launch browser.${log}`);44 throw e;45 });46 let path = `/${(0, _utils.createGuid)()}`;47 if (options.wsPath) path = options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}`; // 2. Start the server48 const server = new _playwrightServer.PlaywrightServer(path, Infinity, false, browser);49 const wsEndpoint = await server.listen(options.port); // 3. Return the BrowserServer interface50 const browserServer = new _ws.EventEmitter();51 browserServer.process = () => browser.options.browserProcess.process;52 browserServer.wsEndpoint = () => wsEndpoint;53 browserServer.close = () => browser.options.browserProcess.close();54 browserServer.kill = () => browser.options.browserProcess.kill();55 browserServer._disconnectForTest = () => server.close();56 browser.options.browserProcess.onclose = async (exitCode, signal) => {57 server.close();58 browserServer.emit('close', exitCode, signal);59 };60 return browserServer;61 }62}63exports.BrowserServerLauncherImpl = BrowserServerLauncherImpl;64function toProtocolLogger(logger) {65 return logger ? (direction, message) => {66 if (logger.isEnabled('protocol', 'verbose')) logger.log('protocol', 'verbose', (direction === 'send' ? 'SEND ⺠' : 'â RECV ') + JSON.stringify(message), [], {});67 } : undefined;...
instrumentation.js
Source:instrumentation.js
...51 };52 }53 });54}55function serverSideCallMetadata() {56 return {57 id: '',58 wallTime: 0,59 startTime: 0,60 endTime: 0,61 type: 'Internal',62 method: '',63 params: {},64 log: [],65 snapshots: [],66 isServerSide: true67 };...
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 const metadata = await page.serverSideCallMetadata();7 console.log(metadata);8 await browser.close();9})();
Using AI Code Generation
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 const response = await page.serverSideCallMetadata();7 console.log(response);8 await browser.close();9})();10{11}12const { chromium } = require('playwright');13(async () => {14 const browser = await chromium.launch();15 const context = await browser.newContext();16 const page = await context.newPage();17 const response = await page.serverSideCallMetadata();18 console.log(response);19 await browser.close();20})();21{22}23const { chromium } = require('playwright');24(async () => {25 const browser = await chromium.launch();26 const context = await browser.newContext();27 const page = await context.newPage();28 const response = await page.serverSideCallMetadata();29 console.log(response);30 await browser.close();31})();32{
Using AI Code Generation
1const { firefox } = require('playwright');2(async () => {3 const browser = await firefox.launch({4 });5 const context = await browser.newContext();6 const page = await context.newPage();7 const metadata = await page.serverSideCallMetadata();8 console.log(metadata);9 await browser.close();10})();11{12 {13 {14 "params": {},15 "result": {16 }17 },18 {19 "params": {20 },21 "result": {}22 }23 }24}
Using AI Code Generation
1const { serverSideCallMetadata } = require('playwright/lib/server/supplements/recorder/recorderSupplement');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 console.log(serverSideCallMetadata(page));8 await browser.close();9})();10Output: { frameId: 'F1', requestId: 'R1', loaderId: 'L1' }11const frame = page.frames()[0];12console.log(frame.frameId());13const frame = page.frames()[0];14console.log(frame.serverSideCallMetadata());15Output: { frameId: 'F2', requestId: 'R2', loaderId: 'L2' }16const frame = page.frames()[0];17console.log(frame.loaderId());18const frame = page.frames()[0];19console.log(frame.frameId());20const frame = page.frames()[0];21console.log(frame.serverSideCallMetadata());22Output: { frameId: 'F2', requestId: 'R2', loaderId: 'L2' }
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 const browser = await playwright['chromium'].launch();4 const page = await browser.newPage();5 const metadata = await page.evaluate(() => {6 return window.playwright.internal.serverSideCallMetadata();7 });8 console.log(metadata);9 await browser.close();10})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { getServerSideCallMetadata } = require('playwright/lib/server/serverSideCallMetadata');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 const metadata = getServerSideCallMetadata(page);8 console.log(metadata);9 await browser.close();10})();11{ sessionId: '6d1f1c2e-2b7a-4d2f-a4e9-9b7a0b4d4b7a',12 isFirefox: false }13const { chromium } = require('playwright');14const { getServerSideCallMetadata } = require('playwright/lib/server/serverSideCallMetadata');15const browser = await chromium.launch();16const context = await browser.newContext();17const page = await context.newPage();18const metadata = getServerSideCallMetadata(page);
Using AI Code Generation
1const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');2const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');3const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');4const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');5const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');6const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');7const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');8const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');9const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');10const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');11const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');12const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');13const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');14const {serverSideCallMetadata} = require('playwright/lib/internal/inspectorInstrumentation');15const {serverSideCallMetadata}
Using AI Code Generation
1import { serverSideCallMetadata } from 'playwright/lib/server/supplements/recorder/recorderSupplement';2const metadata = serverSideCallMetadata();3console.log(metadata);4const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();5console.log(metadata);6const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();7console.log(metadata);8const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();9console.log(metadata);10const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();11console.log(metadata);12const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();13console.log(metadata);14const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();15console.log(metadata);16const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();17console.log(metadata);18const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();19console.log(metadata);20const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();21console.log(metadata);22const metadata = require('playwright/lib/server/supplements/recorder/recorderSupplement').serverSideCallMetadata();23console.log(metadata);24const metadata = require('playwright/lib/server/supplements/recorder/recorderSup
Using AI Code Generation
1const { serverSideCallMetadata } = require('playwright/lib/server/callMetadata');2const { CallMetadata } = require('playwright/lib/server/callMetadata');3const { test } = require('playwright');4(async () => {5 const browser = await test.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const metadata = serverSideCallMetadata();9 console.log(metadata);10 console.log(metadata instanceof CallMetadata);11 await browser.close();12})();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!