Skip to main content

Configuration file: applitools.config.js

Overview

applitools.config.js is the source of truth for project defaults. Keep this small, explicit, and versioned. Env/CLI can override, story files can special‑case. Link back to Integration with Storybook for a starter config.

Create this file at your repo root (or pass with --conf). Export a CommonJS object.

// applitools.config.js
/**
* @type {import('@applitools/eyes-storybook').ApplitoolsConfig}
**/
module.exports = {
apiKey: '...',
};

Core

  • apiKey: string — Your Eyes API key:

    module.exports = { apiKey: '...' };
  • serverUrl: string — Eyes server URL (public cloud if omitted).

  • showLogs: boolean — Show SDK logs (default: false).

  • exitcode: boolean — Non‑zero exit code on diffs/failures (default: true).

Startup & discovery (how Eyes finds and launches Storybook)

  • storybookUrl: string — Use a running/static SB instead of launching:

    module.exports = { storybookUrl: 'http://localhost:6006' };

    Use in CI for deterministic ports/URLs.

  • storybookPort: number, storybookHost: string — When Eyes launches SB for you:

    module.exports = { storybookPort: 9000, storybookHost: 'localhost' };
  • storybookConfigDir: string — Non‑default .storybook path:

    module.exports = { storybookConfigDir: 'apps/docs/.storybook' };
  • storybookStaticDir: string | string[] — Mount extra static assets:

    module.exports = { storybookStaticDir: ['public', '../shared-assets'] };
  • showStorybookOutput: boolean — Pipe SB logs to the terminal (false by default).

  • readStoriesTimeout: number ms — Abort discovery if SB is too slow:

    module.exports = { readStoriesTimeout: 120000 };
  • include: string | RegExp | function — Limit which stories run (see Per‑Story → include for details):

    module.exports = {
    include: ({ kind }) => kind.startsWith('Components/'),
    };
  • variations: Array<{ queryParams?: object; properties?: Array<{name,value}> }> — Run stories with extra query params/properties (e.g., RTL vs LTR):

    module.exports = {
    variations: [
    {
    queryParams: { 'eyes-variation': 'RTL' },
    properties: [{ name: 'rtl', value: 'true' }],
    },
    ],
    };

Rendering & timing (how snapshots are captured & rendered)

  • viewportSize: { width, height } — Puppeteer window used to snapshot DOM (default ~{1024,600}):

    module.exports = { viewportSize: { width: 1280, height: 720 } };
  • browser: Target | Target[] — UFG targets (see Browsers & Devices):

    module.exports = {
    browser: [
    { name: 'chrome', width: 1440, height: 900 },
    { name: 'firefox', width: 1024, height: 768 },
    {
    iosDeviceInfo: {
    deviceName: 'iPhone 16',
    screenOrientation: 'portrait',
    },
    },
    ],
    };
  • testConcurrency: number — Parallel renders on UFG (default often 50 or 100 depending on license tier).

    • This is an optional setting. Set this to override your company concurrency limit, if needed.
  • navigationWaitUntil: 'load'|'domcontentloaded'|'networkidle0'|'networkidle2' — When to consider navigation done. Heavy async UI → try networkidle2.

  • browserCacheRequests: boolean — Cache requests across stories (speed).

  • sendDom: boolean — Attach DOM/CSS for rendering (default true). Rare to disable.

  • visualGridOptions: object — Extra UFG flags (e.g., polyfillAdoptedStyleSheets).

  • runInDocker: boolean — Add stable Chrome flags in containerized envs.

  • puppeteerOptions: object — Pass to puppeteer.launch (e.g., executablePath).

  • puppeteerExtraHTTPHeaders: object — Set extra headers before capture.

Baselines, branches & batches (how results are organized)

  • appName: string — Baseline application key. Defaults to package.json#name:

    module.exports = { appName: 'ui-library' };
  • batch: { id?, name?, sequenceName?, notifyOnCompletion?, properties? } — Name/ID your run and tag it:

    module.exports = {
    batch: {
    name: process.env.CI ? `PR #${process.env.PR_NUMBER}` : 'Local run',
    properties: [{ name: 'team', value: 'design-systems' }],
    },
    };
  • baselineEnvName: string — Name of the baseline environment.

  • envName: string — Name of the execution environment.

  • properties: Array<{name,value}> — Adds custom properties for each test. These show up in Test Manager, and tests can be grouped by custom properties. By default, Eyes-Storybook adds 2 custom properties for each test: the Component name and State of each component. Adding more properties via this config param will not override these two properties..

  • Branching — Control where baselines come from and compare to:

    module.exports = {
    branchName: 'feature/datepicker',
    baselineBranchName: 'main',
    parentBranchName: 'main',
    compareWithParentBranch: false,
    };
  • Save policy — New tests & diffs:

    module.exports = {
    saveNewTests: true,
    saveDiffs: true,
    ignoreBaseline: false,
    };
  • dontCloseBatches: boolean — Keep batch open across multi‑job pipelines.

Matching & regions (what differences are considered important)

  • matchLevel: 'Strict'|'Layout'|'Content'|'IgnoreColors' — Global sensitivity.
    See: Core Concepts → Match Levels.

  • ignoreCaret: boolean — Ignore blinking text cursors.

  • ignoreDisplacements: boolean — Treat pure movement leniently in initial view.

  • Region lists — Show intent to Visual AI per area (selectors or rects):

    module.exports = {
    ignoreRegions: [
    { selector: '.ad' },
    { left: 10, top: 20, width: 200, height: 60 },
    ],
    floatingRegions: [
    {
    selector: '.toast',
    maxUpOffset: 10,
    maxDownOffset: 10,
    maxLeftOffset: 30,
    maxRightOffset: 30,
    },
    ],
    layoutRegions: [{ selector: '.grid' }], // focus on layout/structure
    strictRegions: [{ selector: '.cta' }], // highest scrutiny
    contentRegions: [{ selector: '.article' }], // prefer content changes
    accessibilityRegions: [
    { selector: '.a11y', accessibilityType: 'RegularText' },
    ],
    accessibilityValidation: { level: 'AA', guidelinesVersion: 'WCAG_2_1' },
    };

Responsive snapshots

  • layoutBreakpoints: true | number[] — Capture per width:
    module.exports = { layoutBreakpoints: [480, 768, 1200] };

Results output & Root Cause Analysis

  • jsonFilePath / tapFilePath / xmlFilePath — Emit results for CI parsers:

    module.exports = { jsonFilePath: 'artifacts/eyes-results.json' };
  • domMapping — Map hashed DOM/CSS tokens to readable names for Root Cause Analysis:

    module.exports = { domMapping: './dom-mapping.json' };

Hooks

  • runBefore({ rootEl, story }) — Prep state pre‑capture (open dropdowns, etc.).
  • runAfter({ rootEl, story }) — Cleanup side‑effects post‑capture.

Practical notes

  • Docker/Alpine: If Chrome won’t launch, set runInDocker: true or supply a known executablePath.
  • Deterministic data: Story iframes include ?eyes-storybook=true; branch on it to freeze dates/seeds.
  • Interactions (play): Eyes captures after play completes; waitBeforeCapture starts post‑play.