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/recorderSupUsing 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!!
