2025-03-21 10:58:58 -07:00
/ * *
* Copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
import { program } from 'commander' ;
2025-04-30 23:06:56 +02:00
import { startHttpTransport , startStdioTransport } from './transport.js' ;
2025-05-14 16:01:08 -07:00
import { resolveCLIConfig } from './config.js' ;
2025-05-14 20:15:09 -07:00
// @ts-ignore
import { startTraceViewerServer } from 'playwright-core/lib/server' ;
2025-04-28 15:04:59 -07:00
2025-05-06 14:27:28 -07:00
import type { Connection } from './connection.js' ;
2025-05-07 11:30:01 +02:00
import { packageJSON } from './context.js' ;
2025-03-21 10:58:58 -07:00
program
. version ( 'Version ' + packageJSON . version )
. name ( packageJSON . name )
2025-05-13 14:40:03 -07:00
. option ( '--allowed-origins <origins>' , 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.' , semicolonSeparatedList )
. option ( '--blocked-origins <origins>' , 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.' , semicolonSeparatedList )
. option ( '--block-service-workers' , 'block service workers' )
2025-05-13 15:30:02 -07:00
. option ( '--browser <browser>' , 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.' )
2025-05-13 14:40:03 -07:00
. option ( '--caps <caps>' , 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.' )
2025-04-01 10:26:48 -07:00
. option ( '--cdp-endpoint <endpoint>' , 'CDP endpoint to connect to.' )
2025-05-13 14:40:03 -07:00
. option ( '--config <path>' , 'path to the configuration file.' )
. option ( '--device <device>' , 'device to emulate, for example: "iPhone 15"' )
. option ( '--executable-path <path>' , 'path to the browser executable.' )
. option ( '--headless' , 'run browser in headless mode, headed by default' )
. option ( '--host <host>' , 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.' )
. option ( '--ignore-https-errors' , 'ignore https errors' )
. option ( '--isolated' , 'keep the browser profile in memory, do not save it to disk.' )
2025-05-27 01:25:09 -07:00
. option ( '--image-responses <mode>' , 'whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.' )
2025-05-13 15:30:02 -07:00
. option ( '--no-sandbox' , 'disable the sandbox for all process types that are normally sandboxed.' )
2025-05-13 14:40:03 -07:00
. option ( '--output-dir <path>' , 'path to the directory for output files.' )
. option ( '--port <port>' , 'port to listen on for SSE transport.' )
. option ( '--proxy-bypass <bypass>' , 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"' )
. option ( '--proxy-server <proxy>' , 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"' )
2025-05-14 18:08:44 -07:00
. option ( '--save-trace' , 'Whether to save the Playwright Trace of the session into the output directory.' )
2025-05-13 14:40:03 -07:00
. option ( '--storage-state <path>' , 'path to the storage state file for isolated sessions.' )
. option ( '--user-agent <ua string>' , 'specify user agent string' )
. option ( '--user-data-dir <path>' , 'path to the user data directory. If not specified, a temporary directory will be created.' )
. option ( '--viewport-size <size>' , 'specify browser viewport size in pixels, for example "1280, 720"' )
2025-03-21 10:58:58 -07:00
. option ( '--vision' , 'Run server that uses screenshots (Aria snapshots are used by default)' )
. action ( async options = > {
2025-05-14 16:01:08 -07:00
const config = await resolveCLIConfig ( options ) ;
2025-05-06 14:27:28 -07:00
const connectionList : Connection [ ] = [ ] ;
setupExitWatchdog ( connectionList ) ;
2025-03-25 14:46:39 -07:00
2025-04-28 11:11:31 +02:00
if ( options . port )
2025-05-06 14:27:28 -07:00
startHttpTransport ( config , + options . port , options . host , connectionList ) ;
2025-04-28 11:11:31 +02:00
else
2025-05-06 14:27:28 -07:00
await startStdioTransport ( config , connectionList ) ;
2025-05-14 20:15:09 -07:00
if ( config . saveTrace ) {
const server = await startTraceViewerServer ( ) ;
const urlPrefix = server . urlPrefix ( 'human-readable' ) ;
const url = urlPrefix + '/trace/index.html?trace=' + config . browser . launchOptions . tracesDir + '/trace.json' ;
// eslint-disable-next-line no-console
console . error ( '\nTrace viewer listening on ' + url ) ;
}
2025-03-21 10:58:58 -07:00
} ) ;
2025-05-06 14:27:28 -07:00
function setupExitWatchdog ( connectionList : Connection [ ] ) {
2025-04-07 23:51:57 +02:00
const handleExit = async ( ) = > {
2025-03-21 10:58:58 -07:00
setTimeout ( ( ) = > process . exit ( 0 ) , 15000 ) ;
2025-05-06 14:27:28 -07:00
for ( const connection of connectionList )
await connection . close ( ) ;
2025-03-21 10:58:58 -07:00
process . exit ( 0 ) ;
2025-04-07 23:51:57 +02:00
} ;
process . stdin . on ( 'close' , handleExit ) ;
process . on ( 'SIGINT' , handleExit ) ;
process . on ( 'SIGTERM' , handleExit ) ;
2025-03-21 10:58:58 -07:00
}
2025-05-05 11:28:14 -07:00
function semicolonSeparatedList ( value : string ) : string [ ] {
return value . split ( ';' ) . map ( v = > v . trim ( ) ) ;
}
2025-03-21 10:58:58 -07:00
program . parse ( process . argv ) ;