Skip to main content
Version: 1.x

Playwright CLI Setup

The Playwright CLI (@playwright/cli) is a command-line interface for controlling browsers from your terminal. It provides the same browser automation capabilities as the MCP server, but communicates through stdin/stdout instead of a JSON-RPC protocol. This makes it a token-efficient alternative — each command is a single shell invocation rather than a structured tool call, which reduces context window usage in AI agent conversations.

Both MCP and CLI are first-class, coexisting options in Praman. Choose whichever fits your workflow, or use both side by side.

Prerequisites

RequirementVersion
Node.js>=22
@playwright/test>=1.57.0 <2.0.0
playwright-pramanLatest
@playwright/cliLatest (installed globally or via npx)

Ensure you have already completed the base Praman setup:

npm install --save-dev playwright-praman @playwright/test
npx playwright install

Install the Playwright CLI

Install globally for persistent access:

npm install -g @playwright/cli@latest

Or run on-demand with npx (no global install required):

npx @playwright/cli --help

Verify the installation:

npx @playwright/cli --version

Bridge Configuration

Praman's UI5 bridge must be injected into the browser so the CLI can discover and interact with SAP UI5 controls. Create a configuration file that tells the CLI to load the bridge init script on every page navigation.

Create .playwright/praman-cli.config.json in your project root:

{
"browser": {
"browserName": "chromium",
"launchOptions": {
"headless": false,
"channel": "chromium"
},
"initScript": ["./node_modules/playwright-praman/dist/browser/praman-bridge-init.js"]
}
}
FieldPurpose
browser.browserNameBrowser engine (chromium, firefox, webkit)
browser.launchOptionsPlaywright launch options (headed mode, channel selection)
browser.launchOptions.channelSet to "chromium" to use Playwright's bundled browser
browser.initScriptPraman bridge script — injected into every page via CDP
Auth session reuse

To reuse an authenticated session, run npx playwright test tests/auth.setup.ts once to save a session to .auth/sap-session.json, then load it with the CLI:

npx @playwright/cli state-load .auth/sap-session.json

Quick Test

Verify that the bridge is loaded and the CLI can discover UI5 controls.

1. Open a browser

npx @playwright/cli open --config .playwright/praman-cli.config.json "$SAP_CLOUD_BASE_URL"

This launches Playwright's bundled Chromium with the Praman bridge injected and navigates to your SAP system. The --config flag is only needed on the open command — subsequent commands connect to the running session automatically.

2. Verify bridge readiness

In a separate terminal, run:

npx @playwright/cli eval "() => window.__praman_bridge !== undefined"

Expected output: true. This confirms the bridge init script was injected successfully.

eval syntax

The eval command requires a function wrapper: "() => expression", not a bare expression.

3. Discover a control

npx @playwright/cli eval "() => {
const reg = sap.ui.core.ElementRegistry.all();
const btn = Object.values(reg).find(c => c.getMetadata().getName() === 'sap.m.Button');
return btn ? { id: btn.getId(), text: btn.getText ? btn.getText() : '' } : null;
}"

This returns the first sap.m.Button control found on the page. If you see a JSON object with control metadata, the bridge is working correctly.

For more complex discovery, use run-code with the pre-built scripts:

npx @playwright/cli run-code "$(cat node_modules/playwright-praman/dist/scripts/discover-all.js)"

4. Close the browser

npx @playwright/cli close

Agent Setup with CLI

Praman's init-agents command installs CLI-based agent definitions by default. Use --no-cli to skip them if you only want MCP-based agents:

# Claude Code (CLI agents installed by default)
npx playwright-praman init-agents --loop=claude

# GitHub Copilot — also covers VS Code Copilot (.github/agents/)
npx playwright-praman init-agents --loop=copilot

# Cursor
npx playwright-praman init-agents --loop=cursor

# Auto-detect all IDEs
npx playwright-praman init-agents

# Skip CLI agents (MCP agents only)
npx playwright-praman init-agents --loop=claude --no-cli

This installs agent definitions that reference npx @playwright/cli commands instead of MCP tool calls.

VS Code vs GitHub Copilot

