A modular plugin framework for Playwright to enable enhanced browser automation through plugins.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Create independent plugin-enabled instances from any compatible Playwright launcher. This is useful when you need multiple instances with different plugin configurations or when working with custom or non-standard Playwright implementations.
Augment any compatible Playwright browser launcher with plugin functionality. This creates a fresh PlaywrightExtra instance, unlike the default exports which return cached instances.
/**
* Augment the provided Playwright browser launcher with plugin functionality.
* Using addExtra will always create a fresh PlaywrightExtra instance.
* @param launcher - Playwright (or compatible) browser launcher
* @returns Enhanced launcher with plugin functionality
*/
function addExtra<Launcher extends PlaywrightCompatibleLauncher>(
launcher?: Launcher
): PlaywrightExtraClass & Launcher;Usage Examples:
import playwright from "playwright";
import { addExtra } from "playwright-extra";
// Create independent instances
const chromium1 = addExtra(playwright.chromium);
const chromium2 = addExtra(playwright.chromium);
// Each instance can have different plugins
chromium1.use(pluginA);
chromium2.use(pluginB);
// Instances are completely independent
const browser1 = await chromium1.launch();
const browser2 = await chromium2.launch();Create multiple independent instances with different plugin configurations.
import playwright from "playwright";
import { addExtra } from "playwright-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
import RecaptchaPlugin from "puppeteer-extra-plugin-recaptcha";
// Create specialized instances
const stealthChromium = addExtra(playwright.chromium);
stealthChromium.use(StealthPlugin());
const captchaChromium = addExtra(playwright.chromium);
captchaChromium.use(RecaptchaPlugin({
provider: { id: '2captcha', token: 'key' }
}));
// Use instances independently
const stealthBrowser = await stealthChromium.launch({ headless: true });
const captchaBrowser = await captchaChromium.launch({ headless: false });Integrate with custom or non-standard Playwright implementations.
import { addExtra } from "playwright-extra";
// Custom launcher that implements the required interface
const customLauncher = {
async launch(options) {
// Custom launch implementation
return customBrowser;
},
async connect(wsEndpoint, options) {
// Custom connect implementation
return customBrowser;
}
};
// Enhance custom launcher with plugins
const enhancedLauncher = addExtra(customLauncher);
enhancedLauncher.use(plugin);
const browser = await enhancedLauncher.launch();Create a fresh instance without specifying a launcher. The instance will attempt to load Playwright when methods are called.
import { addExtra } from "playwright-extra";
// Create instance without launcher
const launcher = addExtra();
launcher.use(plugin);
// Will attempt to load playwright-core or playwright when launch is called
const browser = await launcher.launch();The core class that implements plugin functionality for Playwright launchers.
constructor(launcher?: Partial<PlaywrightBrowserLauncher>);Create a new PlaywrightExtra instance with an optional launcher.
/**
* The main interface to register plugins.
* Can be called multiple times to enable multiple plugins.
* @param plugin - Plugin instance to register
* @returns The same PlaywrightExtra instance for optional chaining
*/
use(plugin: CompatiblePlugin): this;readonly plugins: PluginList;Access to the plugin manager for advanced configuration.
The class implements all standard Playwright browser launcher methods with plugin support:
async launch(
options?: LaunchOptions
): Promise<Browser>;
async launchPersistentContext(
userDataDir: string,
options?: BrowserContextOptions & LaunchOptions
): Promise<BrowserContext>;
async connect(
wsEndpointOrOptions: string | (ConnectOptions & { wsEndpoint?: string }),
wsOptions?: ConnectOptions
): Promise<Browser>;
async connectOverCDP(
wsEndpointOrOptions: string | (ConnectOverCDPOptions & { endpointURL?: string }),
wsOptions?: ConnectOverCDPOptions
): Promise<Browser>;interface PlaywrightCompatibleLauncher {
connect(...args: any[]): Promise<any>;
launch(...args: any[]): Promise<any>;
}
class PlaywrightExtraClass {
readonly plugins: PluginList;
constructor(launcher?: Partial<PlaywrightBrowserLauncher>);
use(plugin: CompatiblePlugin): this;
async launch(options?: LaunchOptions): Promise<Browser>;
async launchPersistentContext(userDataDir: string, options?: BrowserContextOptions & LaunchOptions): Promise<BrowserContext>;
async connect(wsEndpointOrOptions: string | ConnectOptions, wsOptions?: ConnectOptions): Promise<Browser>;
async connectOverCDP(wsEndpointOrOptions: string | ConnectOverCDPOptions, wsOptions?: ConnectOverCDPOptions): Promise<Browser>;
}
type PlaywrightBrowserLauncher = BrowserType<{}>;Install with Tessl CLI
npx tessl i tessl/npm-playwright-extra