Command line interface for Percy visual testing platform that enables developers to capture, upload, and manage visual snapshots for web applications.
npx @tessl/cli install tessl/npm-percy--cli@1.31.0Percy CLI is a comprehensive command-line tool for visual testing that enables developers to capture, upload, and manage visual snapshots for web applications. It provides a unified interface for interacting with the Percy visual testing platform, offering commands for taking snapshots of static directories, executing test suites with visual capture, uploading images, and managing Percy builds and configurations.
npm install --save-dev @percy/cliThe Percy CLI is primarily used as a command-line tool, but it also exports programmatic functions:
import { percy, checkForUpdate } from "@percy/cli";For CommonJS:
const { percy, checkForUpdate } = require("@percy/cli");The primary interface is the percy command-line tool:
# Install Percy CLI
npm install --save-dev @percy/cli
# Set Percy token
export PERCY_TOKEN=your-percy-token
# Take snapshots of a test suite
percy exec -- npm test
# Snapshot a static directory
percy snapshot ./public
# Upload directory of images
percy upload ./screenshotsimport { percy } from "@percy/cli";
// Run Percy CLI programmatically
await percy(['exec', '--', 'npm', 'test']);Percy CLI is built around several key components:
@percy/core provides browser automation, asset discovery, and snapshot coordination@percy/client handles all communication with Percy's visual testing service@percy/config manages configuration loading, validation, and migration@percy/logger provides consistent, structured logging across all componentsEssential Percy workflow commands for starting, stopping, and executing visual tests with any test runner or static content.
percy exec -- <command> # Start Percy, run command, then stop
percy start # Start Percy process in background
percy stop # Stop Percy process
percy ping # Check if Percy process is runningCapture visual snapshots of static directories, file lists, or sitemaps without requiring a test runner.
percy snapshot <dir|file|sitemap> # Snapshot static content
--base-url <url> # Base URL for hosted pages
--include <pattern> # Include patterns (multiple)
--exclude <pattern> # Exclude patterns (multiple)
--clean-urls # Remove file extensions from URLsCommands for managing Percy builds, including waiting for completion, finalizing parallel builds, and reviewing build results.
percy build wait # Wait for build completion
--build <build-id> # Specific build ID
--project <project> # Project slug
--commit <sha> # Commit SHA
--timeout <ms> # Timeout duration
--fail-on-changes # Exit with error on diffs
percy build finalize # Finalize parallel builds
percy build id # Print current build ID
percy build approve <build-id> # Approve build
percy build reject <build-id> # Reject build
percy build delete <build-id> # Delete buildTools for creating, validating, and migrating Percy configuration files across different formats.
percy config create [filepath] # Create new config file
--rc # Create .percyrc
--yaml # Create .percy.yaml
--json # Create .percy.json
--js # Create .percy.js
percy config validate [filepath] # Validate config file
percy config migrate [filepath] # Migrate to latest format
--dry-run # Show migration without writingDirect upload of image files as visual snapshots, useful for integrating with external screenshot tools.
percy upload <dirname> # Upload image directory
--files <pattern> # File patterns (default: **/*.{png,jpg,jpeg})
--ignore <pattern> # Ignore patterns
--strip-extensions # Remove extensions from snapshot namesSpecialized commands for visual testing of native mobile applications with Percy's app testing platform.
percy app exec -- <command> # Execute with Percy for native apps
percy app start # Start Percy for native apps
percy app stop # Stop Percy app process
percy app ping # Ping Percy app processAdvanced APIs for SDK development, custom integrations, and deep Percy automation. Includes the Percy core engine, configuration system, API client, environment detection, and utility libraries.
import Percy from "@percy/core"; // Core visual testing engine
import { load, validate } from "@percy/config"; // Configuration system
import PercyClient from "@percy/client"; // Percy API client
import PercyEnv from "@percy/env"; // CI environment detectionAll Percy commands support these global flags:
# Logging Control
--verbose, -v # Log everything (debug level)
--quiet, -q # Log errors only
--silent, -s # Log nothing
# Percy Configuration
--config, -c <path> # Configuration file path
--dry-run, -d # Print snapshot names without uploading
--labels, -l <labels> # Build labels (comma-separated)
# Server Configuration
--port, -P <port> # Local server port (default: 5338)
# Asset Discovery
--allowed-hostname <pattern> # Allowed hostname patterns
--disallowed-hostname <pattern> # Disallowed hostname patterns
--network-idle-timeout <ms> # Network idle timeout
--disable-cache # Disable asset caching
--debug # Debug asset discoveryPERCY_TOKEN # Percy project token (required)# Build Configuration
PERCY_PARALLEL_TOTAL # Number of parallel processes
PERCY_PARALLEL_NONCE # Parallel build identifier
PERCY_PARTIAL_BUILD # Mark build as partial (1 to enable)
PERCY_BUILD_ID # Build identifier (set by percy exec)
PERCY_BUILD_URL # Build URL (set by percy exec)
PERCY_COMMIT # Override commit SHA
PERCY_BRANCH # Override branch name
# Logging Configuration
PERCY_DEBUG # Debug namespace patterns
PERCY_LOGLEVEL # Global log level
PERCY_SKIP_UPDATE_CHECK # Skip version checks (1 to enable)
PERCY_CLIENT_ERROR_LOGS # Enable client error logging (1 to enable)
# Advanced Configuration
PERCY_CLIENT_API_URL # Override Percy API URL
PERCY_CONFIG # Configuration file path
PERCY_GZIP # Enable gzip compression (1 to enable)
PERCY_RESOURCE_UPLOAD_CONCURRENCY # Upload concurrency limit
PERCY_SERVER_ADDRESS # Percy server address for SDK communication
PERCY_ENABLE # Enable/disable Percy (0 to disable)
PERCY_GITHUB_ACTION # GitHub Action identifier
PERCY_DISABLE_SYSTEM_MONITORING # Disable system monitoring (1 to disable)
# CI Environment Variables (detected automatically)
# Travis CI
TRAVIS_BUILD_ID # Travis build identifier
TRAVIS_COMMIT # Travis commit SHA
TRAVIS_PULL_REQUEST # Travis PR number
TRAVIS_BRANCH # Travis branch name
# Jenkins
JENKINS_URL # Jenkins server URL
GIT_COMMIT # Git commit SHA
ghprbPullId # GitHub PR builder pull ID
GIT_BRANCH # Git branch name
# CircleCI
CIRCLECI # CircleCI indicator
CIRCLE_SHA1 # Circle commit SHA
CIRCLE_BRANCH # Circle branch name
CIRCLE_BUILD_NUM # Circle build number
# GitHub Actions
GITHUB_ACTIONS # GitHub Actions indicator
GITHUB_SHA # GitHub commit SHA
GITHUB_REF # GitHub reference
# GitLab CI
GITLAB_CI # GitLab CI indicator
CI_COMMIT_SHA # GitLab commit SHA
CI_COMMIT_REF_NAME # GitLab branch name
CI_MERGE_REQUEST_IID # GitLab merge request ID
# Azure DevOps
TF_BUILD # Team Foundation indicator
BUILD_SOURCEVERSION # Azure commit SHA
BUILD_SOURCEBRANCH # Azure branch name
SYSTEM_PULLREQUEST_PULLREQUESTID # Azure PR ID/**
* Main Percy CLI function
* @param args - Command line arguments array
* @returns Promise that resolves when command completes
*/
function percy(args: string[]): Promise<void>;
/**
* Check for CLI updates and display warnings if newer version available
* @returns Promise that resolves when check completes
*/
function checkForUpdate(): Promise<void>;// Command result types
interface CommandResult {
success: boolean;
exitCode: number;
output?: string;
error?: Error;
}
// Command options interfaces
interface ExecOptions {
parallel?: boolean;
partial?: boolean;
testing?: boolean;
}
interface SnapshotOptions {
baseUrl?: string;
include?: string[];
exclude?: string[];
cleanUrls?: boolean;
files?: string;
}
interface UploadOptions {
files?: string[];
ignore?: string[];
stripExtensions?: boolean;
}
interface BuildWaitOptions {
build?: string;
project?: string;
commit?: string;
timeout?: number;
interval?: number;
failOnChanges?: boolean;
passIfApproved?: boolean;
}
interface BuildReviewOptions {
username?: string;
accessKey?: string;
}interface PercyConfig {
// Core configuration
version?: number;
snapshot?: SnapshotConfig;
discovery?: DiscoveryConfig;
agent?: AgentConfig;
// Build configuration
parallel?: {
total?: number;
nonce?: string;
};
// Upload configuration
defer?: boolean;
delayUploads?: boolean;
deferUploads?: boolean;
// Static configuration
static?: StaticConfig;
// Upload specific configuration
upload?: UploadConfig;
}
interface SnapshotConfig {
widths?: number[];
minHeight?: number;
percyCSS?: string;
enableJavaScript?: boolean;
enableLayout?: boolean;
disableShadowDOM?: boolean;
deviceScaleFactor?: number;
scope?: string;
ignoreRegions?: IgnoreRegion[];
considerRegions?: ConsiderRegion[];
}
interface DiscoveryConfig {
allowedHostnames?: string[];
disallowedHostnames?: string[];
networkIdleTimeout?: number;
concurrency?: number;
launchOptions?: LaunchOptions;
userAgent?: string;
deviceScaleFactor?: number;
}
interface AgentConfig {
assetDiscovery?: {
networkIdleTimeout?: number;
pagePoolSizeMin?: number;
pagePoolSizeMax?: number;
allowedHostnames?: string[];
disallowedHostnames?: string[];
requestHeaders?: Record<string, string>;
authorization?: {
username: string;
password: string;
};
};
}
interface StaticConfig {
baseUrl?: string;
include?: string[];
exclude?: string[];
cleanUrls?: boolean;
rewrites?: RewriteRule[];
}
interface UploadConfig {
files?: string[];
ignore?: string[];
stripExtensions?: boolean;
concurrency?: number;
}
interface LaunchOptions {
headless?: boolean;
args?: string[];
timeout?: number;
slowMo?: number;
devtools?: boolean;
executablePath?: string;
}
interface RewriteRule {
source: string;
destination: string;
}
interface IgnoreRegion {
selector?: string;
xpath?: string;
coordinates?: {
top: number;
bottom: number;
left: number;
right: number;
};
}
interface ConsiderRegion {
selector?: string;
xpath?: string;
coordinates?: {
top: number;
bottom: number;
left: number;
right: number;
};
}interface Build {
id: string;
number: number;
url: string;
webUrl: string;
state: 'pending' | 'processing' | 'finished' | 'failed';
reviewState?: 'unreviewed' | 'approved' | 'rejected';
reviewStateReason?: string;
isApproved?: boolean;
totalComparisons: number;
totalComparisonsFinished: number;
totalComparisonsDiff: number;
branch?: string;
commitSha?: string;
commitMessage?: string;
pullRequestNumber?: string;
}
interface Snapshot {
name: string;
url?: string;
domSnapshot?: string;
clientInfo?: string;
environmentInfo?: string;
widths?: number[];
minHeight?: number;
enableJavaScript?: boolean;
percyCSS?: string;
scope?: string;
additionalSnapshots?: AdditionalSnapshot[];
requestHeaders?: Record<string, string>;
authorization?: {
username: string;
password: string;
};
}
interface AdditionalSnapshot {
prefix?: string;
suffix?: string;
name?: string;
waitForTimeout?: number;
waitForSelector?: string;
execute?: string | Function;
percyCSS?: string;
ignoreRegions?: IgnoreRegion[];
considerRegions?: ConsiderRegion[];
}Percy CLI provides structured error handling with specific exit codes and error types:
--fail-on-changes)Common error scenarios include missing tokens, configuration validation failures, network connectivity issues, and build processing errors. The CLI provides detailed error messages and suggestions for resolution.