Manifest

Schema reference

Every field of the manifest, generated from the JSON Schema at /schema/v1.json.

The normative description of the format is the JSON Schema (draft 2020-12) at https://visual-regression.dev/schema/v1.json, shipped in the visual-regression-manifest package as schema.json. This page is generated from it.

A machine-readable record of every screenshot comparison made during a test run, written by a visual regression tool and read by CI tooling (PR comment bots, review dashboards, approval tools). Runner-agnostic: everything specific to the test runner lives in runner. The envelope, the CI block and the open extra objects follow CTRF (ctrf.io) naming so a manifest maps onto a CTRF report without loss; see the toCtrf/fromCtrf converters. Consumers must ignore keys they do not know.

Top level

fieldtyperequireddescription
reportFormat"visual-regression-manifest"yesIdentifies the document as a visual regression manifest (CTRF has reportFormat: "CTRF").
specVersionstringyesVersion of this format (semver). The major is bumped on breaking changes only; readers accept every version with the major they know.
createdAttimestampyesWhen the run started (ISO 8601).
updatedAttimestampyesWhen the file was last written (ISO 8601). Writers rewrite the file after every comparison, so a manifest is complete even when the run was aborted.
projectRootstringyesAbsolute path (on the machine that ran the tests) that every relative path in the manifest resolves against. Not necessarily the repository root: ci.workspace is the checkout directory.
platformplatformyes
cinull | ciyesCI metadata detected from environment variables. null outside CI, { "provider": null } when only a generic CI flag was set.
tooltoolyes
optionsobjectyesGlobal tool options as configured, in the writer's vocabulary (for the Cypress plugin: every pluginVisualRegression* option with the prefix stripped).
runnerrunneryes
uploadupload
summarysummaryyes
entriesarray of entryyes
extraextra

timestamp

Type: string, matching ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$.

status

passed: within threshold. failed: above threshold, .actual and .diff images kept for review. missing-baseline: no baseline and the tool was told not to create one. created: no baseline, the actual image became the baseline. updated: the baseline was overwritten on request. approved: the baseline was replaced from a review UI. failed and missing-baseline are the entries that need a human. In CTRF terms missing-baseline is failed and created, updated, approved are passed, with the manifest status kept in rawStatus.

One of "passed", "failed", "missing-baseline", "created", "updated", "approved".

tool

What wrote the manifest: a visual regression plugin, a converter, a review tool. Same shape as CTRF's tool.

fieldtyperequireddescription
namestringyes
versionstring
extraextra

summary

Counts over entries, so a consumer can tell whether a human is needed without reading them all. Writers recompute it on every write; readers merging several manifests recompute it from the merged entries.

fieldtyperequireddescription
entriesintegeryes
passedintegeryes
failedintegeryes
missingBaselineintegeryes
createdintegeryes
updatedintegeryes
approvedintegeryes
needsHumanintegeryesfailed + missingBaseline.

platform

The machine that ran the tests (the host), which is not necessarily the device under test: for a mobile or remote-device run see the entries' target. Named like CTRF's environment: osPlatform is an open string (Node-based writers use process.platform names: linux, darwin, win32), osRelease the kernel release, osVersion the human-readable OS version.

fieldtyperequireddescription
osPlatformstringyes
archstringyes
osReleasestring
osVersionstring

browser

fieldtyperequireddescription
namestringyes
versionstring
familystring
headlessboolean

target

What was captured, for tools that are not a browser: a desktop or mobile application on a device, an emulator or a remote farm. Everything is optional; unknown keys are allowed.

fieldtyperequireddescription
kindstringKnown values: browser, desktop, mobile, embedded; free-form otherwise.
osstring
osVersionstring
archstring
deviceobject
displayobject
localestring
themestring
appobject
driverstring
emulatedboolean

device

fieldtyperequireddescription
modelstring
idstring
formFactorstring

display

fieldtyperequireddescription
widthnumber
heightnumber
densitynumberDevice pixels per logical pixel (scale factor / dpr).
orientationstring

app

fieldtyperequireddescription
idstring
versionstring
buildstring

viewport

fieldtyperequireddescription
widthnumberyes
heightnumberyes

ci

Where the run happened. Keys that have a CTRF environment equivalent carry its name (commit, branchName, repositoryName, repositoryUrl, buildId, buildName, buildNumber, buildUrl); the rest is what CTRF lacks.

fieldtyperequireddescription
providerstring | nullyesKnown values: github, gitlab. Other CI systems are free-form lowercase ids; null when only a generic CI flag was set.
repositoryNamestringowner/repo (GitHub) or group/project (GitLab).
repositoryUrlstring
commitstringOn GitHub pull_request events this is the synthetic merge commit; tools that write to the PR branch must use pullRequest.headSha.
refstring
branchNamestring
pullRequestnull | object
eventstring
buildIdstringThe run or pipeline id (GitHub GITHUB_RUN_ID, GitLab CI_PIPELINE_ID); locates the artifacts together with runAttempt.
buildNamestringThe workflow or pipeline name.
buildNumberstring
buildUrlstringLink to the run or job page.
runAttemptstring
jobstring
jobIdstring
serverUrlstring
workspacestringAbsolute path of the checked-out repository on the CI machine.

runner

What ran the tests (Cypress, Playwright, a mobile driver), as opposed to tool, which wrote the manifest. Only name is required; the remaining keys are runner vocabulary and writers may add their own.

