English | 简体中文
playwright-stealth-cli is a thin wrapper around microsoft/playwright-cli, published on npm as @playwright/cli. It keeps that upstream terminal command surface intact while adding:
puppeteer-extra-plugin-stealthenabled by default- temporary-profile defaults for safer one-off runs
- explicit persistent profile controls
- unpacked Chromium extension loading
The installed command name is:
playwright-stealthRelated resources:
Install globally:
npm install -g playwright-stealth-cliThen run:
playwright-stealth open https://example.comYou can also use it with npx:
npx playwright-stealth-cli open https://example.comCommon examples:
Default run:
playwright-stealth open https://x.com/i/flow/loginUse a persistent Chromium profile:
playwright-stealth open --profile-dir "/path/to/chromium-profile" https://x.com/i/flow/loginUse stock Chrome:
playwright-stealth open --channel chrome https://x.com/i/flow/loginDisable stealth for one run:
playwright-stealth open --disable-stealth https://example.comUse a temporary profile explicitly:
playwright-stealth open --temp-profile https://example.comLoad an unpacked extension in Chromium:
playwright-stealth open --profile-dir "/path/to/chromium-ext-profile" --extension-path "/path/to/extension"List running browser/profile pairs:
playwright-stealth profile-listMachine-readable output:
playwright-stealth profile-list --jsonCheck whether a profile is already in use:
playwright-stealth profile-status "/path/to/chromium-profile"Machine-readable status:
playwright-stealth profile-status "/path/to/chromium-profile" --jsonNote:
profile-listreports active wrapper-managed sessions from the upstream session registry.profile-statuschecks whether a profile is in use by one of those active sessions.
- Stealth is enabled by default.
- A temporary profile is used by default.
- Temporary profiles are created under the system temp directory.
- Old
playwright-cli-profile-*temp folders are cleaned up on startup when possible.
This means the default behavior is friendly for ad-hoc browser automation, but real login flows usually work better with an explicit persistent profile.
For login flows, extension reuse, and long-lived browser state, strongly prefer an explicit persistent profile:
playwright-stealth open --profile-dir "/path/to/chromium-main" https://x.com/i/flow/loginFor Chrome:
playwright-stealth open --channel chrome --profile-dir "/path/to/chrome-main" https://x.com/i/flow/loginImportant:
- Do not reuse the same profile directory between Chrome and Chromium.
- Keep Chrome profiles and Chromium profiles in separate directories.
- Mixing them can cause crashes or unstable behavior.
Recommended naming:
- Chromium:
.../profiles/chromium-main - Chrome:
.../profiles/chrome-main
If you try to start a profile that appears to already be in use, the CLI will ask whether to continue. You can skip that confirmation with:
playwright-stealth open --profile-dir "/path/to/chromium-main" --force-profileChromium supports loading unpacked extensions through CLI flags in this wrapper:
playwright-stealth open --profile-dir "/path/to/chromium-ext-profile" --extension-path "/path/to/ext"For Chromium, a successfully loaded extension can usually be opened directly via its extension URL.
Chrome is different:
- In current Chrome versions, loading unpacked extensions purely from startup command line flags is not reliable in this workflow.
- If you want to use stock Chrome with extensions, use a persistent Chrome profile and install the extension manually inside that profile.
Recommended Chrome extension workflow:
- Start Chrome with a persistent profile.
- Open
chrome://extensions/. - Manually install the extension into that profile.
- Reuse that same profile in later runs.
Example:
playwright-stealth open --channel chrome --profile-dir "/path/to/chrome-ext-profile"This wrapper delegates user-facing terminal commands to @playwright/cli instead of reimplementing them by hand. That is how it can follow upstream updates with minimal local code changes.
The upstream command families are preserved, including:
- Core:
open,close,goto,type,click,dblclick,fill,drag,hover,select,upload,check,uncheck,snapshot,eval,dialog-accept,dialog-dismiss,resize,delete-data - Navigation:
go-back,go-forward,reload - Keyboard:
press,keydown,keyup - Mouse:
mousemove,mousedown,mouseup,mousewheel - Save as:
screenshot,pdf - Tabs:
tab-list,tab-new,tab-close,tab-select - Storage:
state-load,state-save,cookie-*,localstorage-*,sessionstorage-* - Network and DevTools:
route,route-list,unroute,console,run-code,network,tracing-*,video-*,show,devtools-start - Install and session management:
install,install-browser,list,close-all,kill-all
Wrapper-only additions:
profile-listprofile-status
Important:
- This is not based on the npm
playwrighttest runner CLI. playwright-stealthis meant to preserve themicrosoft/playwright-cliterminal workflow and add stealth/profile/extension behavior around it.
Clone the project, install dependencies, and use the local entry point:
npm install
node ./cli.js open https://example.comRun the smoke tests:
npm testOperational advice:
- Fully close the browser when you are done with a profile.
- If you automate this CLI from an agent or script, periodically run
playwright-stealth profile-listto check for leftover browser processes. - Prefer separate persistent profiles per workflow or account to avoid accidental profile contention.
This project is designed so that most upstream command changes come from upgrading @playwright/cli, rather than manually copying commands again.
In practice that means:
- The user-facing terminal command set usually follows upstream automatically.
- Upstream additions to commands and help output usually do not require rewriting this wrapper.
- Our local code mainly patches argument normalization, profile handling, and daemon/browser launch behavior.
However, this is still a thin wrapper around some upstream internal modules, so upgrades are not completely zero-risk.
Usually, a package upgrade is enough when upstream only changes:
- command coverage
- help text
- minor CLI behavior
You should still expect a small compatibility fix if upstream changes:
- internal file paths
- session config structure
- daemon startup flow
- browser context factory behavior
- config parsing internals
Recommended upgrade flow:
- Upgrade
@playwright/cli. - Run
npm test. - Verify
playwright-stealth --help. - Verify
playwright-stealth open --help. - Run a basic browser flow such as
open -> goto -> close-all. - Re-check wrapper-specific features such as stealth, persistent profiles, and
--extension-path.
Publishable package files are restricted in package.json via the files field, so local development artifacts like artifacts/, scripts/, and test/ are not uploaded to npm.