### Raw Protocol Usage Example Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/server-protocol.md Demonstrates how to interact with the Odiff server using raw protocol commands in a bash environment. This includes starting the server, sending requests, and reading responses. ```bash # Start server odiff --server # Read ready signal # {"ready":true} # Send request echo '{"requestId":1,"base":"a.png","compare":"b.png","output":"diff.png","options":{}}' # Read response # {"requestId":1,"match":false,"reason":"pixel-diff","diffCount":1234,"diffPercentage":2.5} # Send another request echo '{"requestId":2,"base":"c.png","compare":"d.png","output":"diff2.png","options":{"threshold":0.1}}' # Read response # {"requestId":2,"match":true} ``` -------------------------------- ### Install ODiff Binary Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Install the ODiff binary for command-line image comparison. ```bash # Remove ImageMagick # (no npm package, usually system-wide) # Install ODiff npm install odiff-bin ``` -------------------------------- ### Install and Verify ODiff Binary Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/errors-and-handling.md Installs the 'odiff-bin' package and verifies the installation by checking the version. Use this when encountering 'odiff binary not found' errors. ```bash npm install odiff-bin npx odiff --version ``` -------------------------------- ### Install odiff-bin Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Ensure odiff-bin is installed in your project. This command installs the package and verifies the installation. ```bash # Make sure it's installed npm install odiff-bin # Check installation npx odiff --version ``` -------------------------------- ### Install ODiff CLI Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Installs the native binary and JavaScript bindings for ODiff. Recommended for most Node.js projects. ```bash npm install odiff-bin ``` -------------------------------- ### Install Cypress-ODiff Plugin Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Install the Cypress ODiff plugin using npm. ```bash npm install cypress-odiff ``` -------------------------------- ### ODiff Environment Setup Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Run tests directly; snapshots are stored in the local git repository. ```bash npm test # Snapshots stored in local git repo ``` -------------------------------- ### Benchmark Calculation Example Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md This example demonstrates a calculation for potential CI time savings based on image comparison speed. ```plaintext 3s * 25000 / 3600 = 20,83333 hours ``` -------------------------------- ### Increase Server Start Timeout Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/errors-and-handling.md Increases the server start timeout to 30 seconds, useful in CI environments where startup may be slower. Addresses 'Server failed to start within 5 seconds' errors. ```javascript // Increase timeout in CI const server = new ODiffServer(); await server.compare(base, compare, diff, { timeout: 30000 }); ``` -------------------------------- ### Install hyperfine on macOS Source: https://github.com/dmtrkovalenko/odiff/blob/main/images/README.md Use Homebrew to install the hyperfine benchmarking tool on macOS. ```bash brew install hyperfine ``` -------------------------------- ### Install odiff-bin via npm Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Install the odiff-bin package using npm. This command ensures that the correct binary is linked for your platform. ```bash npm install odiff-bin ``` -------------------------------- ### Install playwright-odiff Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/playwright-odiff/README.md Install the package using npm. This is the first step to integrating the faster screenshot matcher. ```bash npm install playwright-odiff ``` -------------------------------- ### ODiffServer Usage Example Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Demonstrates how to use the ODiffServer for multiple image comparisons, including optional timeouts and server lifecycle management. ```typescript const server = new ODiffServer(); const result1 = await server.compare('a.png', 'b.png', 'diff1.png'); // add optional timeout to catch any possible crashes on the server side: const result2 = await server.compare('c.png', 'd.png', 'diff2.png', { threshold: 0.3, timeout: 5000 }); server.stop(); ``` -------------------------------- ### Playwright Integration Setup Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Integrate ODiff with Playwright for screenshot testing. Importing the setup module enables the `toHaveScreenshotOdiff` assertion. ```typescript // in your setup file or test entrypoint import "playwright-odiff/setup"; expect(page).toHaveScreenshotOdiff("screenshot-name", { /* any odiff and playwright options */ }); ``` -------------------------------- ### ODiffServer Constructor Source: https://github.com/dmtrkovalenko/odiff/blob/main/README.md Initializes a new ODiffServer instance. The server starts its initialization process in the background upon creation. ```APIDOC ## ODiffServer Constructor ### Description Creates a new ODiffServer instance. Server initialization begins immediately in the background. ### Signature ```typescript constructor(binaryPath?: string) ``` ### Parameters - **binaryPath** (string) - Optional - Path to the odiff binary. Defaults to the bundled binary. ``` -------------------------------- ### Batch Processing with ODiffServer Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Use ODiffServer for batch comparisons to significantly improve performance. This example demonstrates setting up the server and performing multiple comparisons. ```javascript const { ODiffServer } = require("odiff-bin"); // Setup const server = new ODiffServer(); // 10 comparisons for (let i = 0; i < 10; i++) { const start = Date.now(); await server.compare(`a${i}.png`, `b${i}.png`, `diff${i}.png`); console.log(`Comparison ${i}: ${Date.now() - start}ms`); } server.stop(); // Results: ~50-100ms per comparison (vs 1200ms per process) // Speedup: 12-24x vs process mode ``` -------------------------------- ### Image Comparison with Options Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-compare.md Configure the comparison behavior by providing an options object. This example demonstrates setting a threshold for pixel differences, enabling antialiasing, and limiting the maximum number of differing pixels. ```javascript const result = await compare( "baseline.png", "screenshot.png", "diff.png", { threshold: 0.1, antialiasing: true, maxDiffPixels: 100, }, ); ``` -------------------------------- ### odiff JSON Request Example Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Example of a client request sent to the odiff server, formatted as a single line of JSON. ```json {"requestId":1,"base":"a.png",...} ``` -------------------------------- ### Install ODiff and Uninstall pixelmatch Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Use npm to remove pixelmatch and install odiff-bin. ```bash # Remove pixelmatch npm uninstall pixelmatch # Install odiff npm install odiff-bin ``` -------------------------------- ### Import Playwright Odiff Setup Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-playwright-matcher.md Import this setup file in your Playwright configuration or test file to extend Playwright's expect with the toHaveScreenshotOdiff matcher. ```typescript // In your test setup file or playwright.config.ts import "playwright-odiff/setup"; ``` -------------------------------- ### Manual Setup for playwright-odiff Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/playwright-odiff/README.md Alternatively, manually extend the expect matcher by importing the necessary functions and types. This provides more control over the setup. ```typescript import { expect } from "@playwright/test"; import { toHaveScreenshotOdiff } from "playwright-odiff/toHaveScreenshotOdiff"; import "playwright-odiff/types"; expect.extend({ toHaveScreenshotOdiff, }); ``` -------------------------------- ### Percy Environment Setup Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Set the PERCY_TOKEN environment variable and run tests using 'percy exec'. ```bash export PERCY_TOKEN=... npx percy exec -- npm test ``` -------------------------------- ### Install Playwright ODiff Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Installs the necessary packages for integrating ODiff with Playwright for visual regression testing. ```bash npm install playwright-odiff @playwright/test ``` -------------------------------- ### odiff JSON Response Example Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Example of a server response to a client request, formatted as a single line of JSON. ```json {"requestId":1,"match":true} ``` -------------------------------- ### Combined Screenshot Configuration Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/configuration.md Example demonstrating a comprehensive configuration combining multiple screenshot options for a complex component test. Requires 'playwright-odiff/setup'. ```typescript await expect(page).toHaveScreenshotOdiff({ name: "complex-component", fullPage: true, mask: [page.locator(".timestamp")], maxDiffPixels: 50, threshold: 0.15, antialiasing: true, animations: "disabled", timeout: 10000, stylePath: "./test-styles.css", }); ``` -------------------------------- ### Cypress Visual Test Structure Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Example of a complete visual test suite structure using Cypress and ODiff. ```javascript describe("visual tests", () => { it("button looks correct", () => { cy.visit("https://example.com"); cy.get("button.primary").compareSnapshot("primary-button"); }); }); ``` -------------------------------- ### Setup playwright-odiff in Playwright tests Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/playwright-odiff/README.md Add this import to your top-level Playwright setup script to extend the expect matcher. ```typescript import "playwright-odiff/setup" ``` -------------------------------- ### Handle Server Initialization Failure Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/errors-and-handling.md Catch errors related to the ODiff server failing to start or become ready within the expected timeframe. This is useful for diagnosing startup issues. ```javascript try { const server = new ODiffServer(); await server.compare("a.png", "b.png", "diff.png"); } catch (error) { if (error.message.includes("Failed to start odiff server")) { console.error("Server startup failed:", error.message); } if (error.message.includes("server failed to start within 5 seconds")) { console.error("Server initialization timeout"); } } ``` -------------------------------- ### ODiff Snapshot Code Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Import the setup and use expect(page).toHaveScreenshotOdiff for visual regression testing. ```typescript import "playwright-odiff/setup"; await page.goto("https://example.com"); await expect(page).toHaveScreenshotOdiff("home-page"); ``` -------------------------------- ### ODiff CLI Server Mode Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Start ODiff in server mode for efficient bulk operations. This mode is recommended for comparing a large number of images. ```bash # Server mode odiff --server ``` -------------------------------- ### Automate .toHaveScreenshot() to .toHaveScreenshotOdiff() replacement Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/playwright-odiff/README.md Use sed to automatically update existing test files, replacing calls to .toHaveScreenshot() with .toHaveScreenshotOdiff(). Ensure GNU sed is installed on macOS. ```bash # if you are on macos already install GNU sed: brew install gnu-sed sed -i -E 's/(await expect\([^)]*\))(\x2e not)?\.toHaveScreenshot\(/\1\2.toHaveScreenshotOdiff(/g' ./**/*.spec.ts ``` -------------------------------- ### Reinstall odiff-bin Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md If the 'odiff binary not found' error occurs, try reinstalling the odiff-bin package and rebuilding it. You can also verify the binary installation by running `npx odiff --version`. ```bash # Reinstall with build scripts npm install odiff-bin npm rebuild odiff-bin # Or verify binary exists npx odiff --version ``` -------------------------------- ### Run Simple Image Difference Benchmark Source: https://github.com/dmtrkovalenko/odiff/blob/main/images/README.md Compares the performance of odiff, pixelmatch, and ImageMagick's compare for generating a diff image between two input images. Ensure all tools are installed and accessible in your PATH. ```bash hyperfine -i 'odiff water-4k.png water-4k-2.png water-diff.png' 'pixelmatch water-4k.png water-4k-2.png water-diff.png' 'compare water-4k.png water-4k-2.png -compose src water-diff.png' ``` -------------------------------- ### odiff Server Mode Execution Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md Start the odiff server for persistent readline-JSON protocol communication. This mode allows for continuous image comparison requests. ```bash odiff --server ``` -------------------------------- ### Binary Server Mode Communication Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Interact with the ODiff binary in server mode using a JSON-based stdio protocol. This example shows the server readiness signal and a request/response cycle. ```bash odiff --server $ odiff --server {"ready":true} # ready signal # your input {"requestId":1,"base":"images/www.cypress.io.png","compare":"images/www.cypress.io-1.png","output":"images/www.cypress-diff.png"} # server response {"requestId":1,"match":false,"reason":"pixel-diff","diffCount":1090946,"diffPercentage":2.95} ``` -------------------------------- ### Handle Server Process Crashes Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Implement error handling and retry logic for server process crashes. This example catches errors, checks for specific messages, and restarts the server if necessary. ```javascript // Add error handling and retry logic try { const result = await server.compare("a.png", "b.png", "diff.png"); } catch (error) { if (error.message.includes("Server process terminated")) { console.log("Server crashed, restarting..."); server.stop(); // Next call will reinitialize } } ``` -------------------------------- ### Error Handling for Comparisons Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Implement robust error handling for image comparisons using a try-catch block. This example shows how to catch potential errors during comparison, such as timeouts or server issues, and log them. It also demonstrates accessing detailed diff information when a pixel difference is detected. ```typescript const server = new ODiffServer(); try { const result = await server.compare( "baseline.png", "screenshot.png", "diff.png", { timeout: 5000 }, ); if (!result.match && result.reason === "pixel-diff") { console.log(`${result.diffCount} pixels differ`); } } catch (error) { console.error(`Comparison failed: ${error.message}`); } finally { server.stop(); } ``` -------------------------------- ### Initialize ODiffServer with Custom Binary Path Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Use this snippet to initialize the ODiffServer when you need to use a different binary version or a custom fork of ODiff. ```javascript new ODiffServer("/path/to/custom/odiff"); ``` -------------------------------- ### Server Startup Ready Signal Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/server-protocol.md Upon successful startup, the ODiffServer outputs a JSON object indicating it is ready to accept requests. ```APIDOC ## Server Startup Ready Signal Upon successful startup, the server outputs: ```json { "ready": true } ``` This indicates the server is ready to accept comparison requests. ``` -------------------------------- ### Install ODiff and Uninstall Percy Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Use npm to remove Percy packages and install the playwright-odiff package. ```bash npm uninstall @percy/cli @percy/playwright npm install playwright-odiff ``` -------------------------------- ### View odiff-bin CLI Help Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Run this command in your terminal to see all available options and arguments for the odiff-bin CLI. ```bash odiff --help ``` -------------------------------- ### Instantiate ODiffServer Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Create a new ODiffServer instance. Initialization happens in the background and the server is ready for use immediately. It automatically waits for initialization on the first compare call. ```typescript const { ODiffServer } = require("odiff-bin"); const server = new ODiffServer(); // Server is automatically initializing in the background // Safe to start using immediately - it auto-waits for initialization const result = await server.compare("a.png", "b.png", "diff.png"); ``` -------------------------------- ### ODiff CLI Help Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Display the full help information for the ODiff command-line interface to explore all available options and commands. ```bash odiff --help ``` -------------------------------- ### Server Ready Signal Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/server-protocol.md Upon successful startup, the server emits a JSON object indicating it is ready to receive requests. ```json {"ready":true} ``` -------------------------------- ### ODiff Server Comparison using File Paths Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Use file paths for image comparison with the ODiff server for optimal performance. This is faster than passing image buffers. ```javascript // Fast: File paths await server.compare("baseline.png", "screenshot.png", "diff.png"); // Slower: Buffer copying const baseBuf = fs.readFileSync("baseline.png"); const compareBuf = fs.readFileSync("screenshot.png"); await server.compareBuffers(baseBuf, "png", compareBuf, "png", "diff.png"); ``` -------------------------------- ### Initialize ODiffServer and Compare Buffers Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Compares two PNG image buffers. Ensure 'baseline.png' and 'screenshot.png' exist in the same directory. The comparison result will be saved to 'diff.png'. ```typescript const { ODiffServer } = require("odiff-bin"); const fs = require("fs"); const server = new ODiffServer(); const baseBuffer = fs.readFileSync("baseline.png"); const compareBuffer = fs.readFileSync("screenshot.png"); const result = await server.compareBuffers( baseBuffer, "png", compareBuffer, "png", "diff.png", ); ``` -------------------------------- ### Playwright Test with toHaveScreenshotOdiff Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md Use the toHaveScreenshotOdiff assertion within a Playwright test after importing the necessary setup and function. ```typescript await expect(page).toHaveScreenshotOdiff("snapshot-name"); ``` -------------------------------- ### odiff-bin File Organization Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md Illustrates the directory structure of the odiff-bin npm package, showing key files and the location of the native binary. ```tree npm_packages/odiff-bin/ ├── odiff.js # Compare function implementation ├── server.js # ODiffServer implementation ├── odiff.d.ts # TypeScript type definitions ├── package.json # Package metadata ├── post_install.js # Binary setup script └── bin/ └── odiff.exe # Native binary (platform-specific) ``` -------------------------------- ### Playwright Visual Test Structure Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Example of a complete visual test suite structure using Playwright and ODiff. ```typescript import { test, expect } from "@playwright/test"; import "playwright-odiff/setup"; test.describe("visual tests", () => { test("button looks correct", async ({ page }) => { await page.goto("https://example.com"); await expect(page.locator("button.primary")) .toHaveScreenshotOdiff("primary-button"); }); }); ``` -------------------------------- ### Manual Image Comparison Workflow Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/migration-guide.md Illustrates a manual workflow involving creating a baseline, taking a screenshot, and manually comparing/updating the baseline. ```javascript // 1. Create baseline fs.copyFileSync("screenshot.png", "baseline.png"); // 2. Run test/script runApplication(); takeScreenshot("screenshot.png"); // 3. Manual comparison // Open in Photoshop/GIMP // Visually inspect differences // Manually document findings // 4. Update baseline if correct fs.copyFileSync("screenshot.png", "baseline.png"); ``` -------------------------------- ### Register Custom Matcher Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md Import the setup module to register the toHaveScreenshotOdiff custom matcher with Playwright's expect global. ```typescript import "playwright-odiff/setup"; ``` -------------------------------- ### ODiffServer Constructor Source: https://github.com/dmtrkovalenko/odiff/blob/main/README.md Shows the basic instantiation of the `ODiffServer` class. The constructor can optionally accept a path to the odiff binary if it's not in the default bundled location. ```typescript /** * Create a new ODiffServer instance * Server initialization begins immediately in the background * @param binaryPath - Optional path to odiff binary (defaults to bundled binary) */ export declare class ODiffServer { constructor(binaryPath?: string); /** * Compare two images using the persistent server * Automatically waits for server initialization if needed * @param basePath - Path to base image * @param comparePath - Path to comparison image * @param diffOutput - Path to output diff image * @param options - Comparison options with optional timeout for request * @returns Promise resolving to comparison result */ compare( basePath: string, comparePath: string, diffOutput: string, options?: ODiffOptions & { timeout?: number }, ): Promise; /** * Compare two images buffers, the buffer data is the actual encoded file bytes. * **Important**: Always prefer file paths compare if you are saving images to disk anyway. * * @param baseBuffer - Buffer containing base image data * @param baseFormat - Format of base image: "png", "jpeg", "jpg", "bmp", "tiff", "webp" * @param compareBuffer - Buffer containing compare image data * @param compareFormat - Format of compare image: "png", "jpeg", "jpg", "bmp", "tiff", "webp" * @param diffOutput - Path to output diff image * @param options - Comparison options with optional timeout for request * @returns Promise resolving to comparison result */ compareBuffers( baseBuffer: Buffer, baseFormat: string, compareBuffer: Buffer, compareFormat: string, diffOutput: string, options?: ODiffOptions & { timeout?: number }, ): Promise; /** ``` -------------------------------- ### Basic CLI Comparison Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Run a basic comparison between two images using the command-line interface. An optional output path for the diff image can be provided. ```bash odiff [DIFF output path] ``` -------------------------------- ### ODiffServer.compare Method Source: https://github.com/dmtrkovalenko/odiff/blob/main/README.md Compares two images using the persistent server instance. It automatically handles server initialization if needed. ```APIDOC ## ODiffServer.compare ### Description Compares two images using the persistent server. Automatically waits for server initialization if needed. ### Signature ```typescript compare(basePath: string, comparePath: string, diffOutput: string, options?: ODiffOptions & { timeout?: number }): Promise ``` ### Parameters - **basePath** (string) - Required - Path to the base image. - **comparePath** (string) - Required - Path to the comparison image. - **diffOutput** (string) - Required - Path to output the diff image. - **options** (ODiffOptions & { timeout?: number }) - Optional - Comparison options, including an optional timeout for the request. ``` -------------------------------- ### Memory-Efficient Image Comparison Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/configuration.md Use `ODiffServer` for bulk comparisons of many large images, enabling `reduceRamUsage` for memory efficiency. Remember to stop the server after use. ```javascript // For bulk comparisons of many large images const server = new ODiffServer(); for (const [base, compare] of imagePairs) { await server.compare(base, compare, `diff-${i}.png`, { reduceRamUsage: true, threshold: 0.15, }); } server.stop(); ``` -------------------------------- ### playwright-odiff Module Exports Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md The `playwright-odiff` package integrates ODiff with Playwright for screenshot testing. It extends the `expect` API with `toHaveScreenshotOdiff` and requires a setup import. ```APIDOC ### playwright-odiff ``` playwright-odiff ├── toHaveScreenshotOdiff() [extends expect] ├── OdiffScreenshotOptions (type) ├── setup [side-effect import] └── (internal) SnapshotHelper, etc. ``` Import: ```typescript import "playwright-odiff/setup"; import { toHaveScreenshotOdiff } from "playwright-odiff"; ``` Or in Playwright tests after setup import: ```typescript await expect(page).toHaveScreenshotOdiff("snapshot-name"); ``` ``` -------------------------------- ### Playwright ODiff Screenshot Integration Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/README.md Integrates ODiff with Playwright for visual regression testing. This setup allows for easy screenshot comparisons directly within Playwright tests. ```typescript import "playwright-odiff/setup" await expect(page).toHaveScreenshotOdiff(name?: string | string[], options?: ODiffScreenshotOptions) await expect(page).toHaveScreenshotOdiff(options?: { name?: string | string[] } & ODiffScreenshotOptions) await expect(locator).toHaveScreenshotOdiff(...) // same as page type ODiffScreenshotOptions = ODiffOptions & { maxDiffPixels?: number maxDiffPixelRatio?: number clip?: { x, y, width, height } fullPage?: boolean mask?: Locator[] maskColor?: string omitBackground?: boolean timeout?: number animations?: "disabled" | "allow" caret?: "hide" | "initial" scale?: "css" | "device" stylePath?: string | string[] } ``` -------------------------------- ### Configure Screenshot Expectations Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-playwright-matcher.md Configure default screenshot expectations, including maximum difference in pixels and a threshold for visual comparison. This setup is applied globally via `playwright.config.ts`. ```typescript import { defineConfig } from "@playwright/test"; export default defineConfig({ expect: { toHaveScreenshot: { maxDiffPixels: 0, threshold: 0.2, }, }, }); ``` -------------------------------- ### Parallel Playwright Testing with ODiff Server Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Run visual tests in parallel using Playwright and an ODiff server. Ensure the server is started before tests and stopped after all tests are completed. ```typescript const server = new ODiffServer(); test.describe.parallel("visual tests", () => { test("feature 1", async () => { await server.compare("a.png", "b.png", "diff1.png"); }); test("feature 2", async () => { await server.compare("c.png", "d.png", "diff2.png"); }); test.afterAll(() => { server.stop(); }); }); ``` -------------------------------- ### Handle Binary Execution Failure Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/errors-and-handling.md Illustrates how to catch errors that arise when the native odiff binary fails to execute or exits with an unexpected code. ```javascript try { const result = await compare("a.png", "b.png", "diff.png"); } catch (error) { // Error: odiff binary exited with unexpected code {code} (no output) console.error("Binary failure:", error.message); } ``` -------------------------------- ### Run Specific Playwright Test Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Execute a specific Playwright test file, for example, `example.spec.ts`. The `--headed` flag ensures the browser window is visible during the test run. ```bash npx playwright test example.spec.ts --headed ``` -------------------------------- ### compare() Method Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Compares two image files using the persistent server. ```APIDOC ## compare() Compare two image files using the persistent server. ### Signature ```typescript async compare( basePath: string, comparePath: string, diffOutput: string, options?: ODiffOptions & { timeout?: number }, ): Promise ``` ### Parameters #### Path Parameters - **basePath** (string) - Required - Path to base image file. - **comparePath** (string) - Required - Path to comparison image file. - **diffOutput** (string) - Required - Path where diff output image will be written (`.png` only). #### Query Parameters - **options.timeout** (number) - Optional - Timeout in milliseconds for this comparison request. ### Return Type `Promise` See [types.md](types.md#odiffresult) for result structure. ### Throws - `Error` — If server fails to initialize. - `Error` — If comparison times out (when `timeout` option is specified). - `Error` — If server process terminates unexpectedly. ### Examples #### Basic file comparison ```typescript const { ODiffServer } = require("odiff-bin"); const server = new ODiffServer(); const result = await server.compare( "baseline.png", "screenshot.png", "diff.png", ); if (result.match) { console.log("Match!"); } else { console.log(`Diff: ${result.reason}`); } ``` #### Multiple comparisons with options ```typescript const server = new ODiffServer(); const result1 = await server.compare("a.png", "b.png", "diff1.png", { threshold: 0.1, antialiasing: true, }); const result2 = await server.compare("c.png", "d.png", "diff2.png", { threshold: 0.2, timeout: 5000, // 5 second timeout for this request }); server.stop(); ``` #### Parallel usage in test suite ```typescript const server = new ODiffServer(); test("visual test 1", async () => { await server.compare("baseline1.png", "screenshot1.png", "diff1.png"); }); test("visual test 2", async () => { await server.compare("baseline2.png", "screenshot2.png", "diff2.png"); }); // Server cleanup handled automatically on process exit ``` #### With error handling ```typescript const server = new ODiffServer(); try { const result = await server.compare( "baseline.png", "screenshot.png", "diff.png", { timeout: 5000 }, ); if (!result.match && result.reason === "pixel-diff") { console.log(`${result.diffCount} pixels differ`); } } catch (error) { console.error(`Comparison failed: ${error.message}`); } finally { server.stop(); } ``` ``` -------------------------------- ### Basic Image Comparison Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-compare.md Use this snippet for a straightforward comparison between two image files. It requires the paths to the base image, the image to compare, and the desired output path for the diff image. The result indicates if the images match or provides a reason for mismatch. ```javascript const { compare } = require("odiff-bin"); const result = await compare("baseline.png", "screenshot.png", "diff.png"); if (result.match) { console.log("Screenshots match!"); } else { console.log(`Mismatch: ${result.reason}`); if (result.reason === "pixel-diff") { console.log(`${result.diffCount} pixels differ`); } } ``` -------------------------------- ### Register Custom Matcher for Playwright Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Extends Playwright's expect() with a new custom matcher, toHaveScreenshotOdiff, using type augmentation. This is the initial setup required to use the custom matcher in your tests. ```typescript expect.extend({ toHaveScreenshotOdiff: toHaveScreenshotOdiff }); ``` -------------------------------- ### Basic CLI Image Comparison Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Perform a basic image comparison using the ODiff CLI. Provide paths for the baseline image, the screenshot to compare, and the output diff image. ```bash # Basic comparison odiff baseline.png screenshot.png diff.png ``` -------------------------------- ### CLI Image Comparison with Options Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Compare images using the ODiff CLI with advanced options. Customize the comparison using thresholds, antialiasing, and ignoring specific regions. ```bash # With options odiff baseline.png screenshot.png diff.png \ --threshold=0.2 \ --antialiasing \ --ignore=0:0-300:50,0:750-1024:768 ``` -------------------------------- ### Screenshot with Name as Array Segments Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-playwright-matcher.md Save screenshots into a directory structure by providing the screenshot name as an array of segments. For example, `["form", "validation"]` will save the screenshot to `form/validation.png`. ```typescript test("form validation", async ({ page }) => { await page.goto("https://example.com/form"); const form = page.locator("form"); // Screenshot saved to: form/validation.png await expect(form).toHaveScreenshotOdiff(["form", "validation"]); }); ``` -------------------------------- ### Basic File Comparison with ODiffServer Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Perform a basic comparison between two image files and save the difference to a specified output path. Checks if the images match and logs the outcome. ```typescript const { ODiffServer } = require("odiff-bin"); const server = new ODiffServer(); const result = await server.compare( "baseline.png", "screenshot.png", "diff.png", ); if (result.match) { console.log("Match!"); } else { console.log(`Diff: ${result.reason}`); } ``` -------------------------------- ### odiff Memory Management Options Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Illustrates the two memory management strategies in odiff: default full image loading and line-by-line streaming for large images. ```text reduceRamUsage: false (default) └─ Load full images in memory └─ Faster for typical sizes (< 16K x 16K) reduceRamUsage: true └─ Stream line-by-line processing └─ Use for massive images └─ ~1MB overhead regardless of image size ``` -------------------------------- ### ODiffServer Class Source: https://github.com/dmtrkovalenko/odiff/blob/main/README.md Provides a persistent server instance for performing multiple image comparisons efficiently, avoiding repeated process spawn overhead. ```APIDOC ## ODiffServer ### Description A persistent server instance for efficient, multiple image comparisons. ### Initialization The server initializes automatically on the first `compare()` call. It can be instantiated and used immediately. ### Example Usage ```typescript const server = new ODiffServer(); const result1 = await server.compare('a.png', 'b.png', 'diff1.png'); const result2 = await server.compare('c.png', 'd.png', 'diff2.png', { threshold: 0.3, timeout: 5000 }); server.stop(); ``` ### Parallel Processing ODiff automatically spawns a server process per multiplexed core to work in parallel, suitable for multiple independent workers. ``` -------------------------------- ### Showing Caret (Initial State) Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/configuration.md Capture the screenshot with the text caret visible in its initial state. Requires 'playwright-odiff/setup'. ```typescript // Show caret (initial state) await expect(page).toHaveScreenshotOdiff("text-field-with-cursor", { caret: "initial", }); ``` -------------------------------- ### Server Mode Comparison with ODiff Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/MANIFEST.txt For batch operations, use `ODiffServer` for improved performance. Instantiate the server, perform comparisons, and then stop the server. This mode is recommended for multiple comparisons. ```javascript const server = new ODiffServer() await server.compare(base, compare, diff) server.stop() ``` -------------------------------- ### Handle Missing Files Gracefully Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Configures the comparison to not fail immediately if input files are missing. Allows for custom error handling when files are not found. ```javascript const result = await compare("baseline.png", "screenshot.png", "diff.png", { noFailOnFsErrors: true, }); if (result.reason === "file-not-exists") { console.log(`Missing: ${result.file}`); } ``` -------------------------------- ### Generate Markdown Benchmark Results Source: https://github.com/dmtrkovalenko/odiff/blob/main/images/README.md Runs a benchmark comparing odiff, pixelmatch, and ImageMagick's compare, exporting the results in markdown format to a specified path. This is useful for integrating benchmark data into README files. ```bash hyperfine -i --export-markdown 'pixelmatch www.cypress.io-1.png www.cypress.io.png www.cypress-diff.png' 'compare www.cypress.io-1.png www.cypress.io.png -compose src diff-magick.png' 'ODiffBin www.cypress.io-1.png www.cypress.io.png www.cypress-diff.png' ``` -------------------------------- ### Binary Server Mode (Stdio Protocol) Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Interact with odiff in server mode using a simple readline stdio protocol with JSON messages. ```APIDOC ## Binary Server Mode (Stdio Protocol) For pure binary usage this is a simple readline stdio protocol with JSON message, here is a simple example ```sh odiff --server $ odiff --server {"ready":true} # ready signal # your input {"requestId":1,"base":"images/www.cypress.io.png","compare":"images/www.cypress.io-1.png","output":"images/www.cypress- diff.png"} # server response {"requestId":1,"match":false,"reason":"pixel-diff","diffCount":1090946,"diffPercentage":2.95} ``` ``` -------------------------------- ### Command-Line Usage Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Basic command-line interface for comparing two images and optionally outputting a diff image. ```APIDOC ## Command-Line Usage Run the simple comparison. Image paths can be one of supported formats, diff output is optional and can only be `.png`. ``` odiff [DIFF output path] ``` ``` -------------------------------- ### odiff Binary Mode Execution Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md Execute the odiff command-line tool for binary image comparison. Specify base, compare, and diff image paths along with optional arguments. ```bash odiff [OPTIONS] ``` -------------------------------- ### ODiffServer Constructor and Methods Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Defines the ODiffServer class, including its constructor for optional binary path specification and methods for comparing images and stopping the server. ```typescript export declare class ODiffServer { /** * Create a new ODiffServer instance * Server initialization begins immediately in the background * @param binaryPath - Optional path to odiff binary (defaults to bundled binary) */ constructor(binaryPath?: string); /** * Compare two images using the persistent server * Automatically waits for server initialization if needed * @param basePath - Path to base image * @param comparePath - Path to comparison image * @param diffOutput - Path to output diff image * @param options - Comparison options with optional timeout for request * @returns Promise resolving to comparison result */ compare( basePath: string, comparePath: string, diffOutput: string, options?: ODiffOptions & { timeout?: number }, ): Promise; /** * Stop the odiff server process * Should be called when done with all comparisons * Safe to call even if server is not running */ stop(): void; } ``` -------------------------------- ### ODiff Binary Mode Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/modules-overview.md The ODiff binary can be executed directly from the command line for image comparison. It takes the base image, comparison image, and output path for the diff image as arguments, along with optional flags. ```APIDOC ## Binary (odiff) Native image comparison engine written in Zig. ### Features - SIMD optimizations (SSE2, AVX2, AVX512, NEON) - Cross-format comparison (PNG, JPEG, WebP, TIFF, BMP) - Antialiasing detection - Region-based ignoring - YIQ NTSC color space for perceptual difference - Single-threaded, controlled memory footprint ### Execution Modes 1. **Binary mode** — Command-line executable ``` odiff [OPTIONS] ``` ``` -------------------------------- ### Basic Page Screenshot Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-playwright-matcher.md Take a screenshot of the entire page and compare it against a baseline. Requires `playwright-odiff/setup` to be imported. ```typescript import { test, expect } from "@playwright/test"; import "playwright-odiff/setup"; test("homepage looks correct", async ({ page }) => { await page.goto("https://example.com"); await expect(page).toHaveScreenshotOdiff("homepage"); }); ``` -------------------------------- ### Node.js Basic Comparison Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Use the `compare` function from the `odiff-bin` package in Node.js to compare two images. ```APIDOC ## Node.js Basic Comparison We also provide direct node.js binding for the `odiff`. Run the `odiff` from nodejs: ```js const { compare } = require("odiff-bin"); const { match, reason } = await compare( "path/to/first/image.png", "path/to/second/image.png", "path/to/diff.png", ); ``` ``` -------------------------------- ### Node.js Server Mode Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Utilize the `ODiffServer` class for a long-lasting runtime application to reduce forking and initialization overhead. ```APIDOC ## Node.js Server Mode Odiff provides a server mode for the long lasting runtime application to reduce a time you have to spend on forking and initializing child process on each odiff call. From node js it works as simply as ```js const { ODiffServer } = require("odiff-bin"); // it is safe to run from the module scope as it will automatically lazy load // and will cleanup and gracefully close on exits/sigints const odiffServer = new ODiffServer(); const { match, reason } = await odiffServer.compare( "path/to/first/image.png", "path/to/second/image.png", "path/to/diff.png", ); ``` ``` -------------------------------- ### ODiff Process-Per-Comparison Mode Flow Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Outlines the steps involved when using the 'Process-Per-Comparison' mode, where a new process is spawned for each comparison. This mode is suitable for single or occasional comparisons. ```text Application ↓ compare() function ↓ spawn new process ↓ odiff binary (single execution) ↓ exit process ``` -------------------------------- ### Initialize and Retrieve Global ODiffServer Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/architecture.md Implements a singleton pattern for the ODiffServer to ensure a single instance is used throughout the test suite. Includes automatic cleanup of the server process upon exit. ```typescript let GLOBAL_ODIFF_SERVER: ODiffServer | null = null; function getODiffServer(): ODiffServer { if (!GLOBAL_ODIFF_SERVER) { GLOBAL_ODIFF_SERVER = new ODiffServer(); } return GLOBAL_ODIFF_SERVER; } // Auto-cleanup on process exit process.on("exit", () => { if (GLOBAL_ODIFF_SERVER) { GLOBAL_ODIFF_SERVER.stop(); } }); ``` -------------------------------- ### Multiple Comparisons with Options Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/api-reference-odiffserver.md Execute multiple image comparisons using the ODiffServer, applying different options such as threshold and antialiasing for each. Includes setting a specific timeout for one of the requests and stopping the server afterwards. ```typescript const server = new ODiffServer(); const result1 = await server.compare("a.png", "b.png", "diff1.png", { threshold: 0.1, antialiasing: true, }); const result2 = await server.compare("c.png", "d.png", "diff2.png", { threshold: 0.2, timeout: 5000, // 5 second timeout for this request }); server.stop(); ``` -------------------------------- ### Compare Images using pixelmatch Source: https://github.com/dmtrkovalenko/odiff/blob/main/npm_packages/odiff-bin/README.md Compares two images using the pixelmatch command-line tool and outputs the difference to a specified file. ```bash pixelmatch www.cypress.io-1.png www.cypress.io.png www.cypress-diff.png ``` -------------------------------- ### Efficient Image Comparison with ODiff Server Source: https://github.com/dmtrkovalenko/odiff/blob/main/_autodocs/quick-start.md Optimize bulk image comparisons by reusing an ODiff server instance. This avoids the overhead of creating a new process for each comparison. ```javascript // Good: Reuse server for many comparisons const server = new ODiffServer(); for (const pair of thousandImagePairs) { await server.compare(pair.base, pair.compare, pair.diff); } server.stop(); // Avoid: Creating new process for each comparison for (const pair of thousandImagePairs) { await compare(pair.base, pair.compare, pair.diff); } ```