fieldtyperequireddescription
namestringyes
versionstring
testingTypestring
mode"run" | "open"
configFilestringRelative to projectRoot, / separators.
browserbrowser
specsarray of stringTest files of the run relative to projectRoot, when known up front.
specPatternstring | array of string
baseUrlstring | null
viewportviewport
cloudobjectHosted runner dashboard details, when recording.

cloud

Hosted runner dashboard details, when recording.

fieldtyperequireddescription
runUrlstring
groupstring
tagstring
parallelboolean

upload

Where the images and snapshots of the run were uploaded to, when an upload service was used.

fieldtyperequireddescription
buildIdstringyes
urlstringyes
level"images" | "images+snapshot"yes

image

fieldtyperequireddescription
pathstring | nullyesRelative to projectRoot, / separators; null when the file does not exist. Baseline, actual and diff of an entry share one extension (PNG for all current writers); .actual and .diff go before it.
widthinteger
heightinteger
extraextra

attachment

Any other file an entry wants to point at (a trace, a video, a DOM snapshot). Same shape as a CTRF attachment; path is relative to projectRoot.

fieldtyperequireddescription
namestringyes
contentTypestringyes
pathstringyes
attachmentIdstring
extraextra

subject

What the screenshot is a picture of, as opposed to the test that took it: a component story, a page, a screen. Tool-neutral; the id is whatever the producer uses to name the thing (for example a Storybook story id), so tools can group or match entries by it.

fieldtyperequireddescription
idstringyes
kindstringKnown values: story, page, component, screen; free-form otherwise.

extra

Open metadata keyed by namespace, like CTRF's extra; every value is an object. Consumers must ignore namespaces they do not know. Conventional namespaces on an entry or image: design (a design software source: tool, file, node, version, for example the Figma file, frame and version a baseline was exported from) and storybook (args, globals). visualRegression is reserved for the CTRF converters. Nothing here takes part in baseline identity.

Type: object.

renderer

Where the pixels came from, as opposed to platform, which is where the test ran. Entries with different renderers are different baselines.

fieldtyperequireddescription
backendstringyesKnown values: native (the test runner's own capture), docker, cloud. Writers may add their own, e.g. device or emulator.
namestringWhat rendered the pixels: a browser, an app or a device. Absent when backend says enough.
versionstring
browserstringBrowser name; kept for browser renderers, same as name.
browserVersionstring
rendererVersionstringVersion of the renderer image; absent under native.
imageDigeststringContent digest of the renderer image; absent under native.
fallbackbooleantrue when an auto renderer degraded to native.

sha256

Type: string, matching ^[0-9a-f]{64}$.

entryOptions

The comparison options the entry was made with, exactly as configured (imagesPath keeps its tokens unexpanded).

fieldtyperequireddescription
imagesPathstringyes
titlestring
maxDiffThresholdnumberyes
diffConfigobjectyes
createMissingImagesbooleanyes
updateImagesboolean | "failures-only"yes
forceDeviceScaleFactorbooleanBrowser runners only.
matchAgainstPathstring
screenshotConfigobjectCapture options in the runner's vocabulary (Cypress screenshot config); JSON-serialisable keys only.

entry

One screenshot comparison. Maps onto a CTRF test of type: "visual": name is the test name, test.titlePath without its last element the suite, test.filePath the file path, message the message, duration the duration.

fieldtyperequireddescription
namestringyesScreenshot name, equal to the baseline file stem. Unique within a run.
testobjectyes
statusstatusyes
comparisonobjectyes
imagesobjectyes
attachmentsarray of attachment
baselineWrittenbooleanyestrue whenever the baseline file was (re)written during the run, whatever the status.
recordedAttimestampyes
durationintegerHow long the capture and comparison took, in milliseconds, when the writer measured it.
platformobjectWhere this screenshot was taken; per entry because manifests of several machines get merged.
targettarget
subjectsubject
extraextra
variantstringProducer-chosen id that tells entries of the same screenshot name apart (device, OS version, density, locale, theme, project, ...). Part of the baseline identity when merging manifests; absent, identity falls back to platform.osPlatform + platform.browser.name + renderer.
viewportviewport
optionsentryOptions
rendererrenderer
hashesobjectsha256 of the files listed in images; a key is present only when the file exists.
messagestringyesHuman-readable summary, informational only.

test

fieldtyperequireddescription
filePathstringyesTest file relative to projectRoot, / separators. Empty when unknown.
titlePatharray of stringyesDescribe blocks and test title, outermost first.
retryintegeryesAttempt index of the test this comparison belongs to: 0 for the first attempt (CTRF's retries is a count, not an index).

comparison

fieldtyperequireddescription
diffRationumberyesShare of differing pixels, 0..1. 0 when no comparison ran.
thresholdnumberyes

images

fieldtyperequireddescription
baselineimage & anyyesThe baseline path is always known, even when the file does not exist yet (missing-baseline).
actualimageyes
diffobjectyes

diff

fieldtyperequireddescription
pathstring | nullyes

platform

Where this screenshot was taken; per entry because manifests of several machines get merged.

fieldtyperequireddescription
osPlatformstringyes
osReleasestring
osVersionstring
archstring
browserbrowserAbsent for non-browser targets (desktop and mobile apps).

hashes

sha256 of the files listed in images; a key is present only when the file exists.

fieldtyperequireddescription
baselinesha256
actualsha256
diffsha256