### Preview documentation locally Source: https://salamaashoush.github.io/ferridriver/contributing.html Commands to install dependencies and start the development server for the documentation site. ```bash cd site bun install bun run dev ``` -------------------------------- ### Basic Configuration Example Source: https://salamaashoush.github.io/ferridriver/test-runner/config.html A standard configuration file setup defining test execution parameters, browser settings, and reporters. ```toml [test] workers = 4 timeout = 30000 expectTimeout = 5000 retries = 1 fullyParallel = true outputDir = "test-results" [test.browser] backend = "cdp-pipe" headless = true [test.browser.viewport] width = 1280 height = 720 [[test.reporter]] name = "terminal" [[test.reporter]] name = "html" ``` -------------------------------- ### Install Chromium Browser Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Use these commands to install Chromium or its dependencies when the browser is not found. ```bash ferridriver install chromium # or ferridriver install --with-deps chromium # also installs Linux libs ``` -------------------------------- ### Web Server Configuration Source: https://salamaashoush.github.io/ferridriver/test-runner/config.html Configure a local web server to start automatically before running tests. ```toml [[test.webServer]] command = "npm run preview" url = "http://localhost:4173" reuseExistingServer = true timeout = 60000 ``` -------------------------------- ### Install browsers with ferridriver install Source: https://salamaashoush.github.io/ferridriver/cli/ferridriver.html Downloads browser binaries into the ferridriver cache. Use --with-deps to install required Linux system libraries. ```bash ferridriver install [BROWSERS]... [--with-deps] ``` -------------------------------- ### Define session parameters Source: https://salamaashoush.github.io/ferridriver/mcp/overview.html Examples of session string formats to isolate browser contexts and instances. ```text session: "admin" isolated context named "admin" session: "staging:qa" context "qa" on Chrome instance "staging" ``` -------------------------------- ### Install Linux Dependencies Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Install required system packages for building Ferridriver on various Linux distributions. ```bash sudo apt-get install -y pkg-config libclang-dev # Debian / Ubuntu sudo pacman -S pkgconf clang # Arch sudo dnf install pkg-config clang-devel # Fedora ``` -------------------------------- ### Install browser binaries Source: https://salamaashoush.github.io/ferridriver/guide/installation.html Download specific browser binaries into the local cache for use with Ferridriver. ```bash ferridriver install chromium # default ferridriver install --with-deps chromium # Linux: also install system libs ferridriver install firefox chromium-headless-shell ferridriver install webkit # Playwright WebKit build ``` -------------------------------- ### Install Browser Dependencies Source: https://salamaashoush.github.io/ferridriver/mcp/setup.html Commands to install browser binaries required for the Ferridriver backends. ```bash ferridriver install chromium # default ferridriver install --with-deps chromium # Linux: + system libs ``` -------------------------------- ### Install Node.js or Bun package Source: https://salamaashoush.github.io/ferridriver/guide/installation.html Add the Ferridriver package to your JavaScript or TypeScript project. ```bash npm install @ferridriver/node # or bun add @ferridriver/node ``` -------------------------------- ### Install Ferridriver CLI binary Source: https://salamaashoush.github.io/ferridriver/guide/installation.html Install the CLI tool via cargo or download prebuilt binaries from GitHub releases. ```bash # From crates.io cargo install ferridriver-cli # From GitHub releases (prebuilt binary) curl -fsSL https://github.com/salamaashoush/ferridriver/releases/latest/download/ferridriver-VERSION-TARGET.tar.gz | tar xz ``` -------------------------------- ### Test Harness Configuration Source: https://salamaashoush.github.io/ferridriver/test-runner/rust.html Setup for the test harness file and Cargo.toml configuration. ```rust // tests/harness.rs mod homepage; mod login; ferridriver_test::main!(); ``` ```toml # Cargo.toml [[test]] name = "e2e" path = "tests/harness.rs" harness = false [dev-dependencies] ferridriver-test = "0.5" ``` -------------------------------- ### Start HTTP Transport Server Source: https://salamaashoush.github.io/ferridriver/mcp/setup.html Command to launch the server in HTTP mode. Ensure the server is deployed behind a firewall or proxy as it lacks built-in authentication. ```bash ferridriver mcp --transport http --port 8080 ``` -------------------------------- ### Install Ferridriver via shell script Source: https://salamaashoush.github.io/ferridriver/guide/installation.html Use the provided curl command to install the binary and dependencies on Linux or macOS. ```bash curl -fsSL https://raw.githubusercontent.com/salamaashoush/ferridriver/main/install.sh | bash ``` ```bash curl -fsSL .../install.sh | bash -s -- --no-browser # skip Chromium download curl -fsSL .../install.sh | bash -s -- --deps-only # system deps only ``` -------------------------------- ### TypeScript screenshot examples Source: https://salamaashoush.github.io/ferridriver/recipes/screenshots-and-traces.html Demonstrates taking screenshots in TypeScript, including writing bytes manually for locator screenshots. ```typescript await page.screenshot({ path: 'home.png', fullPage: true }); // Locator.screenshot() returns the bytes (no path option) — write them yourself. const chart = await page.locator('.chart').screenshot(); await Bun.write('chart.png', chart); ``` -------------------------------- ### Accessibility Snapshot Output Format Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Example of the LLM-optimized tree structure returned by the snapshot tool. ```text ### Page - URL: https://example.com - Title: Example Domain ### Snapshot - heading "Example Domain" [ref=e1] [level=1] - paragraph [ref=e2] - paragraph [ref=e3] - link "Learn more" [ref=e4] [url=https://iana.org/domains/example] ``` -------------------------------- ### Run MCP server via CLI Source: https://salamaashoush.github.io/ferridriver/mcp/overview.html Commands to start the MCP server using different transport protocols and browser backends. ```bash # stdio (Claude Code, Cursor, Claude Desktop) ferridriver mcp # HTTP on port 8080 ferridriver mcp --transport http --port 8080 # Backend choice ferridriver mcp --backend webkit # Playwright WebKit ferridriver mcp --backend bidi # Firefox via WebDriver BiDi ferridriver mcp --backend cdp-pipe --headless # Attach to a running Chrome ferridriver mcp --auto-connect chrome ferridriver mcp --connect ws://localhost:9222/devtools/browser/... ``` -------------------------------- ### run_script Parameter Configuration Source: https://salamaashoush.github.io/ferridriver/scripting/run-script.html Example structure for the run_script tool call parameters, including source code, arguments, and optional execution constraints. ```json { "source": "await page.goto(args[0]); return await page.title();", "args": ["https://example.com"], "timeout_ms": 30000, // optional; default 5 minutes "memory_limit_mb": 256, // optional; default 256 MiB "session": "default" // optional; format "instance:context" } ``` -------------------------------- ### Run MCP server in CI Source: https://salamaashoush.github.io/ferridriver/recipes/ci-github-actions.html Start an MCP server and wait for it to be ready before running agent flows. ```yaml - name: Start MCP server run: | ferridriver mcp --transport http --port 8080 & timeout 30 bash -c 'until curl -s http://localhost:8080/mcp; do sleep 1; done' - name: Run agent flow run: bun run scripts/agent-eval.ts ``` -------------------------------- ### Configure mobile emulation in TypeScript Source: https://salamaashoush.github.io/ferridriver/recipes/mobile-emulation.html Example of setting mobile emulation options when creating a new browser context in TypeScript. ```typescript const context = await browser.newContext({ viewport: { width: 390, height: 844 }, deviceScaleFactor: 3, isMobile: true, hasTouch: true, userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) ...', locale: 'en-US', timezoneId: 'America/Los_Angeles', colorScheme: 'dark', }); ``` -------------------------------- ### Cache browser binaries Source: https://salamaashoush.github.io/ferridriver/recipes/ci-github-actions.html Persist browser installations between CI runs to reduce build times. ```yaml - name: Cache browsers uses: actions/cache@v4 with: path: ~/.cache/ferridriver key: ${{ runner.os }}-ferridriver-browsers-v1 ``` -------------------------------- ### Configure Rust BDD Test Runner Source: https://salamaashoush.github.io/ferridriver/bdd/running.html Setup the binary entry point and Cargo configuration for running BDD tests via cargo test. ```rust // tests/bdd.rs ferridriver_bdd::bdd_main!(); ``` ```toml # Cargo.toml [[test]] name = "bdd" path = "tests/bdd.rs" harness = false [dev-dependencies] ferridriver-bdd = "0.4" ferridriver-test = "0.4" ``` ```bash cargo test --test bdd -- -j 4 --tags '@smoke and not @wip' ``` -------------------------------- ### Defining BDD Steps in Rust Source: https://salamaashoush.github.io/ferridriver/concepts/migrating-from-playwright.html Example of implementing Gherkin step definitions using Rust macros. ```rust #[given("I navigate to {string}")] async fn navigate(world: &mut World, url: String) { /* ... */ } #[when("I click {string}")] async fn click(world: &mut World, sel: String) { /* ... */ } ``` -------------------------------- ### ES Module Imports Source: https://salamaashoush.github.io/ferridriver/scripting/run-script.html Example of importing internal ferridriver modules and cucumber steps within the sandbox. ```javascript import { commands, fs, vars, tool, tools, bdd } from "ferridriver"; import { Given, When, Then } from "@cucumber/cucumber"; ``` -------------------------------- ### Ferridriver MCP CLI Commands Source: https://salamaashoush.github.io/ferridriver/concepts/migrating-from-playwright.html Various command-line options for starting the Ferridriver MCP server with different transports and backends. ```bash ferridriver mcp # stdio (Claude Code, Cursor, Desktop) ferridriver mcp --transport http --port 8080 # HTTP ferridriver mcp --backend webkit --headless # any backend ferridriver mcp --auto-connect chrome # attach to a running Chrome ``` -------------------------------- ### Run build and test commands Source: https://salamaashoush.github.io/ferridriver/contributing.html Use these commands to verify the workspace, run tests across backends, or build the release binary. ```bash # Type-check the workspace (default-members; ferridriver-node excluded) just check # Format check + clippy + full test suite (matrix across all 4 backends + BDD) just ready # Single backend just test-backend cdp_pipe # or cdp_raw, webkit, bidi # BDD only just bdd tests/features/ # Build the release binary just build ``` -------------------------------- ### Launch browser and navigate in TypeScript Source: https://salamaashoush.github.io/ferridriver/guide/quickstart.html Initialize a browser, navigate to a URL, perform actions, and capture a screenshot. ```typescript import { chromium } from '@ferridriver/node'; const browser = await chromium().launch(); const page = await browser.newPageWithUrl('https://example.com'); await page.locator('#email').fill('test@example.com'); await page.locator('button[type=submit]').click(); await page.waitForUrl('/dashboard'); const png = await page.screenshot({ fullPage: true }); await browser.close(); ``` -------------------------------- ### Build with release-fast profile Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Use this command to reduce build times by approximately 40% compared to the default release profile. ```bash just build-fast ``` -------------------------------- ### Install Ferridriver in Docker Source: https://salamaashoush.github.io/ferridriver/troubleshooting/faq.html Use this Dockerfile configuration to install Ferridriver and its required browser dependencies in a Rust-based container. ```dockerfile FROM rust:1.91-slim RUN apt-get update && apt-get install -y \ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \ libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 \ libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 \ && rm -rf /var/lib/apt/lists/* RUN cargo install ferridriver-cli --locked RUN ferridriver install chromium ``` -------------------------------- ### fetch(input, init?) Source: https://salamaashoush.github.io/ferridriver/scripting/sandbox.html The fetch function is the standard entry point for making network requests, supporting standard Request and Response objects. ```APIDOC ## fetch(input, init?) ### Description Performs a network request using the web-standard fetch API. Supports automatic JSON serialization for objects and multipart/form-data for FormData. ### Parameters - **input** (string|Request) - Required - The URL or Request object to fetch. - **init** (object) - Optional - Configuration object including method, headers, body, and signal. ### Request Example ```javascript const r = await fetch("https://api.example.com/x", { method: "POST", headers: { "content-type": "application/json" }, body: { hello: "world" }, signal: AbortSignal.timeout(5000), }); ``` ``` -------------------------------- ### Launch browser and navigate in Rust Source: https://salamaashoush.github.io/ferridriver/guide/quickstart.html Initialize a Chromium browser, navigate to a page, interact with elements, and take a screenshot. ```rust use ferridriver::browser_type::chromium; use ferridriver::options::LaunchOptions; use ferridriver::url_matcher::UrlMatcher; #[tokio::main] async fn main() -> Result<(), Box> { let browser = chromium().launch(LaunchOptions::default()).await?; let page = browser.page().await?; page.goto("https://example.com").await?; page.locator("#email").fill("test@example.com").await?; page.locator("button[type=submit]").click().await?; page.wait_for_url(UrlMatcher::glob("**/dashboard")?).await?; let png = page.screenshot().await?; std::fs::write("home.png", png)?; browser.close().await?; Ok(()) } ``` -------------------------------- ### Manual tracing Source: https://salamaashoush.github.io/ferridriver/recipes/screenshots-and-traces.html Manually starts and stops tracing for a specific sequence of actions. ```rust page.start_tracing().await?; page.goto("https://app.example.com").await?; page.locator("button.cta").click().await?; page.stop_tracing().await?; // Output goes to launchOptions.traces_dir ``` -------------------------------- ### Configure mobile emulation project-wide Source: https://salamaashoush.github.io/ferridriver/recipes/mobile-emulation.html Define mobile emulation settings in the project configuration file and run tests using the specified project. ```toml [[test.projects]] name = "iphone-15-pro" [test.projects.browser] browser = "webkit" backend = "webkit" [test.projects.browser.useOptions] isMobile = true hasTouch = true userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1" deviceScaleFactor = 3.0 locale = "en-US" [test.projects.browser.viewport] width = 390 height = 844 ``` ```bash cargo test --test e2e -- --project iphone-15-pro ``` -------------------------------- ### Configure video recording Source: https://salamaashoush.github.io/ferridriver/recipes/screenshots-and-traces.html Sets up video recording directory, dimensions, and modes. Requires ffmpeg on the system path. ```toml [test.browser.useOptions.recordVideo] dir = "test-results/videos" size = { width = 1280, height = 720 } ``` ```toml [test.video] mode = "retain-on-failure" # off | on | retain-on-failure ``` -------------------------------- ### ferridriver mcp Source: https://salamaashoush.github.io/ferridriver/cli/ferridriver.html Starts the Model Context Protocol (MCP) server for browser automation. ```APIDOC ## ferridriver mcp ### Description Starts the MCP server to provide browser automation capabilities. Supports various backends and transport modes. ### Options - **--backend** (string) - Optional - cdp-pipe (default), cdp-raw, webkit, or bidi. - **--headless** (boolean) - Optional - Run the browser without a visible window. - **--executable-path** (string) - Optional - Path to a Chrome / Chromium binary. - **--connect** (string) - Optional - WebSocket URL of an already-running browser. - **--auto-connect** (string) - Optional - Discover a running Chrome by channel name. - **--user-data-dir** (string) - Optional - Persistent Chrome profile directory. - **--transport** (string) - Optional - stdio (default) or http. - **--port** (number) - Optional - HTTP port (default 8080). ``` -------------------------------- ### Scraping with Request API Source: https://salamaashoush.github.io/ferridriver/scripting/run-script.html Performs an HTTP GET request and returns the JSON response. ```javascript const r = await request.get(args[0]); if (!r.ok) throw new Error(`HTTP ${r.status}`); return await r.json(); ``` -------------------------------- ### commands.run(name, args) Source: https://salamaashoush.github.io/ferridriver/scripting/capabilities.html Executes a pre-configured command by name with optional variable substitution. ```APIDOC ## commands.run(name, args) ### Description Executes a command defined in the `allow.commands` configuration. The command name must be pre-declared, and variables provided in the arguments object are substituted into the command template. ### Parameters - **name** (string) - Required - The identifier of the command as defined in the configuration. - **args** (object) - Optional - Key-value pairs to substitute into the command template. ### Response - **result** (string|object|array) - The command output, formatted according to the `output` configuration (text, json, or lines). ``` -------------------------------- ### Connect to an existing Chrome instance Source: https://salamaashoush.github.io/ferridriver/troubleshooting/faq.html Connect to a running Chrome browser instance using the command line or the Rust API. ```bash # Start Chrome with remote debugging google-chrome --remote-debugging-port=9222 # Connect ferridriver mcp --connect ws://localhost:9222/devtools/browser/... ``` ```rust use ferridriver::browser_type::chromium; let browser = chromium() .connect("ws://localhost:9222/devtools/browser/...", Default::default()) .await?; ``` -------------------------------- ### CLI Synopsis Source: https://salamaashoush.github.io/ferridriver/cli/ferridriver.html General usage pattern for the ferridriver binary. ```bash ferridriver [GLOBAL FLAGS] [ARGS] ``` -------------------------------- ### Defining Tests with Fixtures Source: https://salamaashoush.github.io/ferridriver/test-runner/rust.html Example of defining tests using the #[ferritest] attribute and injecting fixtures as parameters. ```rust // tests/homepage.rs use ferridriver_test::prelude::*; #[ferritest] async fn loads_homepage(page: Arc) { page.goto("https://example.com").await?; expect(&page).to_have_title("Example Domain").await?; } #[ferritest(retries = 2, tag = "smoke")] async fn login_flow(page: Arc, request: Arc) { request.post("/api/seed").await?; page.goto("https://app.example.com/login").await?; page.locator("#email").fill("user@example.com").await?; page.locator("button[type=submit]").click().await?; expect(&page).to_have_url("/dashboard").await?; } ``` -------------------------------- ### Handle multiple authentication roles Source: https://salamaashoush.github.io/ferridriver/recipes/login-and-auth-state.html Configure different storage state files for various user roles. ```text .auth/ admin.json editor.json viewer.json ``` ```toml [[test.projects]] name = "admin" [test.projects.browser.useOptions] storageState = ".auth/admin.json" [[test.projects]] name = "editor" [test.projects.browser.useOptions] storageState = ".auth/editor.json" ``` ```bash cargo test --test e2e -- --project admin cargo test --test e2e -- --project editor ``` -------------------------------- ### Connect to Chrome via cdp-raw Source: https://salamaashoush.github.io/ferridriver/concepts/backends.html Demonstrates launching a new browser or attaching to an existing Chrome instance using the WebSocket transport. ```rust use ferridriver::browser_type::{chromium, BrowserType}; use ferridriver::options::{BrowserTypeOptions, ChromiumTransport}; // launch let browser = BrowserType::chromium_with(&BrowserTypeOptions { transport: Some(ChromiumTransport::Ws), ..Default::default() }).launch(Default::default()).await?; // attach let browser = chromium() .connect("ws://localhost:9222/devtools/browser/abcd-1234", Default::default()) .await?; ``` -------------------------------- ### run_script Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Executes JavaScript in a sandboxed QuickJS runtime against the current session. ```APIDOC ## run_script ### Description Executes JavaScript in a sandboxed QuickJS runtime against the current session. The script can interact with the browser page, file system, and session-scoped variables. ### Parameters - **source** (string) - Optional - Inline JavaScript code to execute. Provide either this or 'path'. - **path** (string) - Optional - Relative path to a .js/.mjs file under script_root. Provide either this or 'source'. - **args** (array) - Optional - Positional arguments accessible within the script via the 'args' global. - **timeout_ms** (number) - Optional - Execution timeout in milliseconds (default: 300000). - **memory_limit_mb** (number) - Optional - Memory limit in MiB (default: 256). - **session** (string) - Optional - Session identifier (default: 'default'). ### Request Example { "source": "await page.goto(args[0]); return await page.title();", "args": ["https://example.com"], "timeout_ms": 30000, "memory_limit_mb": 256, "session": "default" } ### Response #### Success Response - **status** (string) - 'ok' - **value** (any) - The JSON-serialized return value of the script. - **duration_ms** (number) - Execution duration in milliseconds. - **console** (array) - Captured console logs. #### Failure Response - **status** (string) - 'error' - **error** (object) - Details regarding the failure (kind, message, stack, line, column, source_snippet). - **duration_ms** (number) - Execution duration in milliseconds. - **console** (array) - Captured console logs. ``` -------------------------------- ### Persist Data with globalThis and vars Source: https://salamaashoush.github.io/ferridriver/scripting/state-and-sessions.html Demonstrates using globalThis for temporary caching and vars for persistent storage across VM resets. ```javascript // First call — discover, cache, persist const token = await page.evaluate(() => localStorage.token); globalThis.parsed = parseSomethingExpensive(); vars.set("auth_token", token); return "ready"; // Later call in the same session const token = vars.get("auth_token"); // always present const parsed = globalThis.parsed; // present unless VM reset ``` -------------------------------- ### Resolve WebKit Binary Issues Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Commands to download WebKit or configure an override path for the binary. ```bash # Download into the ferridriver cache ferridriver install webkit # Or install via Playwright (one-time) npx playwright install webkit # Or set the override export FERRIDRIVER_WEBKIT=/path/to/playwright/webkit-XXXX/ ``` -------------------------------- ### Project Matrix Configuration Source: https://salamaashoush.github.io/ferridriver/test-runner/config.html Define multiple test projects to run against different browser backends. ```toml [[test.projects]] name = "chromium" [test.projects.browser] browser = "chromium" [[test.projects]] name = "firefox" [test.projects.browser] browser = "firefox" backend = "bidi" [[test.projects]] name = "webkit" [test.projects.browser] browser = "webkit" backend = "webkit" ``` -------------------------------- ### Execute a configured command Source: https://salamaashoush.github.io/ferridriver/scripting/capabilities.html Run a pre-defined command using the commands module. ```javascript import { commands } from "ferridriver"; const sha = await commands.run("headSha"); ``` -------------------------------- ### Connect and interact with a sidecar process Source: https://salamaashoush.github.io/ferridriver/scripting/sidecars.html Demonstrates connecting to a sidecar, performing requests, handling events, and closing the connection. ```javascript const sc = await sidecars.connect("formatter"); // Request / response: send a method + optional params, await the result. const result = await sc.send("format", { code, language: "rust" }); // Many at once: issue a batch in a single call, results returned in order. const [a, b] = await sc.sendMany([ { method: "format", params: { code: codeA, language: "rust" } }, { method: "format", params: { code: codeB, language: "rust" } }, ]); // Pushed events: the child can write id-less frames at any time. const off = sc.on("progress", (params) => { console.log("progress", params.percent); }); // Wait for the next single event. const summary = await sc.once("done"); off(); // remove that one listener sc.off("progress"); // or remove every listener for an event await sc.close(); // stop the pump, close the pipe, reap the child ``` -------------------------------- ### Scripting Pipeline Visualization Source: https://salamaashoush.github.io/ferridriver/scripting/overview.html A diagram illustrating the compilation and execution flow from source files to the Rust ExtensionRegistry. ```text source files (.js / .ts / .mjs / .tsx / ...) │ ▼ rolldown (TypeScript + node_modules + tree-shake, Platform::Neutral, OutputFormat::Esm) │ ▼ QuickJS bytecode (in-memory, content-hash cached) │ ▼ Module::load per session VM (no re-parse, no resolver — imports already inlined) │ ▼ top-level Given() / tool() side effects populate the Rust ExtensionRegistry ``` -------------------------------- ### navigate Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Navigates to a specified URL and returns an accessibility snapshot. ```APIDOC ## navigate ### Description Navigates the browser to a URL and returns a fresh accessibility snapshot. ### Parameters - **url** (string) - Required - The URL to navigate to. - **wait_until** (string) - Optional - Wait condition: 'commit', 'load', 'domcontentloaded', 'networkidle', or 'none' (default: 'commit'). - **session** (string) - Optional - Session identifier (default: "default"). ``` -------------------------------- ### CLI Flags Reference Source: https://salamaashoush.github.io/ferridriver/bdd/running.html Available command-line arguments for configuring the BDD test execution. ```text --steps GLOB JS / TS step files (repeatable) --tags EXPR tag filter: @smoke and not @wip, etc. --workers N parallel workers (default: CPU count) --reporter NAME reporter name (repeatable) --strict treat undefined / pending steps as failures --dry-run parse + report scenarios without executing --fail-fast stop after first failure --step-timeout MS override per-step timeout --order MODE defined | random | random:SEED --language LANG default Gherkin keyword language (en, de, fr, ...) --shard X/N run shard X of N across CI machines --world-parameters JSON pass JSON object to this.parameters ``` -------------------------------- ### Configure mobile emulation per-test Source: https://salamaashoush.github.io/ferridriver/recipes/mobile-emulation.html Use the browser context builder to set mobile-specific options like viewport size, user agent, and touch support for an individual test. ```rust use ferridriver_test::prelude::*; use ferridriver::options::ViewportOption; #[ferritest] async fn mobile_layout(browser: Arc) { let context = browser.new_context() .viewport(ViewportOption::Size { width: 390, height: 844 }) .device_scale_factor(3.0) .mobile(true) .has_touch(true) .user_agent( "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) \ AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 \ Mobile/15E148 Safari/604.1", ) .locale("en-US") .await?; let page = context.new_page().await?; page.goto("https://example.com").await?; expect(&page.locator(".mobile-nav")).to_be_visible().await?; } ``` -------------------------------- ### Configure Browser Paths Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Set the browser cache path or specify an existing executable path to avoid download issues. ```bash FERRIDRIVER_BROWSERS_PATH=/path/to/your/cache ferridriver mcp ``` ```rust LaunchOptions { executable_path: Some("/usr/bin/chromium".into()), .. } ``` -------------------------------- ### Minimal GitHub Actions workflow Source: https://salamaashoush.github.io/ferridriver/recipes/ci-github-actions.html A complete workflow template for running tests with sharding, caching, and artifact collection. ```yaml # .github/workflows/e2e.yml name: e2e on: push: branches: [main] pull_request: jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: shard: [1/4, 2/4, 3/4, 4/4] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} - name: Install ferridriver run: cargo install ferridriver-cli --locked - name: Install browsers run: ferridriver install --with-deps chromium - name: Run tests run: | cargo test --test e2e --release -- \ --shard ${{ matrix.shard }} \ --retries 1 - name: Upload JUnit if: always() uses: actions/upload-artifact@v4 with: name: junit-${{ strategy.job-index }} path: test-results/junit.xml - name: Upload failure artifacts if: failure() uses: actions/upload-artifact@v4 with: name: artifacts-${{ strategy.job-index }} path: | test-results/**/*.png test-results/**/*.webm test-results/**/trace.zip retention-days: 7 ``` -------------------------------- ### Configure Global BDD Settings Source: https://salamaashoush.github.io/ferridriver/scripting/bdd-js-api.html Set default timeouts and function wrappers for step execution. ```javascript setDefaultTimeout(10000); // ms; per-registry default setDefinitionFunctionWrapper((fn) => fn); // wrap every step body (retry, trace) setParallelCanAssign((/* ignored */) => true); // accepted but inert ``` -------------------------------- ### Configure Claude Desktop and Cursor Source: https://salamaashoush.github.io/ferridriver/mcp/setup.html JSON configuration for the Claude Desktop or Cursor settings file to register the Ferridriver MCP server. ```json { "mcpServers": { "ferridriver": { "command": "ferridriver", "args": ["mcp"] } } } ``` ```json { "mcpServers": { "ferridriver": { "command": "ferridriver", "args": ["mcp", "--backend", "webkit", "--headless"] } } } ``` -------------------------------- ### Configure color scheme and contrast Source: https://salamaashoush.github.io/ferridriver/recipes/mobile-emulation.html Override media features like color scheme, contrast, and reduced motion at the context or page level. ```rust use ferridriver::options::MediaOverride; let context = browser.new_context() .color_scheme(MediaOverride::Set("dark".into())) .contrast(MediaOverride::Set("more".into())) .reduced_motion(MediaOverride::Set("reduce".into())) .await?; ``` ```rust use ferridriver::options::MediaOverride; page.emulate_media() .color_scheme(MediaOverride::Set("dark".into())) .await?; ``` -------------------------------- ### Capture page screenshots Source: https://salamaashoush.github.io/ferridriver/recipes/screenshots-and-traces.html Demonstrates capturing full page screenshots and configuring JPEG format with quality settings. ```rust use ferridriver::options::ScreenshotFormat; let png = page.screenshot().await?; std::fs::write("home.png", png).map_err(|e| e.to_string())?; // Full page (scrolling capture) let png = page.screenshot().full_page(true).await?; // JPEG with quality let jpg = page.screenshot() .format(ScreenshotFormat::Jpeg) .quality(80) .await?; ``` -------------------------------- ### Project Layout Structure Source: https://salamaashoush.github.io/ferridriver/test-runner/rust.html Recommended directory structure for a ferridriver Rust project. ```text my-project/ ├── Cargo.toml ├── ferridriver.toml # optional, auto-discovered └── tests/ ├── harness.rs # main!() — one per test binary ├── homepage.rs └── login.rs ``` -------------------------------- ### Configure Rust dependencies Source: https://salamaashoush.github.io/ferridriver/guide/quickstart.html Add the necessary dependencies to your Cargo.toml file. ```toml # Cargo.toml [dependencies] ferridriver = "0.4" tokio = { version = "1", features = ["full"] } ``` -------------------------------- ### Build and test Node bindings Source: https://salamaashoush.github.io/ferridriver/contributing.html Commands to manage the Node.js binding located in the crates/ferridriver-node directory. ```bash cd crates/ferridriver-node bun install bun run build:debug bun test ``` -------------------------------- ### Set Firefox Executable Path Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Configure the executable path in LaunchOptions if Firefox is not found on the system PATH. ```rust LaunchOptions { executable_path: Some("/usr/bin/firefox".into()), ..Default::default() } ``` -------------------------------- ### Import Modules in Step Files Source: https://salamaashoush.github.io/ferridriver/scripting/bdd-js-api.html Use standard import syntax for local helpers, TypeScript files, and bundled node_modules. ```typescript import { helper } from "./helpers.js"; // resolved by rolldown import * as utils from "../shared/utils.ts"; // TS imports work import semver from "semver"; // node_modules bundled ``` -------------------------------- ### Allow environment variables in scripts Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Specify allowed environment variable keys in the configuration file, as process.env is empty by default. ```toml [scripting] allowEnv = ["HOME", "TZ", "DATABASE_URL"] ``` -------------------------------- ### Execute a script with run_script Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Use the source parameter to provide inline JavaScript or path for a file. Arguments are passed via the args array to prevent injection. ```json { "source": "await page.goto(args[0]); return await page.title();", "args": ["https://example.com"], "timeout_ms": 30000, // optional; default 5 minutes "memory_limit_mb": 256, // optional; default 256 MiB "session": "default" // optional } ``` -------------------------------- ### Configure allowed commands Source: https://salamaashoush.github.io/ferridriver/scripting/capabilities.html Define commands in the configuration file using a spec object to specify execution details. ```toml [scripting.allow.commands] headSha = { run = ["git", "rev-parse", "HEAD"], output = "text" } ``` -------------------------------- ### Configure Ferridriver Extensions Source: https://salamaashoush.github.io/ferridriver/scripting/extensions.html Define extensions, environment variables, and test step locations in the ferridriver.toml configuration file. ```toml # ESM packages, package subpaths, files, or directories. Used by the # MCP server (tools) AND, bundled alongside BDD step files, by the test # runner (steps). extensions = ["@acme/ferridriver-box", "@acme/ferridriver-box/login", "./extensions", "./tools/box-login.ts"] [scripting] # Sandbox relaxations — default-deny, like allow.net. # Names a script may read via process.env (intersected with the real # environment; absent names stay absent — never invented). Empty ⇒ # process.env is {}. allowEnv = ["HOME", "TZ"] [test] # JS/TS step-definition globs. Defaults to steps/**/*.{js,ts} and # step_definitions/**/*.{js,ts} when empty. steps = ["features/steps/**/*.ts"] ``` -------------------------------- ### Define Doc Strings in Feature Files Source: https://salamaashoush.github.io/ferridriver/scripting/bdd-js-api.html Pass multi-line strings as arguments to step definitions using triple-quote blocks. ```gherkin When I send this JSON: """json { "name": "Ada", "role": "admin" } """ ``` -------------------------------- ### Configure Sandbox Options for Linux Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Disable the SUID sandbox in LaunchOptions to prevent crashes on Linux environments. ```rust LaunchOptions { args: vec!["--no-sandbox".into(), "--disable-setuid-sandbox".into()], ..Default::default() } ``` -------------------------------- ### Open a new tab in Rust Source: https://salamaashoush.github.io/ferridriver/recipes/multiple-tabs.html Use context.new_page() to open a fresh tab that shares cookies and storage with the existing context. ```rust use ferridriver_test::prelude::*; #[ferritest] async fn checkout_in_new_tab(context: Arc) { // Open a fresh tab in the same context (shared cookies/storage) let second = context.new_page().await?; second.goto("https://app.example.com/cart").await?; expect(&second.locator(".cart-total")).to_have_text("$42.00").await?; second.close().await?; } ``` -------------------------------- ### Configure browser projects in ferridriver.toml Source: https://salamaashoush.github.io/ferridriver/concepts/backends.html Define test projects with specific browser and backend configurations for CI or local execution. ```toml # ferridriver.toml [[test.projects]] name = "chromium" [test.projects.browser] browser = "chromium" [[test.projects]] name = "firefox" [test.projects.browser] browser = "firefox" backend = "bidi" [[test.projects]] name = "webkit" [test.projects.browser] browser = "webkit" backend = "webkit" ``` -------------------------------- ### Configure CI test profile Source: https://salamaashoush.github.io/ferridriver/troubleshooting/index.html Adjust timeout and worker settings for CI environments to prevent failures due to CPU contention. ```toml [test.profiles.ci] timeout = 60000 expectTimeout = 10000 workers = 2 ``` -------------------------------- ### Running BDD Tests Source: https://salamaashoush.github.io/ferridriver/concepts/migrating-from-playwright.html Command-line usage for executing BDD tests with either native Rust steps or bundled JS/TS steps. ```bash # Before (playwright-bdd): bddgen + npx playwright test # After: ferridriver bdd tests/features/ # Rust steps ferridriver bdd --steps 'steps/**/*.{js,ts}' tests/features/ # JS/TS steps ``` -------------------------------- ### snapshot Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Returns an LLM-optimized tree of the current page for accessibility and navigation purposes. ```APIDOC ## snapshot ### Description Returns an LLM-optimized tree of the current page. Note that references are tied to the specific snapshot; any navigation or DOM-mutating actions will invalidate them, requiring a new snapshot. ``` -------------------------------- ### Configure storage state in ferridriver.toml Source: https://salamaashoush.github.io/ferridriver/recipes/login-and-auth-state.html Apply the saved authentication state globally or per project. ```toml # ferridriver.toml [test] storageState = ".auth/admin.json" ``` ```toml [[test.projects]] name = "authed" [test.projects.browser.useOptions] storageState = ".auth/admin.json" ``` -------------------------------- ### ferridriver_extensions Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Lists extensions loaded at server startup to discover available plugin tools and audit declared capabilities. ```APIDOC ## ferridriver_extensions ### Description Lists extensions loaded at server startup. Use this to discover available plugin tools and audit declared capabilities. ### Parameters - **include_schema** (boolean) - Optional - When true, returns each tool's full JSON inputSchema. Defaults to false. ``` -------------------------------- ### Share State via Module Imports Source: https://salamaashoush.github.io/ferridriver/scripting/state-and-sessions.html Demonstrates sharing state between different tools by importing a common module instance. ```typescript // shared/state.ts export const cache = new Map(); // extension-a.ts import { cache } from "./shared/state.js"; import { tool } from "ferridriver"; tool({ name: "a.read", handler: () => cache.get("key") }); // extension-b.ts import { cache } from "./shared/state.js"; import { tool } from "ferridriver"; tool({ name: "b.write", handler: ({ args }) => cache.set("key", args.value) }); ``` -------------------------------- ### Capture and save downloads Source: https://salamaashoush.github.io/ferridriver/recipes/file-upload-download.html Wait for the download event after triggering a download, then process the file or save it to a specific path. ```rust page.locator("a.download-csv").click().await?; let download = page.wait_for_download(30_000).await?; let path = download.path().await?; let bytes = std::fs::read(&path).map_err(|e| e.to_string())?; assert!(bytes.starts_with(b"name,score")); ``` ```rust download.save_as(std::path::Path::new("test-results/report.csv")).await?; ``` -------------------------------- ### Generate Code with Codegen Source: https://salamaashoush.github.io/ferridriver/cli/ferridriver.html Command to open a headed browser, record interactions, and output the generated code. ```bash ferridriver codegen [--output rec.ts] [--language ts|rust|gherkin] ``` -------------------------------- ### Configure Rust BDD entry point Source: https://salamaashoush.github.io/ferridriver/bdd/overview.html Register the BDD test runner in a Rust test file. ```rust // tests/bdd.rs ferridriver_bdd::bdd_main!(); ``` -------------------------------- ### Configure logging with RUST_LOG Source: https://salamaashoush.github.io/ferridriver/cli/ferridriver.html Sets the standard tracing filter for the application. ```bash RUST_LOG=warn,ferridriver::cdp=trace ``` -------------------------------- ### connect Source: https://salamaashoush.github.io/ferridriver/mcp/tools.html Attaches to a running Chrome instance using a debugger URL or auto-discovery. ```APIDOC ## connect ### Description Attaches to a running Chrome instance. ### Parameters - **url** (string) - Optional - Debugger URL to connect to. - **auto_discover** (boolean) - Optional - Whether to automatically discover the Chrome instance. - **channel** (string) - Optional - Browser channel (default: "stable"). - **user_data_dir** (string) - Optional - Path to the user data directory. - **session** (string) - Optional - Session identifier (default: "default"). ``` -------------------------------- ### Configure Playwright-compatible traces Source: https://salamaashoush.github.io/ferridriver/recipes/screenshots-and-traces.html Sets up trace retention policies and provides the command to view traces using the Playwright viewer. ```toml [test] trace = "retain-on-failure" ``` ```bash npx playwright show-trace test-results/login-flow/trace.zip ```