A command line tool to help build, run, and test web extensions
—
Browser automation system for running extensions in development mode with support for Firefox desktop, Firefox Android, and Chromium browsers. Provides hot reloading, profile management, and cross-platform testing capabilities.
Launch extensions in browsers with comprehensive configuration options for development and testing.
/**
* Run an extension in one or more browsers
* @param params - Run configuration parameters
* @param options - Optional dependencies and settings
* @returns Promise that resolves when runner is stopped
*/
function run(params: RunParams, options?: RunOptions): Promise<void>;
interface RunParams {
/** Source directory containing the extension */
sourceDir: string;
/** Directory for build artifacts */
artifactsDir: string;
/** Target browsers to run ['firefox-desktop', 'firefox-android', 'chromium'] */
target?: string[];
/** Path or alias to Firefox binary (firefox, beta, nightly, deved) */
firefox?: string;
/** Firefox profile path or name to use */
firefoxProfile?: string;
/** Create profile if it doesn't exist */
profileCreateIfMissing?: boolean;
/** Keep profile changes after exit */
keepProfileChanges?: boolean;
/** Path to Chromium binary */
chromiumBinary?: string;
/** Path to custom Chromium profile */
chromiumProfile?: string;
/** Enable automatic extension reloading on file changes */
reload?: boolean;
/** Specific files to watch for reloading */
watchFile?: string[];
/** Paths to ignore when watching for changes */
watchIgnored?: string[];
/** Pre-install extension into profile before startup */
preInstall?: boolean;
/** Custom Firefox preferences */
pref?: string[];
/** URLs to open at startup */
startUrl?: string[];
/** Open DevTools for the extension */
devtools?: boolean;
/** Open Browser Console */
browserConsole?: boolean;
/** Additional CLI arguments for browser */
args?: string[];
/** Disable user input features */
noInput?: boolean;
/** Files to ignore during operations */
ignoreFiles?: string[];
/** Enable verbose logging */
verbose?: boolean;
}
interface RunOptions {
/** Custom build function */
build?: Function;
/** Desktop notification handler */
desktopNotifications?: Function;
/** Firefox app utilities */
firefoxApp?: any;
/** Firefox remote debugging client */
firefoxClient?: Function;
/** Manifest validator */
getValidatedManifest?: Function;
/** Extension runner factory */
createExtensionRunner?: Function;
/** Multi-extension runner class */
MultiExtensionRunner?: any;
/** Reload strategy implementation */
reloadStrategy?: any;
}Usage Examples:
import { cmd } from "web-ext";
// Basic Firefox run
await cmd.run({
sourceDir: './my-extension',
target: ['firefox-desktop']
});
// Run with custom Firefox and profile
await cmd.run({
sourceDir: './extension',
target: ['firefox-desktop'],
firefox: 'firefox-nightly',
firefoxProfile: './test-profile',
startUrl: ['https://example.com'],
devtools: true
});
// Run on multiple browsers
await cmd.run({
sourceDir: './extension',
target: ['firefox-desktop', 'chromium'],
chromiumBinary: 'google-chrome',
reload: true,
verbose: true
});
// Firefox Android development
await cmd.run({
sourceDir: './extension',
target: ['firefox-android'],
adbDevice: 'emulator-5554',
firefoxApk: 'org.mozilla.fenix'
});Create browser-specific extension runners with unified interface.
/**
* Create an extension runner for specified target browser
* @param params - Runner creation parameters
* @returns Promise resolving to extension runner instance
*/
function createExtensionRunner(params: ExtensionRunnerParams): Promise<ExtensionRunner>;
interface ExtensionRunnerParams {
/** Target browser type */
target: 'firefox-desktop' | 'firefox-android' | 'chromium';
/** Extension source directory */
sourceDir: string;
/** Build artifacts directory */
artifactsDir: string;
/** Desktop notification handler */
desktopNotifications: Function;
/** Browser-specific options */
[key: string]: any;
}
interface ExtensionRunner {
/** Get name of the runner */
getName(): string;
/** Check if runner supports reloading */
reloadAllowed(): boolean;
/** Start the browser with extension */
run(): Promise<any>;
/** Reload the extension */
reloadExtension(): Promise<void>;
/** Exit the runner */
exit(): Promise<void>;
}Manage multiple browser targets simultaneously.
class MultiExtensionRunner {
constructor(params: MultiRunnerParams);
/** Start all configured runners */
run(): Promise<void>;
/** Reload extensions in all runners */
reloadAllExtensions(): Promise<void>;
/** Exit all runners */
exit(): Promise<void>;
}
interface MultiRunnerParams {
/** Array of extension runners */
runners: ExtensionRunner[];
/** Desktop notification handler */
desktopNotifications: Function;
/** Should exit process on completion */
shouldExitProgram: boolean;
}Specialized runner for Firefox desktop with profile management and debugging support.
interface FirefoxDesktopRunner extends ExtensionRunner {
/** Firefox-specific configuration */
firefox: string;
firefoxProfile?: string;
keepProfileChanges: boolean;
profileCreateIfMissing: boolean;
args: string[];
pref: object;
startUrl: string[];
devtools: boolean;
browserConsole: boolean;
}Specialized runner for Firefox on Android devices via ADB.
interface FirefoxAndroidRunner extends ExtensionRunner {
/** ADB binary path */
adbBin?: string;
/** ADB host connection */
adbHost?: string;
/** ADB port */
adbPort?: string;
/** Target Android device ID */
adbDevice?: string;
/** ADB discovery timeout in milliseconds */
adbDiscoveryTimeout?: number;
/** Remove old artifacts from device */
adbRemoveOldArtifacts?: boolean;
/** Firefox APK package name */
firefoxApk?: string;
/** Firefox APK component name */
firefoxApkComponent?: string;
}Specialized runner for Chromium-based browsers.
interface ChromiumRunner extends ExtensionRunner {
/** Chromium binary path */
chromiumBinary?: string;
/** Custom Chromium profile path */
chromiumProfile?: string;
/** Additional launch arguments */
args: string[];
/** URLs to open at startup */
startUrl: string[];
}Hot reloading system for development workflow.
interface ReloadStrategy {
/** Reload extension when files change */
reloadExtension(runners: ExtensionRunner[]): Promise<void>;
/** Watch for file changes */
watchForChanges(params: WatchParams): Promise<void>;
}
interface WatchParams {
sourceDir: string;
watchFile?: string[];
watchIgnored?: string[];
onFileChanged: () => void;
}
/** Default reload strategy instance */
const defaultReloadStrategy: ReloadStrategy;Usage Example:
import { defaultReloadStrategy } from "web-ext";
// Custom reload handling
await defaultReloadStrategy.watchForChanges({
sourceDir: './extension',
watchFile: ['manifest.json', 'content.js'],
watchIgnored: ['**/*.log'],
onFileChanged: async () => {
console.log('Extension files changed, reloading...');
await defaultReloadStrategy.reloadExtension(runners);
}
});Extended parameters for Firefox Android development:
interface AndroidParams {
/** Path to adb binary */
adbBin?: string;
/** ADB host to connect to */
adbHost?: string;
/** ADB port number */
adbPort?: string;
/** Android device identifier */
adbDevice?: string;
/** Timeout for device discovery in milliseconds */
adbDiscoveryTimeout?: number;
/** Remove old artifacts from device */
adbRemoveOldArtifacts?: boolean;
/** Firefox APK package (e.g., org.mozilla.fenix) */
firefoxApk?: string;
/** Firefox APK component (defaults to <firefoxApk>/.App) */
firefoxApkComponent?: string;
}Extension runners handle various error scenarios:
Install with Tessl CLI
npx tessl i tessl/npm-web-ext