Best JavaScript code snippet using playwright-internal
cli.ts
Source:cli.ts  
...39import { registry, writeDockerVersion } from '../server';40const packageJSON = require('../../package.json');41program42    .version('Version ' + (process.env.PW_CLI_DISPLAY_VERSION || packageJSON.version))43    .name(buildBasePlaywrightCLICommand(process.env.PW_LANG_NAME));44program45    .command('mark-docker-image [dockerImageNameTemplate]', { hidden: true })46    .description('mark docker image')47    .allowUnknownOption(true)48    .action(function(dockerImageNameTemplate) {49      assert(dockerImageNameTemplate, 'dockerImageNameTemplate is required');50      writeDockerVersion(dockerImageNameTemplate).catch(logErrorAndExit);51    });52commandWithOpenOptions('open [url]', 'open page in browser specified via -b, --browser', [])53    .action(function(url, options) {54      open(options, url, language()).catch(logErrorAndExit);55    })56    .addHelpText('afterAll', `57Examples:58  $ open  $ open -b webkit https://example.com`);59commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions',60    [61      ['-o, --output <file name>', 'saves the generated script to a file'],62      ['--target <language>', `language to generate, one of javascript, test, python, python-async, csharp`, language()],63    ]).action(function(url, options) {64  codegen(options, url, options.target, options.output).catch(logErrorAndExit);65}).addHelpText('afterAll', `66Examples:67  $ codegen68  $ codegen --target=python69  $ codegen -b webkit https://example.com`);70program71    .command('debug <app> [args...]', { hidden: true })72    .description('run command in debug mode: disable timeout, open inspector')73    .allowUnknownOption(true)74    .action(function(app, options) {75      spawn(app, options, {76        env: { ...process.env, PWDEBUG: '1' },77        stdio: 'inherit'78      });79    }).addHelpText('afterAll', `80Examples:81  $ debug node test.js82  $ debug npm run test`);83function suggestedBrowsersToInstall() {84  return registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');85}86function checkBrowsersToInstall(args: string[]): Executable[] {87  const faultyArguments: string[] = [];88  const executables: Executable[] = [];89  for (const arg of args) {90    const executable = registry.findExecutable(arg);91    if (!executable || executable.installType === 'none')92      faultyArguments.push(arg);93    else94      executables.push(executable);95  }96  if (faultyArguments.length) {97    console.log(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);98    process.exit(1);99  }100  return executables;101}102program103    .command('install [browser...]')104    .description('ensure browsers necessary for this version of Playwright are installed')105    .option('--with-deps', 'install system dependencies for browsers')106    .option('--force', 'force reinstall of stable browser channels')107    .action(async function(args: string[], options: { withDeps?: boolean, force?: boolean }) {108      if (isLikelyNpxGlobal()) {109        console.error(wrapInASCIIBox([110          `WARNING: It looks like you are running 'npx playwright install' without first`,111          `installing your project's dependencies.`,112          ``,113          `To avoid unexpected behavior, please install your dependencies first, and`,114          `then run Playwright's install command:`,115          ``,116          `    npm install`,117          `    npx playwright install`,118          ``,119          `If your project does not yet depend on Playwright, first install the`,120          `applicable npm package (most commonly @playwright/test), and`,121          `then run Playwright's install command to download the browsers:`,122          ``,123          `    npm install @playwright/test`,124          `    npx playwright install`,125          ``,126        ].join('\n'), 1));127      }128      try {129        if (!args.length) {130          const executables = registry.defaultExecutables();131          if (options.withDeps)132            await registry.installDeps(executables, false);133          await registry.install(executables, false /* forceReinstall */);134        } else {135          const installDockerImage = args.some(arg => arg === 'docker-image');136          args = args.filter(arg => arg !== 'docker-image');137          if (installDockerImage) {138            const imageName = `mcr.microsoft.com/playwright:v${getPlaywrightVersion()}-focal`;139            const { code } = await spawnAsync('docker', ['pull', imageName], { stdio: 'inherit' });140            if (code !== 0) {141              console.log('Failed to pull docker image');142              process.exit(1);143            }144          }145          const executables = checkBrowsersToInstall(args);146          if (options.withDeps)147            await registry.installDeps(executables, false);148          await registry.install(executables, !!options.force /* forceReinstall */);149        }150      } catch (e) {151        console.log(`Failed to install browsers\n${e}`);152        process.exit(1);153      }154    }).addHelpText('afterAll', `155Examples:156  - $ install157    Install default browsers.158  - $ install chrome firefox159    Install custom browsers, supports ${suggestedBrowsersToInstall()}.`);160program161    .command('install-deps [browser...]')162    .description('install dependencies necessary to run browsers (will ask for sudo permissions)')163    .option('--dry-run', 'Do not execute installation commands, only print them')164    .action(async function(args: string[], options: { dryRun?: boolean }) {165      try {166        if (!args.length)167          await registry.installDeps(registry.defaultExecutables(), !!options.dryRun);168        else169          await registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun);170      } catch (e) {171        console.log(`Failed to install browser dependencies\n${e}`);172        process.exit(1);173      }174    }).addHelpText('afterAll', `175Examples:176  - $ install-deps177    Install dependencies for default browsers.178  - $ install-deps chrome firefox179    Install dependencies for specific browsers, supports ${suggestedBrowsersToInstall()}.`);180const browsers = [181  { alias: 'cr', name: 'Chromium', type: 'chromium' },182  { alias: 'ff', name: 'Firefox', type: 'firefox' },183  { alias: 'wk', name: 'WebKit', type: 'webkit' },184];185for (const { alias, name, type } of browsers) {186  commandWithOpenOptions(`${alias} [url]`, `open page in ${name}`, [])187      .action(function(url, options) {188        open({ ...options, browser: type }, url, options.target).catch(logErrorAndExit);189      }).addHelpText('afterAll', `190Examples:191  $ ${alias} https://example.com`);192}193commandWithOpenOptions('screenshot <url> <filename>', 'capture a page screenshot',194    [195      ['--wait-for-selector <selector>', 'wait for selector before taking a screenshot'],196      ['--wait-for-timeout <timeout>', 'wait for timeout in milliseconds before taking a screenshot'],197      ['--full-page', 'whether to take a full page screenshot (entire scrollable area)'],198    ]).action(function(url, filename, command) {199  screenshot(command, command, url, filename).catch(logErrorAndExit);200}).addHelpText('afterAll', `201Examples:202  $ screenshot -b webkit https://example.com example.png`);203commandWithOpenOptions('pdf <url> <filename>', 'save page as pdf',204    [205      ['--wait-for-selector <selector>', 'wait for given selector before saving as pdf'],206      ['--wait-for-timeout <timeout>', 'wait for given timeout in milliseconds before saving as pdf'],207    ]).action(function(url, filename, options) {208  pdf(options, options, url, filename).catch(logErrorAndExit);209}).addHelpText('afterAll', `210Examples:211  $ pdf https://example.com example.pdf`);212program213    .command('experimental-grid-server', { hidden: true })214    .option('--port <port>', 'grid port; defaults to 3333')215    .option('--address <address>', 'address of the server')216    .option('--agent-factory <factory>', 'path to grid agent factory or npm package')217    .option('--auth-token <authToken>', 'optional authentication token')218    .action(function(options) {219      launchGridServer(options.agentFactory, options.port || 3333, options.address, options.authToken);220    });221program222    .command('experimental-grid-agent', { hidden: true })223    .requiredOption('--agent-id <agentId>', 'agent ID')224    .requiredOption('--grid-url <gridURL>', 'grid URL')225    .option('--run-id <github run_id>', 'Workflow run_id')226    .action(function(options) {227      launchGridAgent(options.agentId, options.gridUrl, options.runId);228    });229program230    .command('run-driver', { hidden: true })231    .action(function(options) {232      runDriver();233    });234program235    .command('run-server', { hidden: true })236    .option('--port <port>', 'Server port')237    .option('--path <path>', 'Endpoint Path', '/')238    .option('--max-clients <maxClients>', 'Maximum clients')239    .option('--no-socks-proxy', 'Disable Socks Proxy')240    .action(function(options) {241      runServer(options.port ? +options.port : undefined,  options.path, options.maxClients ? +options.maxClients : Infinity, options.socksProxy).catch(logErrorAndExit);242    });243program244    .command('print-api-json', { hidden: true })245    .action(function(options) {246      printApiJson();247    });248program249    .command('launch-server', { hidden: true })250    .requiredOption('--browser <browserName>', 'Browser name, one of "chromium", "firefox" or "webkit"')251    .option('--config <path-to-config-file>', 'JSON file with launchServer options')252    .action(function(options) {253      launchBrowserServer(options.browser, options.config);254    });255program256    .command('show-trace [trace...]')257    .option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium')258    .description('Show trace viewer')259    .action(function(traces, options) {260      if (options.browser === 'cr')261        options.browser = 'chromium';262      if (options.browser === 'ff')263        options.browser = 'firefox';264      if (options.browser === 'wk')265        options.browser = 'webkit';266      showTraceViewer(traces, options.browser, false, 9322).catch(logErrorAndExit);267    }).addHelpText('afterAll', `268Examples:269  $ show-trace https://example.com/trace.zip`);270if (!process.env.PW_LANG_NAME) {271  let playwrightTestPackagePath = null;272  try {273    playwrightTestPackagePath = require.resolve('@playwright/test/lib/cli', {274      paths: [__dirname, process.cwd()]275    });276  } catch {}277  if (playwrightTestPackagePath) {278    require(playwrightTestPackagePath).addTestCommand(program);279    require(playwrightTestPackagePath).addShowReportCommand(program);280    require(playwrightTestPackagePath).addListFilesCommand(program);281  } else {282    {283      const command = program.command('test').allowUnknownOption(true);284      command.description('Run tests with Playwright Test. Available in @playwright/test package.');285      command.action(async () => {286        console.error('Please install @playwright/test package to use Playwright Test.');287        console.error('  npm install -D @playwright/test');288        process.exit(1);289      });290    }291    {292      const command = program.command('show-report').allowUnknownOption(true);293      command.description('Show Playwright Test HTML report. Available in @playwright/test package.');294      command.action(async () => {295        console.error('Please install @playwright/test package to use Playwright Test.');296        console.error('  npm install -D @playwright/test');297        process.exit(1);298      });299    }300  }301}302program.parse(process.argv);303type Options = {304  browser: string;305  channel?: string;306  colorScheme?: string;307  device?: string;308  geolocation?: string;309  ignoreHttpsErrors?: boolean;310  lang?: string;311  loadStorage?: string;312  proxyServer?: string;313  proxyBypass?: string;314  saveStorage?: string;315  saveTrace?: string;316  timeout: string;317  timezone?: string;318  viewportSize?: string;319  userAgent?: string;320};321type CaptureOptions = {322  waitForSelector?: string;323  waitForTimeout?: string;324  fullPage: boolean;325};326async function launchContext(options: Options, headless: boolean, executablePath?: string): Promise<{ browser: Browser, browserName: string, launchOptions: LaunchOptions, contextOptions: BrowserContextOptions, context: BrowserContext }> {327  validateOptions(options);328  const browserType = lookupBrowserType(options);329  const launchOptions: LaunchOptions = { headless, executablePath };330  if (options.channel)331    launchOptions.channel = options.channel as any;332  const contextOptions: BrowserContextOptions =333    // Copy the device descriptor since we have to compare and modify the options.334    options.device ? { ...playwright.devices[options.device] } : {};335  // In headful mode, use host device scale factor for things to look nice.336  // In headless, keep things the way it works in Playwright by default.337  // Assume high-dpi on MacOS. TODO: this is not perfect.338  if (!headless)339    contextOptions.deviceScaleFactor = os.platform() === 'darwin' ? 2 : 1;340  // Work around the WebKit GTK scrolling issue.341  if (browserType.name() === 'webkit' && process.platform === 'linux') {342    delete contextOptions.hasTouch;343    delete contextOptions.isMobile;344  }345  if (contextOptions.isMobile && browserType.name() === 'firefox')346    contextOptions.isMobile = undefined;347  // Proxy348  if (options.proxyServer) {349    launchOptions.proxy = {350      server: options.proxyServer351    };352    if (options.proxyBypass)353      launchOptions.proxy.bypass = options.proxyBypass;354  }355  const browser = await browserType.launch(launchOptions);356  // Viewport size357  if (options.viewportSize) {358    try {359      const [ width, height ] = options.viewportSize.split(',').map(n => parseInt(n, 10));360      contextOptions.viewport = { width, height };361    } catch (e) {362      console.log('Invalid window size format: use "width, height", for example --window-size=800,600');363      process.exit(0);364    }365  }366  // Geolocation367  if (options.geolocation) {368    try {369      const [latitude, longitude] = options.geolocation.split(',').map(n => parseFloat(n.trim()));370      contextOptions.geolocation = {371        latitude,372        longitude373      };374    } catch (e) {375      console.log('Invalid geolocation format: user lat, long, for example --geolocation="37.819722,-122.478611"');376      process.exit(0);377    }378    contextOptions.permissions = ['geolocation'];379  }380  // User agent381  if (options.userAgent)382    contextOptions.userAgent = options.userAgent;383  // Lang384  if (options.lang)385    contextOptions.locale = options.lang;386  // Color scheme387  if (options.colorScheme)388    contextOptions.colorScheme = options.colorScheme as 'dark' | 'light';389  // Timezone390  if (options.timezone)391    contextOptions.timezoneId = options.timezone;392  // Storage393  if (options.loadStorage)394    contextOptions.storageState = options.loadStorage;395  if (options.ignoreHttpsErrors)396    contextOptions.ignoreHTTPSErrors = true;397  // Close app when the last window closes.398  const context = await browser.newContext(contextOptions);399  let closingBrowser = false;400  async function closeBrowser() {401    // We can come here multiple times. For example, saving storage creates402    // a temporary page and we call closeBrowser again when that page closes.403    if (closingBrowser)404      return;405    closingBrowser = true;406    if (options.saveTrace)407      await context.tracing.stop({ path: options.saveTrace });408    if (options.saveStorage)409      await context.storageState({ path: options.saveStorage }).catch(e => null);410    await browser.close();411  }412  context.on('page', page => {413    page.on('dialog', () => {});  // Prevent dialogs from being automatically dismissed.414    page.on('close', () => {415      const hasPage = browser.contexts().some(context => context.pages().length > 0);416      if (hasPage)417        return;418      // Avoid the error when the last page is closed because the browser has been closed.419      closeBrowser().catch(e => null);420    });421  });422  if (options.timeout) {423    context.setDefaultTimeout(parseInt(options.timeout, 10));424    context.setDefaultNavigationTimeout(parseInt(options.timeout, 10));425  }426  if (options.saveTrace)427    await context.tracing.start({ screenshots: true, snapshots: true });428  // Omit options that we add automatically for presentation purpose.429  delete launchOptions.headless;430  delete launchOptions.executablePath;431  delete contextOptions.deviceScaleFactor;432  return { browser, browserName: browserType.name(), context, contextOptions, launchOptions };433}434async function openPage(context: BrowserContext, url: string | undefined): Promise<Page> {435  const page = await context.newPage();436  if (url) {437    if (fs.existsSync(url))438      url = 'file://' + path.resolve(url);439    else if (!url.startsWith('http') && !url.startsWith('file://') && !url.startsWith('about:') && !url.startsWith('data:'))440      url = 'http://' + url;441    await page.goto(url);442  }443  return page;444}445async function open(options: Options, url: string | undefined, language: string) {446  const { context, launchOptions, contextOptions } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);447  await context._enableRecorder({448    language,449    launchOptions,450    contextOptions,451    device: options.device,452    saveStorage: options.saveStorage,453  });454  await openPage(context, url);455  if (process.env.PWTEST_CLI_EXIT)456    await Promise.all(context.pages().map(p => p.close()));457}458async function codegen(options: Options, url: string | undefined, language: string, outputFile?: string) {459  const { context, launchOptions, contextOptions } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);460  await context._enableRecorder({461    language,462    launchOptions,463    contextOptions,464    device: options.device,465    saveStorage: options.saveStorage,466    startRecording: true,467    outputFile: outputFile ? path.resolve(outputFile) : undefined468  });469  await openPage(context, url);470  if (process.env.PWTEST_CLI_EXIT)471    await Promise.all(context.pages().map(p => p.close()));472}473async function waitForPage(page: Page, captureOptions: CaptureOptions) {474  if (captureOptions.waitForSelector) {475    console.log(`Waiting for selector ${captureOptions.waitForSelector}...`);476    await page.waitForSelector(captureOptions.waitForSelector);477  }478  if (captureOptions.waitForTimeout) {479    console.log(`Waiting for timeout ${captureOptions.waitForTimeout}...`);480    await page.waitForTimeout(parseInt(captureOptions.waitForTimeout, 10));481  }482}483async function screenshot(options: Options, captureOptions: CaptureOptions, url: string, path: string) {484  const { browser, context } = await launchContext(options, true);485  console.log('Navigating to ' + url);486  const page = await openPage(context, url);487  await waitForPage(page, captureOptions);488  console.log('Capturing screenshot into ' + path);489  await page.screenshot({ path, fullPage: !!captureOptions.fullPage });490  await browser.close();491}492async function pdf(options: Options, captureOptions: CaptureOptions, url: string, path: string) {493  if (options.browser !== 'chromium') {494    console.error('PDF creation is only working with Chromium');495    process.exit(1);496  }497  const { browser, context } = await launchContext({ ...options, browser: 'chromium' }, true);498  console.log('Navigating to ' + url);499  const page = await openPage(context, url);500  await waitForPage(page, captureOptions);501  console.log('Saving as pdf into ' + path);502  await page.pdf!({ path });503  await browser.close();504}505function lookupBrowserType(options: Options): BrowserType {506  let name = options.browser;507  if (options.device) {508    const device = playwright.devices[options.device];509    name = device.defaultBrowserType;510  }511  let browserType: any;512  switch (name) {513    case 'chromium': browserType = playwright.chromium; break;514    case 'webkit': browserType = playwright.webkit; break;515    case 'firefox': browserType = playwright.firefox; break;516    case 'cr': browserType = playwright.chromium; break;517    case 'wk': browserType = playwright.webkit; break;518    case 'ff': browserType = playwright.firefox; break;519  }520  if (browserType)521    return browserType;522  program.help();523  process.exit(1);524}525function validateOptions(options: Options) {526  if (options.device && !(options.device in playwright.devices)) {527    console.log(`Device descriptor not found: '${options.device}', available devices are:`);528    for (const name in playwright.devices)529      console.log(`  "${name}"`);530    process.exit(0);531  }532  if (options.colorScheme && !['light', 'dark'].includes(options.colorScheme)) {533    console.log('Invalid color scheme, should be one of "light", "dark"');534    process.exit(0);535  }536}537function logErrorAndExit(e: Error) {538  console.error(e);539  process.exit(1);540}541function language(): string {542  return process.env.PW_LANG_NAME || 'test';543}544function commandWithOpenOptions(command: string, description: string, options: any[][]): Command {545  let result = program.command(command).description(description);546  for (const option of options)547    result = result.option(option[0], ...option.slice(1));548  return result549      .option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium')550      .option('--channel <channel>', 'Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc')551      .option('--color-scheme <scheme>', 'emulate preferred color scheme, "light" or "dark"')552      .option('--device <deviceName>', 'emulate device, for example  "iPhone 11"')553      .option('--geolocation <coordinates>', 'specify geolocation coordinates, for example "37.819722,-122.478611"')554      .option('--ignore-https-errors', 'ignore https errors')555      .option('--load-storage <filename>', 'load context storage state from the file, previously saved with --save-storage')556      .option('--lang <language>', 'specify language / locale, for example "en-GB"')557      .option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')558      .option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')559      .option('--save-storage <filename>', 'save context storage state at the end, for later use with --load-storage')560      .option('--save-trace <filename>', 'record a trace for the session and save it to a file')561      .option('--timezone <time zone>', 'time zone to emulate, for example "Europe/Rome"')562      .option('--timeout <timeout>', 'timeout for Playwright actions in milliseconds', '10000')563      .option('--user-agent <ua string>', 'specify user agent string')564      .option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"');565}566async function launchGridServer(factoryPathOrPackageName: string, port: number, address: string | undefined, authToken: string | undefined): Promise<void> {567  if (!factoryPathOrPackageName)568    factoryPathOrPackageName = path.join('..', 'grid', 'simpleGridFactory');569  let factory;570  try {571    factory = require(path.resolve(factoryPathOrPackageName));572  } catch (e) {573    factory = require(factoryPathOrPackageName);574  }575  if (factory && typeof factory === 'object' && ('default' in factory))576    factory = factory['default'];577  if (!factory || !factory.launch || typeof factory.launch !== 'function')578    throw new Error('factory does not export `launch` method');579  factory.name = factory.name || factoryPathOrPackageName;580  const gridServer = new GridServer(factory as GridFactory, authToken, address);581  await gridServer.start(port);582  console.log('Grid server is running at ' + gridServer.gridURL());583}584function buildBasePlaywrightCLICommand(cliTargetLang: string | undefined): string {585  switch (cliTargetLang) {586    case 'python':587      return `playwright`;588    case 'java':589      return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="...options.."`;590    case 'csharp':591      return `pwsh bin\\Debug\\netX\\playwright.ps1`;592    default:593      return `npx playwright`;594  }...cli.js
Source:cli.js  
...31function _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); }32function _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; }33function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }34const packageJSON = require('../../package.json');35_commander.program.version('Version ' + (process.env.PW_CLI_DISPLAY_VERSION || packageJSON.version)).name(buildBasePlaywrightCLICommand(process.env.PW_LANG_NAME));36commandWithOpenOptions('open [url]', 'open page in browser specified via -b, --browser', []).action(function (url, options) {37  open(options, url, language()).catch(logErrorAndExit);38}).addHelpText('afterAll', `39Examples:40  $ open  $ open -b webkit https://example.com`);41commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions', [['-o, --output <file name>', 'saves the generated script to a file'], ['--target <language>', `language to generate, one of javascript, test, python, python-async, csharp`, language()]]).action(function (url, options) {42  codegen(options, url, options.target, options.output).catch(logErrorAndExit);43}).addHelpText('afterAll', `44Examples:45  $ codegen46  $ codegen --target=python47  $ codegen -b webkit https://example.com`);48_commander.program.command('debug <app> [args...]', {49  hidden: true50}).description('run command in debug mode: disable timeout, open inspector').allowUnknownOption(true).action(function (app, options) {51  (0, _child_process.spawn)(app, options, {52    env: { ...process.env,53      PWDEBUG: '1'54    },55    stdio: 'inherit'56  });57}).addHelpText('afterAll', `58Examples:59  $ debug node test.js60  $ debug npm run test`);61function suggestedBrowsersToInstall() {62  return _registry.registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');63}64function checkBrowsersToInstall(args) {65  const faultyArguments = [];66  const executables = [];67  for (const arg of args) {68    const executable = _registry.registry.findExecutable(arg);69    if (!executable || executable.installType === 'none') faultyArguments.push(arg);else executables.push(executable);70  }71  if (faultyArguments.length) {72    console.log(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);73    process.exit(1);74  }75  return executables;76}77_commander.program.command('install [browser...]').description('ensure browsers necessary for this version of Playwright are installed').option('--with-deps', 'install system dependencies for browsers').action(async function (args, options) {78  try {79    if (!args.length) {80      const executables = _registry.registry.defaultExecutables();81      if (options.withDeps) await _registry.registry.installDeps(executables, false);82      await _registry.registry.install(executables);83    } else {84      const installDockerImage = args.some(arg => arg === 'docker-image');85      args = args.filter(arg => arg !== 'docker-image');86      if (installDockerImage) {87        const imageName = `mcr.microsoft.com/playwright:v${(0, _utils.getPlaywrightVersion)()}-focal`;88        const {89          code90        } = await (0, _utils.spawnAsync)('docker', ['pull', imageName], {91          stdio: 'inherit'92        });93        if (code !== 0) {94          console.log('Failed to pull docker image');95          process.exit(1);96        }97      }98      const executables = checkBrowsersToInstall(args);99      if (options.withDeps) await _registry.registry.installDeps(executables, false);100      await _registry.registry.install(executables);101    }102  } catch (e) {103    console.log(`Failed to install browsers\n${e}`);104    process.exit(1);105  }106}).addHelpText('afterAll', `107Examples:108  - $ install109    Install default browsers.110  - $ install chrome firefox111    Install custom browsers, supports ${suggestedBrowsersToInstall()}.`);112_commander.program.command('install-deps [browser...]').description('install dependencies necessary to run browsers (will ask for sudo permissions)').option('--dry-run', 'Do not execute installation commands, only print them').action(async function (args, options) {113  try {114    if (!args.length) await _registry.registry.installDeps(_registry.registry.defaultExecutables(), !!options.dryRun);else await _registry.registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun);115  } catch (e) {116    console.log(`Failed to install browser dependencies\n${e}`);117    process.exit(1);118  }119}).addHelpText('afterAll', `120Examples:121  - $ install-deps122    Install dependencies for default browsers.123  - $ install-deps chrome firefox124    Install dependencies for specific browsers, supports ${suggestedBrowsersToInstall()}.`);125const browsers = [{126  alias: 'cr',127  name: 'Chromium',128  type: 'chromium'129}, {130  alias: 'ff',131  name: 'Firefox',132  type: 'firefox'133}, {134  alias: 'wk',135  name: 'WebKit',136  type: 'webkit'137}];138for (const {139  alias,140  name,141  type142} of browsers) {143  commandWithOpenOptions(`${alias} [url]`, `open page in ${name}`, []).action(function (url, options) {144    open({ ...options,145      browser: type146    }, url, options.target).catch(logErrorAndExit);147  }).addHelpText('afterAll', `148Examples:149  $ ${alias} https://example.com`);150}151commandWithOpenOptions('screenshot <url> <filename>', 'capture a page screenshot', [['--wait-for-selector <selector>', 'wait for selector before taking a screenshot'], ['--wait-for-timeout <timeout>', 'wait for timeout in milliseconds before taking a screenshot'], ['--full-page', 'whether to take a full page screenshot (entire scrollable area)']]).action(function (url, filename, command) {152  screenshot(command, command, url, filename).catch(logErrorAndExit);153}).addHelpText('afterAll', `154Examples:155  $ screenshot -b webkit https://example.com example.png`);156commandWithOpenOptions('pdf <url> <filename>', 'save page as pdf', [['--wait-for-selector <selector>', 'wait for given selector before saving as pdf'], ['--wait-for-timeout <timeout>', 'wait for given timeout in milliseconds before saving as pdf']]).action(function (url, filename, options) {157  pdf(options, options, url, filename).catch(logErrorAndExit);158}).addHelpText('afterAll', `159Examples:160  $ pdf https://example.com example.pdf`);161_commander.program.command('experimental-grid-server', {162  hidden: true163}).option('--port <port>', 'grid port; defaults to 3333').option('--agent-factory <factory>', 'path to grid agent factory or npm package').option('--auth-token <authToken>', 'optional authentication token').action(function (options) {164  launchGridServer(options.agentFactory, options.port || 3333, options.authToken);165});166_commander.program.command('experimental-grid-agent', {167  hidden: true168}).requiredOption('--agent-id <agentId>', 'agent ID').requiredOption('--grid-url <gridURL>', 'grid URL').action(function (options) {169  (0, _gridAgent.launchGridAgent)(options.agentId, options.gridUrl);170});171_commander.program.command('run-driver', {172  hidden: true173}).action(function (options) {174  (0, _driver.runDriver)();175});176_commander.program.command('run-server', {177  hidden: true178}).option('--port <port>', 'Server port').option('--path <path>', 'Endpoint Path', '/').option('--max-clients <maxClients>', 'Maximum clients').option('--no-socks-proxy', 'Disable Socks Proxy').action(function (options) {179  (0, _driver.runServer)(options.port ? +options.port : undefined, options.path, options.maxClients ? +options.maxClients : Infinity, options.socksProxy).catch(logErrorAndExit);180});181_commander.program.command('print-api-json', {182  hidden: true183}).action(function (options) {184  (0, _driver.printApiJson)();185});186_commander.program.command('launch-server', {187  hidden: true188}).requiredOption('--browser <browserName>', 'Browser name, one of "chromium", "firefox" or "webkit"').option('--config <path-to-config-file>', 'JSON file with launchServer options').action(function (options) {189  (0, _driver.launchBrowserServer)(options.browser, options.config);190});191_commander.program.command('show-trace [trace...]').option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').description('Show trace viewer').action(function (traces, options) {192  if (options.browser === 'cr') options.browser = 'chromium';193  if (options.browser === 'ff') options.browser = 'firefox';194  if (options.browser === 'wk') options.browser = 'webkit';195  (0, _traceViewer.showTraceViewer)(traces, options.browser, false, 9322).catch(logErrorAndExit);196}).addHelpText('afterAll', `197Examples:198  $ show-trace https://example.com/trace.zip`);199if (!process.env.PW_LANG_NAME) {200  let playwrightTestPackagePath = null;201  try {202    playwrightTestPackagePath = require.resolve('@playwright/test/lib/cli', {203      paths: [__dirname, process.cwd()]204    });205  } catch {}206  if (playwrightTestPackagePath) {207    require(playwrightTestPackagePath).addTestCommand(_commander.program);208    require(playwrightTestPackagePath).addShowReportCommand(_commander.program);209    require(playwrightTestPackagePath).addListFilesCommand(_commander.program);210  } else {211    {212      const command = _commander.program.command('test').allowUnknownOption(true);213      command.description('Run tests with Playwright Test. Available in @playwright/test package.');214      command.action(async () => {215        console.error('Please install @playwright/test package to use Playwright Test.');216        console.error('  npm install -D @playwright/test');217        process.exit(1);218      });219    }220    {221      const command = _commander.program.command('show-report').allowUnknownOption(true);222      command.description('Show Playwright Test HTML report. Available in @playwright/test package.');223      command.action(async () => {224        console.error('Please install @playwright/test package to use Playwright Test.');225        console.error('  npm install -D @playwright/test');226        process.exit(1);227      });228    }229  }230}231_commander.program.parse(process.argv);232async function launchContext(options, headless, executablePath) {233  validateOptions(options);234  const browserType = lookupBrowserType(options);235  const launchOptions = {236    headless,237    executablePath238  };239  if (options.channel) launchOptions.channel = options.channel;240  const contextOptions = // Copy the device descriptor since we have to compare and modify the options.241  options.device ? { ...playwright.devices[options.device]242  } : {}; // In headful mode, use host device scale factor for things to look nice.243  // In headless, keep things the way it works in Playwright by default.244  // Assume high-dpi on MacOS. TODO: this is not perfect.245  if (!headless) contextOptions.deviceScaleFactor = _os.default.platform() === 'darwin' ? 2 : 1; // Work around the WebKit GTK scrolling issue.246  if (browserType.name() === 'webkit' && process.platform === 'linux') {247    delete contextOptions.hasTouch;248    delete contextOptions.isMobile;249  }250  if (contextOptions.isMobile && browserType.name() === 'firefox') contextOptions.isMobile = undefined; // Proxy251  if (options.proxyServer) {252    launchOptions.proxy = {253      server: options.proxyServer254    };255    if (options.proxyBypass) launchOptions.proxy.bypass = options.proxyBypass;256  }257  const browser = await browserType.launch(launchOptions); // Viewport size258  if (options.viewportSize) {259    try {260      const [width, height] = options.viewportSize.split(',').map(n => parseInt(n, 10));261      contextOptions.viewport = {262        width,263        height264      };265    } catch (e) {266      console.log('Invalid window size format: use "width, height", for example --window-size=800,600');267      process.exit(0);268    }269  } // Geolocation270  if (options.geolocation) {271    try {272      const [latitude, longitude] = options.geolocation.split(',').map(n => parseFloat(n.trim()));273      contextOptions.geolocation = {274        latitude,275        longitude276      };277    } catch (e) {278      console.log('Invalid geolocation format: user lat, long, for example --geolocation="37.819722,-122.478611"');279      process.exit(0);280    }281    contextOptions.permissions = ['geolocation'];282  } // User agent283  if (options.userAgent) contextOptions.userAgent = options.userAgent; // Lang284  if (options.lang) contextOptions.locale = options.lang; // Color scheme285  if (options.colorScheme) contextOptions.colorScheme = options.colorScheme; // Timezone286  if (options.timezone) contextOptions.timezoneId = options.timezone; // Storage287  if (options.loadStorage) contextOptions.storageState = options.loadStorage;288  if (options.ignoreHttpsErrors) contextOptions.ignoreHTTPSErrors = true; // Close app when the last window closes.289  const context = await browser.newContext(contextOptions);290  let closingBrowser = false;291  async function closeBrowser() {292    // We can come here multiple times. For example, saving storage creates293    // a temporary page and we call closeBrowser again when that page closes.294    if (closingBrowser) return;295    closingBrowser = true;296    if (options.saveTrace) await context.tracing.stop({297      path: options.saveTrace298    });299    if (options.saveStorage) await context.storageState({300      path: options.saveStorage301    }).catch(e => null);302    await browser.close();303  }304  context.on('page', page => {305    page.on('dialog', () => {}); // Prevent dialogs from being automatically dismissed.306    page.on('close', () => {307      const hasPage = browser.contexts().some(context => context.pages().length > 0);308      if (hasPage) return; // Avoid the error when the last page is closed because the browser has been closed.309      closeBrowser().catch(e => null);310    });311  });312  if (options.timeout) {313    context.setDefaultTimeout(parseInt(options.timeout, 10));314    context.setDefaultNavigationTimeout(parseInt(options.timeout, 10));315  }316  if (options.saveTrace) await context.tracing.start({317    screenshots: true,318    snapshots: true319  }); // Omit options that we add automatically for presentation purpose.320  delete launchOptions.headless;321  delete launchOptions.executablePath;322  delete contextOptions.deviceScaleFactor;323  return {324    browser,325    browserName: browserType.name(),326    context,327    contextOptions,328    launchOptions329  };330}331async function openPage(context, url) {332  const page = await context.newPage();333  if (url) {334    if (_fs.default.existsSync(url)) url = 'file://' + _path.default.resolve(url);else if (!url.startsWith('http') && !url.startsWith('file://') && !url.startsWith('about:') && !url.startsWith('data:')) url = 'http://' + url;335    await page.goto(url);336  }337  return page;338}339async function open(options, url, language) {340  const {341    context,342    launchOptions,343    contextOptions344  } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);345  await context._enableRecorder({346    language,347    launchOptions,348    contextOptions,349    device: options.device,350    saveStorage: options.saveStorage351  });352  await openPage(context, url);353  if (process.env.PWTEST_CLI_EXIT) await Promise.all(context.pages().map(p => p.close()));354}355async function codegen(options, url, language, outputFile) {356  const {357    context,358    launchOptions,359    contextOptions360  } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);361  await context._enableRecorder({362    language,363    launchOptions,364    contextOptions,365    device: options.device,366    saveStorage: options.saveStorage,367    startRecording: true,368    outputFile: outputFile ? _path.default.resolve(outputFile) : undefined369  });370  await openPage(context, url);371  if (process.env.PWTEST_CLI_EXIT) await Promise.all(context.pages().map(p => p.close()));372}373async function waitForPage(page, captureOptions) {374  if (captureOptions.waitForSelector) {375    console.log(`Waiting for selector ${captureOptions.waitForSelector}...`);376    await page.waitForSelector(captureOptions.waitForSelector);377  }378  if (captureOptions.waitForTimeout) {379    console.log(`Waiting for timeout ${captureOptions.waitForTimeout}...`);380    await page.waitForTimeout(parseInt(captureOptions.waitForTimeout, 10));381  }382}383async function screenshot(options, captureOptions, url, path) {384  const {385    browser,386    context387  } = await launchContext(options, true);388  console.log('Navigating to ' + url);389  const page = await openPage(context, url);390  await waitForPage(page, captureOptions);391  console.log('Capturing screenshot into ' + path);392  await page.screenshot({393    path,394    fullPage: !!captureOptions.fullPage395  });396  await browser.close();397}398async function pdf(options, captureOptions, url, path) {399  if (options.browser !== 'chromium') {400    console.error('PDF creation is only working with Chromium');401    process.exit(1);402  }403  const {404    browser,405    context406  } = await launchContext({ ...options,407    browser: 'chromium'408  }, true);409  console.log('Navigating to ' + url);410  const page = await openPage(context, url);411  await waitForPage(page, captureOptions);412  console.log('Saving as pdf into ' + path);413  await page.pdf({414    path415  });416  await browser.close();417}418function lookupBrowserType(options) {419  let name = options.browser;420  if (options.device) {421    const device = playwright.devices[options.device];422    name = device.defaultBrowserType;423  }424  let browserType;425  switch (name) {426    case 'chromium':427      browserType = playwright.chromium;428      break;429    case 'webkit':430      browserType = playwright.webkit;431      break;432    case 'firefox':433      browserType = playwright.firefox;434      break;435    case 'cr':436      browserType = playwright.chromium;437      break;438    case 'wk':439      browserType = playwright.webkit;440      break;441    case 'ff':442      browserType = playwright.firefox;443      break;444  }445  if (browserType) return browserType;446  _commander.program.help();447}448function validateOptions(options) {449  if (options.device && !(options.device in playwright.devices)) {450    console.log(`Device descriptor not found: '${options.device}', available devices are:`);451    for (const name in playwright.devices) console.log(`  "${name}"`);452    process.exit(0);453  }454  if (options.colorScheme && !['light', 'dark'].includes(options.colorScheme)) {455    console.log('Invalid color scheme, should be one of "light", "dark"');456    process.exit(0);457  }458}459function logErrorAndExit(e) {460  console.error(e);461  process.exit(1);462}463function language() {464  return process.env.PW_LANG_NAME || 'test';465}466function commandWithOpenOptions(command, description, options) {467  let result = _commander.program.command(command).description(description);468  for (const option of options) result = result.option(option[0], ...option.slice(1));469  return result.option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').option('--channel <channel>', 'Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc').option('--color-scheme <scheme>', 'emulate preferred color scheme, "light" or "dark"').option('--device <deviceName>', 'emulate device, for example  "iPhone 11"').option('--geolocation <coordinates>', 'specify geolocation coordinates, for example "37.819722,-122.478611"').option('--ignore-https-errors', 'ignore https errors').option('--load-storage <filename>', 'load context storage state from the file, previously saved with --save-storage').option('--lang <language>', 'specify language / locale, for example "en-GB"').option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"').option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"').option('--save-storage <filename>', 'save context storage state at the end, for later use with --load-storage').option('--save-trace <filename>', 'record a trace for the session and save it to a file').option('--timezone <time zone>', 'time zone to emulate, for example "Europe/Rome"').option('--timeout <timeout>', 'timeout for Playwright actions in milliseconds', '10000').option('--user-agent <ua string>', 'specify user agent string').option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"');470}471async function launchGridServer(factoryPathOrPackageName, port, authToken) {472  if (!factoryPathOrPackageName) factoryPathOrPackageName = _path.default.join('..', 'grid', 'simpleGridFactory');473  let factory;474  try {475    factory = require(_path.default.resolve(factoryPathOrPackageName));476  } catch (e) {477    factory = require(factoryPathOrPackageName);478  }479  if (factory && typeof factory === 'object' && 'default' in factory) factory = factory['default'];480  if (!factory || !factory.launch || typeof factory.launch !== 'function') throw new Error('factory does not export `launch` method');481  factory.name = factory.name || factoryPathOrPackageName;482  const gridServer = new _gridServer.GridServer(factory, authToken);483  await gridServer.start(port);484  console.log('Grid server is running at ' + gridServer.urlPrefix());485}486function buildBasePlaywrightCLICommand(cliTargetLang) {487  switch (cliTargetLang) {488    case 'python':489      return `playwright`;490    case 'java':491      return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="...options.."`;492    case 'csharp':493      return `pwsh bin\\Debug\\netX\\playwright.ps1`;494    default:495      return `npx playwright`;496  }...innerCli.js
Source:innerCli.js  
...30 * limitations under the License.31 */32/* eslint-disable no-console */33const packageJSON = require('../../package.json');34_commander.program.version('Version ' + (process.env.PW_CLI_DISPLAY_VERSION || packageJSON.version)).name(buildBasePlaywrightCLICommand(process.env.PW_CLI_TARGET_LANG));35commandWithOpenOptions('open [url]', 'open page in browser specified via -b, --browser', []).action(function (url, options) {36  open(options, url, language()).catch(logErrorAndExit);37}).addHelpText('afterAll', `38Examples:39  $ open  $ open -b webkit https://example.com`);40commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions', [['-o, --output <file name>', 'saves the generated script to a file'], ['--target <language>', `language to generate, one of javascript, test, python, python-async, csharp`, language()]]).action(function (url, options) {41  codegen(options, url, options.target, options.output).catch(logErrorAndExit);42}).addHelpText('afterAll', `43Examples:44  $ codegen45  $ codegen --target=python46  $ codegen -b webkit https://example.com`);47_commander.program.command('debug <app> [args...]', {48  hidden: true49}).description('run command in debug mode: disable timeout, open inspector').allowUnknownOption(true).action(function (app, options) {50  (0, _child_process.spawn)(app, options, {51    env: { ...process.env,52      PWDEBUG: '1'53    },54    stdio: 'inherit'55  });56}).addHelpText('afterAll', `57Examples:58  $ debug node test.js59  $ debug npm run test`);60function suggestedBrowsersToInstall() {61  return _registry.registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');62}63function checkBrowsersToInstall(args) {64  const faultyArguments = [];65  const executables = [];66  for (const arg of args) {67    const executable = _registry.registry.findExecutable(arg);68    if (!executable || executable.installType === 'none') faultyArguments.push(arg);else executables.push(executable);69  }70  if (faultyArguments.length) {71    console.log(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);72    process.exit(1);73  }74  return executables;75}76_commander.program.command('install [browser...]').description('ensure browsers necessary for this version of Playwright are installed').option('--with-deps', 'install system dependencies for browsers').action(async function (args, options) {77  try {78    if (!args.length) {79      const executables = _registry.registry.defaultExecutables();80      if (options.withDeps) await _registry.registry.installDeps(executables, false);81      await _registry.registry.install(executables);82    } else {83      const installDockerImage = args.some(arg => arg === 'docker-image');84      args = args.filter(arg => arg !== 'docker-image');85      if (installDockerImage) {86        const imageName = `mcr.microsoft.com/playwright:v${(0, _utils.getPlaywrightVersion)()}-focal`;87        const {88          code89        } = await (0, _utils.spawnAsync)('docker', ['pull', imageName], {90          stdio: 'inherit'91        });92        if (code !== 0) {93          console.log('Failed to pull docker image');94          process.exit(1);95        }96      }97      const executables = checkBrowsersToInstall(args);98      if (options.withDeps) await _registry.registry.installDeps(executables, false);99      await _registry.registry.install(executables);100    }101  } catch (e) {102    console.log(`Failed to install browsers\n${e}`);103    process.exit(1);104  }105}).addHelpText('afterAll', `106Examples:107  - $ install108    Install default browsers.109  - $ install chrome firefox110    Install custom browsers, supports ${suggestedBrowsersToInstall()}.`);111_commander.program.command('install-deps [browser...]').description('install dependencies necessary to run browsers (will ask for sudo permissions)').option('--dry-run', 'Do not execute installation commands, only print them').action(async function (args, options) {112  try {113    if (!args.length) await _registry.registry.installDeps(_registry.registry.defaultExecutables(), !!options.dryRun);else await _registry.registry.installDeps(checkBrowsersToInstall(args), !!options.dryRun);114  } catch (e) {115    console.log(`Failed to install browser dependencies\n${e}`);116    process.exit(1);117  }118}).addHelpText('afterAll', `119Examples:120  - $ install-deps121    Install dependencies for default browsers.122  - $ install-deps chrome firefox123    Install dependencies for specific browsers, supports ${suggestedBrowsersToInstall()}.`);124const browsers = [{125  alias: 'cr',126  name: 'Chromium',127  type: 'chromium'128}, {129  alias: 'ff',130  name: 'Firefox',131  type: 'firefox'132}, {133  alias: 'wk',134  name: 'WebKit',135  type: 'webkit'136}];137for (const {138  alias,139  name,140  type141} of browsers) {142  commandWithOpenOptions(`${alias} [url]`, `open page in ${name}`, []).action(function (url, options) {143    open({ ...options,144      browser: type145    }, url, options.target).catch(logErrorAndExit);146  }).addHelpText('afterAll', `147Examples:148  $ ${alias} https://example.com`);149}150commandWithOpenOptions('screenshot <url> <filename>', 'capture a page screenshot', [['--wait-for-selector <selector>', 'wait for selector before taking a screenshot'], ['--wait-for-timeout <timeout>', 'wait for timeout in milliseconds before taking a screenshot'], ['--full-page', 'whether to take a full page screenshot (entire scrollable area)']]).action(function (url, filename, command) {151  screenshot(command, command, url, filename).catch(logErrorAndExit);152}).addHelpText('afterAll', `153Examples:154  $ screenshot -b webkit https://example.com example.png`);155commandWithOpenOptions('pdf <url> <filename>', 'save page as pdf', [['--wait-for-selector <selector>', 'wait for given selector before saving as pdf'], ['--wait-for-timeout <timeout>', 'wait for given timeout in milliseconds before saving as pdf']]).action(function (url, filename, options) {156  pdf(options, options, url, filename).catch(logErrorAndExit);157}).addHelpText('afterAll', `158Examples:159  $ pdf https://example.com example.pdf`);160_commander.program.command('experimental-grid-server', {161  hidden: true162}).option('--port <port>', 'grid port; defaults to 3333').option('--agent-factory <factory>', 'path to grid agent factory or npm package').option('--auth-token <authToken>', 'optional authentication token').action(function (options) {163  launchGridServer(options.agentFactory, options.port || 3333, options.authToken);164});165_commander.program.command('experimental-grid-agent', {166  hidden: true167}).requiredOption('--agent-id <agentId>', 'agent ID').requiredOption('--grid-url <gridURL>', 'grid URL').action(function (options) {168  (0, _gridAgent.launchGridAgent)(options.agentId, options.gridUrl);169});170_commander.program.command('show-trace [trace]').option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').description('Show trace viewer').action(function (trace, options) {171  if (options.browser === 'cr') options.browser = 'chromium';172  if (options.browser === 'ff') options.browser = 'firefox';173  if (options.browser === 'wk') options.browser = 'webkit';174  (0, _traceViewer.showTraceViewer)(trace, options.browser, false, 9322).catch(logErrorAndExit);175}).addHelpText('afterAll', `176Examples:177  $ show-trace https://example.com/trace.zip`);178if (!process.env.PW_CLI_TARGET_LANG) {179  let playwrightTestPackagePath = null;180  try {181    playwrightTestPackagePath = require.resolve('@playwright/test/lib/cli', {182      paths: [__dirname, process.cwd()]183    });184  } catch {}185  if (playwrightTestPackagePath) {186    require(playwrightTestPackagePath).addTestCommand(_commander.program);187    require(playwrightTestPackagePath).addShowReportCommand(_commander.program);188  } else {189    {190      const command = _commander.program.command('test').allowUnknownOption(true);191      command.description('Run tests with Playwright Test. Available in @playwright/test package.');192      command.action(async () => {193        console.error('Please install @playwright/test package to use Playwright Test.');194        console.error('  npm install -D @playwright/test');195        process.exit(1);196      });197    }198    {199      const command = _commander.program.command('show-report').allowUnknownOption(true);200      command.description('Show Playwright Test HTML report. Available in @playwright/test package.');201      command.action(async () => {202        console.error('Please install @playwright/test package to use Playwright Test.');203        console.error('  npm install -D @playwright/test');204        process.exit(1);205      });206    }207  }208}209if (process.argv[2] === 'run-driver') (0, _driver.runDriver)();else if (process.argv[2] === 'run-server') (0, _driver.runServer)(process.argv[3] ? +process.argv[3] : undefined).catch(logErrorAndExit);else if (process.argv[2] === 'print-api-json') (0, _driver.printApiJson)();else if (process.argv[2] === 'launch-server') (0, _driver.launchBrowserServer)(process.argv[3], process.argv[4]).catch(logErrorAndExit);else _commander.program.parse(process.argv);210async function launchContext(options, headless, executablePath) {211  validateOptions(options);212  const browserType = lookupBrowserType(options);213  const launchOptions = {214    headless,215    executablePath216  };217  if (options.channel) launchOptions.channel = options.channel;218  const contextOptions = // Copy the device descriptor since we have to compare and modify the options.219  options.device ? { ...playwright.devices[options.device]220  } : {}; // In headful mode, use host device scale factor for things to look nice.221  // In headless, keep things the way it works in Playwright by default.222  // Assume high-dpi on MacOS. TODO: this is not perfect.223  if (!headless) contextOptions.deviceScaleFactor = _os.default.platform() === 'darwin' ? 2 : 1; // Work around the WebKit GTK scrolling issue.224  if (browserType.name() === 'webkit' && process.platform === 'linux') {225    delete contextOptions.hasTouch;226    delete contextOptions.isMobile;227  }228  if (contextOptions.isMobile && browserType.name() === 'firefox') contextOptions.isMobile = undefined; // Proxy229  if (options.proxyServer) {230    launchOptions.proxy = {231      server: options.proxyServer232    };233    if (options.proxyBypass) launchOptions.proxy.bypass = options.proxyBypass;234  }235  const browser = await browserType.launch(launchOptions); // Viewport size236  if (options.viewportSize) {237    try {238      const [width, height] = options.viewportSize.split(',').map(n => parseInt(n, 10));239      contextOptions.viewport = {240        width,241        height242      };243    } catch (e) {244      console.log('Invalid window size format: use "width, height", for example --window-size=800,600');245      process.exit(0);246    }247  } // Geolocation248  if (options.geolocation) {249    try {250      const [latitude, longitude] = options.geolocation.split(',').map(n => parseFloat(n.trim()));251      contextOptions.geolocation = {252        latitude,253        longitude254      };255    } catch (e) {256      console.log('Invalid geolocation format: user lat, long, for example --geolocation="37.819722,-122.478611"');257      process.exit(0);258    }259    contextOptions.permissions = ['geolocation'];260  } // User agent261  if (options.userAgent) contextOptions.userAgent = options.userAgent; // Lang262  if (options.lang) contextOptions.locale = options.lang; // Color scheme263  if (options.colorScheme) contextOptions.colorScheme = options.colorScheme; // Timezone264  if (options.timezone) contextOptions.timezoneId = options.timezone; // Storage265  if (options.loadStorage) contextOptions.storageState = options.loadStorage;266  if (options.ignoreHttpsErrors) contextOptions.ignoreHTTPSErrors = true; // Close app when the last window closes.267  const context = await browser.newContext(contextOptions);268  let closingBrowser = false;269  async function closeBrowser() {270    // We can come here multiple times. For example, saving storage creates271    // a temporary page and we call closeBrowser again when that page closes.272    if (closingBrowser) return;273    closingBrowser = true;274    if (options.saveTrace) await context.tracing.stop({275      path: options.saveTrace276    });277    if (options.saveStorage) await context.storageState({278      path: options.saveStorage279    }).catch(e => null);280    await browser.close();281  }282  context.on('page', page => {283    page.on('dialog', () => {}); // Prevent dialogs from being automatically dismissed.284    page.on('close', () => {285      const hasPage = browser.contexts().some(context => context.pages().length > 0);286      if (hasPage) return; // Avoid the error when the last page is closed because the browser has been closed.287      closeBrowser().catch(e => null);288    });289  });290  if (options.timeout) {291    context.setDefaultTimeout(parseInt(options.timeout, 10));292    context.setDefaultNavigationTimeout(parseInt(options.timeout, 10));293  }294  if (options.saveTrace) await context.tracing.start({295    screenshots: true,296    snapshots: true297  }); // Omit options that we add automatically for presentation purpose.298  delete launchOptions.headless;299  delete launchOptions.executablePath;300  delete contextOptions.deviceScaleFactor;301  return {302    browser,303    browserName: browserType.name(),304    context,305    contextOptions,306    launchOptions307  };308}309async function openPage(context, url) {310  const page = await context.newPage();311  if (url) {312    if (_fs.default.existsSync(url)) url = 'file://' + _path.default.resolve(url);else if (!url.startsWith('http') && !url.startsWith('file://') && !url.startsWith('about:') && !url.startsWith('data:')) url = 'http://' + url;313    await page.goto(url);314  }315  return page;316}317async function open(options, url, language) {318  const {319    context,320    launchOptions,321    contextOptions322  } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);323  await context._enableRecorder({324    language,325    launchOptions,326    contextOptions,327    device: options.device,328    saveStorage: options.saveStorage329  });330  await openPage(context, url);331  if (process.env.PWTEST_CLI_EXIT) await Promise.all(context.pages().map(p => p.close()));332}333async function codegen(options, url, language, outputFile) {334  const {335    context,336    launchOptions,337    contextOptions338  } = await launchContext(options, !!process.env.PWTEST_CLI_HEADLESS, process.env.PWTEST_CLI_EXECUTABLE_PATH);339  await context._enableRecorder({340    language,341    launchOptions,342    contextOptions,343    device: options.device,344    saveStorage: options.saveStorage,345    startRecording: true,346    outputFile: outputFile ? _path.default.resolve(outputFile) : undefined347  });348  await openPage(context, url);349  if (process.env.PWTEST_CLI_EXIT) await Promise.all(context.pages().map(p => p.close()));350}351async function waitForPage(page, captureOptions) {352  if (captureOptions.waitForSelector) {353    console.log(`Waiting for selector ${captureOptions.waitForSelector}...`);354    await page.waitForSelector(captureOptions.waitForSelector);355  }356  if (captureOptions.waitForTimeout) {357    console.log(`Waiting for timeout ${captureOptions.waitForTimeout}...`);358    await page.waitForTimeout(parseInt(captureOptions.waitForTimeout, 10));359  }360}361async function screenshot(options, captureOptions, url, path) {362  const {363    browser,364    context365  } = await launchContext(options, true);366  console.log('Navigating to ' + url);367  const page = await openPage(context, url);368  await waitForPage(page, captureOptions);369  console.log('Capturing screenshot into ' + path);370  await page.screenshot({371    path,372    fullPage: !!captureOptions.fullPage373  });374  await browser.close();375}376async function pdf(options, captureOptions, url, path) {377  if (options.browser !== 'chromium') {378    console.error('PDF creation is only working with Chromium');379    process.exit(1);380  }381  const {382    browser,383    context384  } = await launchContext({ ...options,385    browser: 'chromium'386  }, true);387  console.log('Navigating to ' + url);388  const page = await openPage(context, url);389  await waitForPage(page, captureOptions);390  console.log('Saving as pdf into ' + path);391  await page.pdf({392    path393  });394  await browser.close();395}396function lookupBrowserType(options) {397  let name = options.browser;398  if (options.device) {399    const device = playwright.devices[options.device];400    name = device.defaultBrowserType;401  }402  let browserType;403  switch (name) {404    case 'chromium':405      browserType = playwright.chromium;406      break;407    case 'webkit':408      browserType = playwright.webkit;409      break;410    case 'firefox':411      browserType = playwright.firefox;412      break;413    case 'cr':414      browserType = playwright.chromium;415      break;416    case 'wk':417      browserType = playwright.webkit;418      break;419    case 'ff':420      browserType = playwright.firefox;421      break;422  }423  if (browserType) return browserType;424  _commander.program.help();425}426function validateOptions(options) {427  if (options.device && !(options.device in playwright.devices)) {428    console.log(`Device descriptor not found: '${options.device}', available devices are:`);429    for (const name in playwright.devices) console.log(`  "${name}"`);430    process.exit(0);431  }432  if (options.colorScheme && !['light', 'dark'].includes(options.colorScheme)) {433    console.log('Invalid color scheme, should be one of "light", "dark"');434    process.exit(0);435  }436}437function logErrorAndExit(e) {438  console.error(e);439  process.exit(1);440}441function language() {442  return process.env.PW_CLI_TARGET_LANG || 'test';443}444function commandWithOpenOptions(command, description, options) {445  let result = _commander.program.command(command).description(description);446  for (const option of options) result = result.option(option[0], ...option.slice(1));447  return result.option('-b, --browser <browserType>', 'browser to use, one of cr, chromium, ff, firefox, wk, webkit', 'chromium').option('--channel <channel>', 'Chromium distribution channel, "chrome", "chrome-beta", "msedge-dev", etc').option('--color-scheme <scheme>', 'emulate preferred color scheme, "light" or "dark"').option('--device <deviceName>', 'emulate device, for example  "iPhone 11"').option('--geolocation <coordinates>', 'specify geolocation coordinates, for example "37.819722,-122.478611"').option('--ignore-https-errors', 'ignore https errors').option('--load-storage <filename>', 'load context storage state from the file, previously saved with --save-storage').option('--lang <language>', 'specify language / locale, for example "en-GB"').option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"').option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"').option('--save-storage <filename>', 'save context storage state at the end, for later use with --load-storage').option('--save-trace <filename>', 'record a trace for the session and save it to a file').option('--timezone <time zone>', 'time zone to emulate, for example "Europe/Rome"').option('--timeout <timeout>', 'timeout for Playwright actions in milliseconds', '10000').option('--user-agent <ua string>', 'specify user agent string').option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"');448}449async function launchGridServer(factoryPathOrPackageName, port, authToken) {450  if (!factoryPathOrPackageName) factoryPathOrPackageName = _path.default.join('..', 'grid', 'simpleGridFactory');451  let factory;452  try {453    factory = require(_path.default.resolve(factoryPathOrPackageName));454  } catch (e) {455    factory = require(factoryPathOrPackageName);456  }457  if (factory && typeof factory === 'object' && 'default' in factory) factory = factory['default'];458  if (!factory || !factory.launch || typeof factory.launch !== 'function') throw new Error('factory does not export `launch` method');459  factory.name = factory.name || factoryPathOrPackageName;460  const gridServer = new _gridServer.GridServer(factory, authToken);461  await gridServer.start(port);462  console.log('Grid server is running at ' + gridServer.urlPrefix());463}464function buildBasePlaywrightCLICommand(cliTargetLang) {465  switch (cliTargetLang) {466    case 'python':467      return `playwright`;468    case 'java':469      return `mvn exec:java -e -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="...options.."`;470    case 'csharp':471      return `playwright`;472    default:473      return `npx playwright`;474  }...Using AI Code Generation
1const playwright = require('playwright');2const browserType = 'chromium';3const browser = await playwright[browserType].launch();4const context = await browser.newContext();5const page = await context.newPage();6await page.screenshot({ path: 'example.png' });7await browser.close();8const { buildBasePlaywrightCLICommand } = require('playwright-core/lib/utils/registry');9const baseCommand = buildBasePlaywrightCLICommand();10module.exports = {11    {12      use: {13      },14    },15};16{17  "scripts": {18  },19  "devDependencies": {20  }21}Using AI Code Generation
1const { buildBasePlaywrightCLICommand } = require('playwright/lib/utils/utils');2const { BrowserType } = require('playwright/lib/server/browserType');3const { BrowserServer } = require('playwright/lib/server/browserServer');4const { Browser } = require('playwright/lib/server/browser');5const { Page } = require('playwright/lib/server/page');6const { BrowserContext } = require('playwright/lib/server/browserContext');7const { ElectronApplication } = require('playwright/lib/server/electron');8const { WebKitBrowser } = require('playwright/lib/server/webkit');9const { WebKitBrowserContext } = require('playwright/lib/server/webkit');10const { WebKitPage } = require('playwright/lib/server/webkit');11const { WebKit } = require('playwright/lib/server/webkit');12const { Android } = require('playwright/lib/server/android');13const { AndroidBrowser } = require('playwright/lib/server/android');14const { AndroidBrowserContext } = require('playwright/lib/server/android');15const { AndroidPage } = require('playwright/lib/server/android');16const { AndroidDevice } = require('playwright/lib/server/android');17const { AndroidDeviceManager } = require('playwright/lib/server/android');18const { BrowserContextDispatcher } = require('playwright/lib/server/browserContextDispatcher');19const { BrowserDispatcher } = require('playwright/lib/server/browserDispatcher');20const { BrowserServerDispatcher } = require('playwright/lib/server/browserServerDispatcher');21const { ElectronApplicationDispatcher } = require('playwright/lib/server/electronDispatcher');22const { PageDispatcher } = require('playwright/lib/server/pageDispatcher');23const { AndroidBrowserContextDispatcher } = require('playwright/lib/server/androidDispatcher');24const { AndroidBrowserDispatcher } = require('playwright/lib/server/androidDispatcher');25const { AndroidDeviceDispatcher } = require('playwright/lib/server/androidDispatcher');26const { AndroidPageDispatcher } = require('playwright/lib/server/androidDispatcher');27const { AndroidDispatcher } = require('playwright/lib/server/androidDispatcher');28const { WebKitBrowserContextDispatcher } = require('playwright/lib/server/webkitDispatcher');29const { WebKitBrowserDispatcher } = require('playwright/lib/server/webkitDispatcher');30const { WebKitPageDispatcher } = require('playwright/lib/server/webkitDispatcher');31const { WebKitDispatcher } = require('playwright/lib/server/webkitDispatcher');32const { AndroidDeviceManagerDispatcher } = require('playwrightUsing AI Code Generation
1const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/test');2const { expect } = require('@playwright/test');3const { test } = require('@playwright/test');4const { devices } = require('@playwright/test');5const { chromium } = require('playwright');6const { webkit } = require('playwright');7const { firefox } = require('playwright');8const { devices } = require('playwright');9const { expect } = require('playwright');10const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/test');11const { test } = require('@playwright/test');12const { chromium } = require('playwright');13const { firefox } = require('playwright');14const { webkit } = require('playwright');15const { devices } = require('playwright');16const { expect } = require('playwright');17const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/test');18const { test } = require('@playwright/test');19const { chromium } = require('playwright');20const { firefox } = require('playwright');21const { webkit } = require('playwright');22const { devices } = require('playwright');23const { expect } = require('playwright');24const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/test');25const { test } = require('@playwright/test');26const { chromium } = require('playwright');27const { firefox } = require('playwright');28const { webkit } = require('playwright');29const { devices } = require('playwright');30const { expect } = require('playwright');31const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/test');32const { test } = require('@playwright/test');33const { chromium } = require('playwright');34const { firefox } = require('playwright');35const { webkit } = require('playwright');36const { devices } = require('playwright');37const { expect } = require('playwright');Using AI Code Generation
1const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');2const { createTestType } = require('@playwright/test/lib/types');3const { PlaywrightTestConfig } = require('@playwright/test/lib/config');4const { PlaywrightTest } = require('@playwright/test/lib/test');5const testType = createTestType('testType');6const config = new PlaywrightTestConfig();7const test = new PlaywrightTest(config, testType);8const basePlaywrightCLICommand = buildBasePlaywrightCLICommand(test);9console.log(basePlaywrightCLICommand);10const { spawnSync } = require('child_process');11spawnSync(basePlaywrightCLICommand, ['test.js'], { stdio: 'inherit' });12testType.use({ workers: 2 });13spawnSync(basePlaywrightCLICommand, ['test.js'], { stdio: 'inherit' });Using AI Code Generation
1const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/cli/cli');2const { spawn } = require('child_process');3const { join } = require('path');4const pathToPlaywrightConfig = join(__dirname, 'playwright.config.js');5const pathToPlaywrightTest = join(__dirname, 'playwright.config.js');6const pathToTestFile = join(__dirname, 'test.spec.js');7const command = buildBasePlaywrightCLICommand(pathToPlaywrightConfig, pathToPlaywrightTest, pathToTestFile);8const child = spawn(command, { shell: true });9child.stdout.on('data', (data) => {10  console.log(`stdout: ${data}`);11});12child.stderr.on('data', (data) => {13  console.error(`stderr: ${data}`);14});15child.on('close', (code) => {16  console.log(`child process exited with code ${code}`);17});18child.on('error', (err) => {19  console.log(`child process errored with code ${err}`);20});21module.exports = {22    {23      use: {24        viewport: { width: 1280, height: 720 },25      },26    },27};28const { test, expect } = require('@playwright/test');29test('basic test', async ({ page }) => {30  const title = page.locator('text=Playwright');31  await expect(title).toBeVisible();32});Using AI Code Generation
1const { buildBasePlaywrightCLICommand } = require("playwright/lib/cli/cli");2const { createRequire } = require('module');3const require = createRequire(import.meta.url);4const playwright = require('playwright');5const playwrightConfig = require('./playwright.config.js');6const testConfig = require('./test.config.js');7const run = async () => {8    const { browsers, devices, launchOptions } = playwrightConfig;9    const { testName, testPath } = testConfig;10    const cliCommand = buildBasePlaywrightCLICommand({11    });12    const browser = await playwright.chromium.launch();13    const context = await browser.newContext();14    const page = await context.newPage();15    await page.screenshot({ path: 'example.png' });16    await browser.close();17};18run();19module.exports = {20    launchOptions: {21    }22};23module.exports = {24};Using AI Code Generation
1const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');2const cliCommand = buildBasePlaywrightCLICommand();3console.log(cliCommand);4const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');5const cliCommand = buildBasePlaywrightCLICommand();6console.log(cliCommand);7const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');8const cliCommand = buildBasePlaywrightCLICommand();9console.log(cliCommand);10const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');11const cliCommand = buildBasePlaywrightCLICommand();12console.log(cliCommand);13const { buildBasePlaywrightCLICommand } = require('@playwright/test/lib/utils/cli');14const cliCommand = buildBasePlaywrightCLICommand();15console.log(cliCommand);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!!
