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('playwright
Using 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!!