VS Code Copilot reads agents from .github/agents/. Use --loop=copilot (not --loop=vscode) to install CLI agents there. --loop=vscode installs VS Code IDE settings only (snippets, extensions, settings.json) — it has no CLI agent files.

FlagDescription
--loop=<ide>Target IDE: claude, copilot, cursor, jules, opencode, vscode
--no-cliSkip Playwright CLI agent definitions (installed by default)
--forceOverwrite existing agent files

MCP vs CLI Comparison

Both approaches give agents full browser control. The difference is in the communication protocol and token efficiency.

AspectMCP (JSON-RPC)CLI (stdin/stdout)
CommunicationJSON-RPC over stdioShell commands via stdin/stdout
Token cost per callHigher (structured JSON request + response)Lower (single command string + text output)
Setup.mcp.json with playwright-test server.playwright/praman-cli.config.json
Browser lifecycleManaged by MCP serverManaged by CLI process
Agent integrationNative tool calls (Claude, Copilot, Cursor)Shell execution (Bash tool, terminal)
Best forIDEs with native MCP supportToken-constrained agents, CI pipelines, scripting
Parallel sessionsOne browser per MCP serverMultiple CLI processes
Bridge injectionAutomatic via Praman MCP configVia initScript in CLI config

Example: Discovering a Button

MCP approach (tool call):

{
"tool": "browser_evaluate",
"arguments": {
"expression": "window.__praman_bridge.findControl({ controlType: 'sap.m.Button', properties: { text: 'Create' } })"
}
}

CLI approach (shell command):

npx @playwright/cli eval "() => window.__praman_bridge.findControl({ controlType: 'sap.m.Button', properties: { text: 'Create' } })"

Both return the same result. The CLI version uses fewer tokens because there is no JSON wrapper around the command.

Example: Clicking a Control

MCP approach:

{
"tool": "browser_click",
"arguments": {
"element": "Create BOM button",
"ref": "s1e45"
}
}

CLI approach:

npx @playwright/cli click "Create BOM button"

Example: Taking a Screenshot

MCP approach:

{
"tool": "browser_take_screenshot"
}

CLI approach:

npx @playwright/cli screenshot screenshot.png

Using MCP and CLI Together

You can use both MCP and CLI in the same project. A typical pattern:

  • MCP for interactive agent sessions (planning, discovery, healing) where the IDE manages the browser lifecycle
  • CLI for scripted automation, CI pipelines, and token-constrained batch operations

Both share the same .auth/ session storage and praman.config.ts settings.

Troubleshooting

SymptomLikely CauseFix
command not found: playwrightCLI not installedRun npm install -g @playwright/cli@latest or use npx
__praman_bridge is undefinedBridge init script not loadedVerify initScript path in .playwright/praman-cli.config.json
ERR_BRIDGE_TIMEOUTPage is not a UI5 appVerify the URL passed to open points to a Fiori Launchpad
Browser opens but no SAP loginMissing or expired auth sessionRe-run npx playwright test tests/auth.setup.ts
storageState file not foundAuth setup not run yetRun auth setup first: npx playwright test tests/auth.setup.ts
CLI hangs after openBrowser waiting for interactionUse a separate terminal for subsequent CLI commands
initScript path resolves to missing filePackage not installed or wrong pathRun npm install and verify dist/browser/praman-bridge-init.js exists
ERR_CONTROL_NOT_FOUNDControl not on current pageNavigate to the correct page first, then retry discovery
Permission denied on global installnpm global directory permissionsUse npx @playwright/cli instead of global install

Verifying the Init Script Path

If the bridge is not loading, verify the init script exists:

ls node_modules/playwright-praman/dist/browser/praman-bridge-init.js

If the file does not exist, reinstall the package:

npm install --save-dev playwright-praman

Debugging Bridge Injection

To confirm the bridge is injected, open the browser console (F12) and type:

typeof window.__praman_bridge;

If this returns "undefined", the initScript path in your config is incorrect. If it returns "object", the bridge is loaded and ready.

Next Steps

TopicDocumentation
Agent & IDE setup (MCP)Agent Setup
Running your first agentRunning Your Agent
Authentication strategiesAuthentication
Configuration referenceConfiguration
Selectors referenceSelectors