[{"data":1,"prerenderedAt":935},["ShallowReactive",2],{"navigation_docs":3,"-manifest-writing":93,"-manifest-writing-surround":930},[4,41,46,89],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":40},"Learn","i-lucide-book-open","\u002Flearn","1.learn",[10,15,20,25,30,35],{"title":11,"path":12,"stem":13,"icon":14},"What visual regression testing is","\u002Flearn\u002Fwhat-is-visual-regression-testing","1.learn\u002F1.what-is-visual-regression-testing","i-lucide-eye",{"title":16,"path":17,"stem":18,"icon":19},"How image diffing works","\u002Flearn\u002Fhow-image-diffing-works","1.learn\u002F2.how-image-diffing-works","i-lucide-diff",{"title":21,"path":22,"stem":23,"icon":24},"Why screenshots flake","\u002Flearn\u002Fwhy-screenshots-flake","1.learn\u002F3.why-screenshots-flake","i-lucide-shuffle",{"title":26,"path":27,"stem":28,"icon":29},"Baselines and approval","\u002Flearn\u002Fbaselines-and-approval","1.learn\u002F4.baselines-and-approval","i-lucide-check-check",{"title":31,"path":32,"stem":33,"icon":34},"Running in CI","\u002Flearn\u002Frunning-in-ci","1.learn\u002F5.running-in-ci","i-lucide-workflow",{"title":36,"path":37,"stem":38,"icon":39},"Choosing a tool","\u002Flearn\u002Fchoosing-a-tool","1.learn\u002F6.choosing-a-tool","i-lucide-list-checks",false,{"title":42,"path":43,"stem":44,"icon":45},"Compare the tools","\u002Fcompare","2.compare","i-lucide-scale",{"title":47,"path":48,"stem":49,"children":50,"icon":53},"Manifest","\u002Fmanifest","3.manifest\u002F1.index",[51,54,59,64,69,74,79,84],{"title":52,"path":48,"stem":49,"icon":53},"The run manifest","i-lucide-file-json",{"title":55,"path":56,"stem":57,"icon":58},"The format","\u002Fmanifest\u002Fformat","3.manifest\u002F2.format","i-lucide-file-code",{"title":60,"path":61,"stem":62,"icon":63},"Reading manifests","\u002Fmanifest\u002Freading","3.manifest\u002F3.reading","i-lucide-book-open-check",{"title":65,"path":66,"stem":67,"icon":68},"Merging the manifests of a run","\u002Fmanifest\u002Fmerging","3.manifest\u002F4.merging","i-lucide-merge",{"title":70,"path":71,"stem":72,"icon":73},"Writing manifests","\u002Fmanifest\u002Fwriting","3.manifest\u002F5.writing","i-lucide-pencil-line",{"title":75,"path":76,"stem":77,"icon":78},"Converting to and from other formats","\u002Fmanifest\u002Fconverting","3.manifest\u002F6.converting","i-lucide-arrow-left-right",{"title":80,"path":81,"stem":82,"icon":83},"Reference","\u002Fmanifest\u002Freference","3.manifest\u002F7.reference","i-lucide-list",{"title":85,"path":86,"stem":87,"icon":88},"Schema reference","\u002Fmanifest\u002Fschema","3.manifest\u002F8.schema","i-lucide-braces",{"title":90,"path":91,"stem":92,"icon":14},"Viewer","\u002Fviewer","4.viewer",{"id":94,"title":70,"body":95,"description":923,"extension":924,"links":925,"meta":926,"navigation":927,"path":71,"seo":928,"stem":72,"__hash__":929},"docs\u002F3.manifest\u002F5.writing.md",{"type":96,"value":97,"toc":921},"minimark",[98,139,888,917],[99,100,101,102,106,107,110,111,114,115,118,119,122,123,126,127,130,131,134,135,138],"p",{},"Test-runner integrations use ",[103,104,105],"code",{},"ManifestWriter",": a builder bound to a file that rewrites it atomically on every change. For runs with thousands of screenshots pass ",[103,108,109],{},"{ writeDelayMs: 200 }"," as the third argument to coalesce the rewrites; pending changes are written on ",[103,112,113],{},"flush()"," and when the process exits (not if it is killed outright, which is why the default is ",[103,116,117],{},"0","). A ",[103,120,121],{},"passed"," entry never lists ",[103,124,125],{},".actual"," or ",[103,128,129],{},".diff"," files, even when leftovers of an earlier run sit next to it, and test files are recorded normalised (",[103,132,133],{},".\u002Fa.spec.ts"," and ",[103,136,137],{},"a.spec.ts"," are one file).",[140,141,146],"pre",{"className":142,"code":143,"language":144,"meta":145,"style":145},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import {\n  ManifestWriter,\n  getManifestFileName,\n} from 'visual-regression-manifest';\n\nconst writer = new ManifestWriter(\n  `output\u002F${getManifestFileName('my-runner')}`,\n  {\n    projectRoot: process.cwd(),\n    tool: { name: 'my-visual-plugin', version: '1.0.0' }, \u002F\u002F what writes the file\n    runner: { name: 'my-runner', version: '2.0.0' }, \u002F\u002F what runs the tests; add any runner-specific keys\n    options: { threshold: 0.01 }, \u002F\u002F your global options, verbatim\n    \u002F\u002F platform and ci are detected (GitHub Actions, GitLab CI) unless given\n  },\n);\n\nwriter.record({\n  actualPath: 'shots\u002Fhome.actual.png', \u002F\u002F also the key: recording it again replaces the entry\n  baselinePath: 'shots\u002Fhome.png',\n  \u002F\u002F diffPath defaults to the `.diff` sibling; pass `null` when you write none\n  testFile: 'e2e\u002Fhome.spec.ts',\n  titlePath: ['home', 'renders'],\n  retry: 0, \u002F\u002F a retry replaces the entries of the earlier attempts of that test\n  status: 'failed',\n  diffRatio: 0.02,\n  threshold: 0.01,\n  baselineWritten: false,\n  duration: 840,\n  actualSize: { width: 1280, height: 720 },\n  platform: {\n    osPlatform: process.platform,\n    browser: { name: 'chromium', version: '130' },\n  },\n  attachments: [\n    { name: 'trace', contentType: 'application\u002Fzip', path: 'trace.zip' },\n  ],\n  message: '2% of pixels differ',\n});\nwriter.approve({ actualPath: 'shots\u002Fhome.actual.png' }); \u002F\u002F after moving the actual over the baseline\nwriter.dropTestFile('e2e\u002Fhome.spec.ts'); \u002F\u002F before re-running a file in an interactive runner\nwriter.reset(); \u002F\u002F start of a run: forget everything, delete the file\n","ts","",[103,147,148,161,171,179,201,208,231,264,270,294,339,377,401,407,413,420,425,441,461,478,484,501,533,549,566,579,591,605,618,649,659,676,712,717,728,775,783,800,809,846,871],{"__ignoreMap":145},[149,150,153,157],"span",{"class":151,"line":152},"line",1,[149,154,156],{"class":155},"s7zQu","import",[149,158,160],{"class":159},"sMK4o"," {\n",[149,162,164,168],{"class":151,"line":163},2,[149,165,167],{"class":166},"sTEyZ","  ManifestWriter",[149,169,170],{"class":159},",\n",[149,172,174,177],{"class":151,"line":173},3,[149,175,176],{"class":166},"  getManifestFileName",[149,178,170],{"class":159},[149,180,182,185,188,191,195,198],{"class":151,"line":181},4,[149,183,184],{"class":159},"}",[149,186,187],{"class":155}," from",[149,189,190],{"class":159}," '",[149,192,194],{"class":193},"sfazB","visual-regression-manifest",[149,196,197],{"class":159},"'",[149,199,200],{"class":159},";\n",[149,202,204],{"class":151,"line":203},5,[149,205,207],{"emptyLinePlaceholder":206},true,"\n",[149,209,211,215,218,221,224,228],{"class":151,"line":210},6,[149,212,214],{"class":213},"spNyl","const",[149,216,217],{"class":166}," writer ",[149,219,220],{"class":159},"=",[149,222,223],{"class":159}," new",[149,225,227],{"class":226},"s2Zo4"," ManifestWriter",[149,229,230],{"class":166},"(\n",[149,232,234,237,240,243,246,249,251,254,256,259,262],{"class":151,"line":233},7,[149,235,236],{"class":159},"  `",[149,238,239],{"class":193},"output\u002F",[149,241,242],{"class":159},"${",[149,244,245],{"class":226},"getManifestFileName",[149,247,248],{"class":166},"(",[149,250,197],{"class":159},[149,252,253],{"class":193},"my-runner",[149,255,197],{"class":159},[149,257,258],{"class":166},")",[149,260,261],{"class":159},"}`",[149,263,170],{"class":159},[149,265,267],{"class":151,"line":266},8,[149,268,269],{"class":159},"  {\n",[149,271,273,277,280,283,286,289,292],{"class":151,"line":272},9,[149,274,276],{"class":275},"swJcz","    projectRoot",[149,278,279],{"class":159},":",[149,281,282],{"class":166}," process",[149,284,285],{"class":159},".",[149,287,288],{"class":226},"cwd",[149,290,291],{"class":166},"()",[149,293,170],{"class":159},[149,295,297,300,302,305,308,310,312,315,317,320,323,325,327,330,332,335],{"class":151,"line":296},10,[149,298,299],{"class":275},"    tool",[149,301,279],{"class":159},[149,303,304],{"class":159}," {",[149,306,307],{"class":275}," name",[149,309,279],{"class":159},[149,311,190],{"class":159},[149,313,314],{"class":193},"my-visual-plugin",[149,316,197],{"class":159},[149,318,319],{"class":159},",",[149,321,322],{"class":275}," version",[149,324,279],{"class":159},[149,326,190],{"class":159},[149,328,329],{"class":193},"1.0.0",[149,331,197],{"class":159},[149,333,334],{"class":159}," },",[149,336,338],{"class":337},"sHwdD"," \u002F\u002F what writes the file\n",[149,340,342,345,347,349,351,353,355,357,359,361,363,365,367,370,372,374],{"class":151,"line":341},11,[149,343,344],{"class":275},"    runner",[149,346,279],{"class":159},[149,348,304],{"class":159},[149,350,307],{"class":275},[149,352,279],{"class":159},[149,354,190],{"class":159},[149,356,253],{"class":193},[149,358,197],{"class":159},[149,360,319],{"class":159},[149,362,322],{"class":275},[149,364,279],{"class":159},[149,366,190],{"class":159},[149,368,369],{"class":193},"2.0.0",[149,371,197],{"class":159},[149,373,334],{"class":159},[149,375,376],{"class":337}," \u002F\u002F what runs the tests; add any runner-specific keys\n",[149,378,380,383,385,387,390,392,396,398],{"class":151,"line":379},12,[149,381,382],{"class":275},"    options",[149,384,279],{"class":159},[149,386,304],{"class":159},[149,388,389],{"class":275}," threshold",[149,391,279],{"class":159},[149,393,395],{"class":394},"sbssI"," 0.01",[149,397,334],{"class":159},[149,399,400],{"class":337}," \u002F\u002F your global options, verbatim\n",[149,402,404],{"class":151,"line":403},13,[149,405,406],{"class":337},"    \u002F\u002F platform and ci are detected (GitHub Actions, GitLab CI) unless given\n",[149,408,410],{"class":151,"line":409},14,[149,411,412],{"class":159},"  },\n",[149,414,416,418],{"class":151,"line":415},15,[149,417,258],{"class":166},[149,419,200],{"class":159},[149,421,423],{"class":151,"line":422},16,[149,424,207],{"emptyLinePlaceholder":206},[149,426,428,431,433,436,438],{"class":151,"line":427},17,[149,429,430],{"class":166},"writer",[149,432,285],{"class":159},[149,434,435],{"class":226},"record",[149,437,248],{"class":166},[149,439,440],{"class":159},"{\n",[149,442,444,447,449,451,454,456,458],{"class":151,"line":443},18,[149,445,446],{"class":275},"  actualPath",[149,448,279],{"class":159},[149,450,190],{"class":159},[149,452,453],{"class":193},"shots\u002Fhome.actual.png",[149,455,197],{"class":159},[149,457,319],{"class":159},[149,459,460],{"class":337}," \u002F\u002F also the key: recording it again replaces the entry\n",[149,462,464,467,469,471,474,476],{"class":151,"line":463},19,[149,465,466],{"class":275},"  baselinePath",[149,468,279],{"class":159},[149,470,190],{"class":159},[149,472,473],{"class":193},"shots\u002Fhome.png",[149,475,197],{"class":159},[149,477,170],{"class":159},[149,479,481],{"class":151,"line":480},20,[149,482,483],{"class":337},"  \u002F\u002F diffPath defaults to the `.diff` sibling; pass `null` when you write none\n",[149,485,487,490,492,494,497,499],{"class":151,"line":486},21,[149,488,489],{"class":275},"  testFile",[149,491,279],{"class":159},[149,493,190],{"class":159},[149,495,496],{"class":193},"e2e\u002Fhome.spec.ts",[149,498,197],{"class":159},[149,500,170],{"class":159},[149,502,504,507,509,512,514,517,519,521,523,526,528,531],{"class":151,"line":503},22,[149,505,506],{"class":275},"  titlePath",[149,508,279],{"class":159},[149,510,511],{"class":166}," [",[149,513,197],{"class":159},[149,515,516],{"class":193},"home",[149,518,197],{"class":159},[149,520,319],{"class":159},[149,522,190],{"class":159},[149,524,525],{"class":193},"renders",[149,527,197],{"class":159},[149,529,530],{"class":166},"]",[149,532,170],{"class":159},[149,534,536,539,541,544,546],{"class":151,"line":535},23,[149,537,538],{"class":275},"  retry",[149,540,279],{"class":159},[149,542,543],{"class":394}," 0",[149,545,319],{"class":159},[149,547,548],{"class":337}," \u002F\u002F a retry replaces the entries of the earlier attempts of that test\n",[149,550,552,555,557,559,562,564],{"class":151,"line":551},24,[149,553,554],{"class":275},"  status",[149,556,279],{"class":159},[149,558,190],{"class":159},[149,560,561],{"class":193},"failed",[149,563,197],{"class":159},[149,565,170],{"class":159},[149,567,569,572,574,577],{"class":151,"line":568},25,[149,570,571],{"class":275},"  diffRatio",[149,573,279],{"class":159},[149,575,576],{"class":394}," 0.02",[149,578,170],{"class":159},[149,580,582,585,587,589],{"class":151,"line":581},26,[149,583,584],{"class":275},"  threshold",[149,586,279],{"class":159},[149,588,395],{"class":394},[149,590,170],{"class":159},[149,592,594,597,599,603],{"class":151,"line":593},27,[149,595,596],{"class":275},"  baselineWritten",[149,598,279],{"class":159},[149,600,602],{"class":601},"sfNiH"," false",[149,604,170],{"class":159},[149,606,608,611,613,616],{"class":151,"line":607},28,[149,609,610],{"class":275},"  duration",[149,612,279],{"class":159},[149,614,615],{"class":394}," 840",[149,617,170],{"class":159},[149,619,621,624,626,628,631,633,636,638,641,643,646],{"class":151,"line":620},29,[149,622,623],{"class":275},"  actualSize",[149,625,279],{"class":159},[149,627,304],{"class":159},[149,629,630],{"class":275}," width",[149,632,279],{"class":159},[149,634,635],{"class":394}," 1280",[149,637,319],{"class":159},[149,639,640],{"class":275}," height",[149,642,279],{"class":159},[149,644,645],{"class":394}," 720",[149,647,648],{"class":159}," },\n",[149,650,652,655,657],{"class":151,"line":651},30,[149,653,654],{"class":275},"  platform",[149,656,279],{"class":159},[149,658,160],{"class":159},[149,660,662,665,667,669,671,674],{"class":151,"line":661},31,[149,663,664],{"class":275},"    osPlatform",[149,666,279],{"class":159},[149,668,282],{"class":166},[149,670,285],{"class":159},[149,672,673],{"class":166},"platform",[149,675,170],{"class":159},[149,677,679,682,684,686,688,690,692,695,697,699,701,703,705,708,710],{"class":151,"line":678},32,[149,680,681],{"class":275},"    browser",[149,683,279],{"class":159},[149,685,304],{"class":159},[149,687,307],{"class":275},[149,689,279],{"class":159},[149,691,190],{"class":159},[149,693,694],{"class":193},"chromium",[149,696,197],{"class":159},[149,698,319],{"class":159},[149,700,322],{"class":275},[149,702,279],{"class":159},[149,704,190],{"class":159},[149,706,707],{"class":193},"130",[149,709,197],{"class":159},[149,711,648],{"class":159},[149,713,715],{"class":151,"line":714},33,[149,716,412],{"class":159},[149,718,720,723,725],{"class":151,"line":719},34,[149,721,722],{"class":275},"  attachments",[149,724,279],{"class":159},[149,726,727],{"class":166}," [\n",[149,729,731,734,736,738,740,743,745,747,750,752,754,757,759,761,764,766,768,771,773],{"class":151,"line":730},35,[149,732,733],{"class":159},"    {",[149,735,307],{"class":275},[149,737,279],{"class":159},[149,739,190],{"class":159},[149,741,742],{"class":193},"trace",[149,744,197],{"class":159},[149,746,319],{"class":159},[149,748,749],{"class":275}," contentType",[149,751,279],{"class":159},[149,753,190],{"class":159},[149,755,756],{"class":193},"application\u002Fzip",[149,758,197],{"class":159},[149,760,319],{"class":159},[149,762,763],{"class":275}," path",[149,765,279],{"class":159},[149,767,190],{"class":159},[149,769,770],{"class":193},"trace.zip",[149,772,197],{"class":159},[149,774,648],{"class":159},[149,776,778,781],{"class":151,"line":777},36,[149,779,780],{"class":166},"  ]",[149,782,170],{"class":159},[149,784,786,789,791,793,796,798],{"class":151,"line":785},37,[149,787,788],{"class":275},"  message",[149,790,279],{"class":159},[149,792,190],{"class":159},[149,794,795],{"class":193},"2% of pixels differ",[149,797,197],{"class":159},[149,799,170],{"class":159},[149,801,803,805,807],{"class":151,"line":802},38,[149,804,184],{"class":159},[149,806,258],{"class":166},[149,808,200],{"class":159},[149,810,812,814,816,819,821,824,827,829,831,833,835,838,840,843],{"class":151,"line":811},39,[149,813,430],{"class":166},[149,815,285],{"class":159},[149,817,818],{"class":226},"approve",[149,820,248],{"class":166},[149,822,823],{"class":159},"{",[149,825,826],{"class":275}," actualPath",[149,828,279],{"class":159},[149,830,190],{"class":159},[149,832,453],{"class":193},[149,834,197],{"class":159},[149,836,837],{"class":159}," }",[149,839,258],{"class":166},[149,841,842],{"class":159},";",[149,844,845],{"class":337}," \u002F\u002F after moving the actual over the baseline\n",[149,847,849,851,853,856,858,860,862,864,866,868],{"class":151,"line":848},40,[149,850,430],{"class":166},[149,852,285],{"class":159},[149,854,855],{"class":226},"dropTestFile",[149,857,248],{"class":166},[149,859,197],{"class":159},[149,861,496],{"class":193},[149,863,197],{"class":159},[149,865,258],{"class":166},[149,867,842],{"class":159},[149,869,870],{"class":337}," \u002F\u002F before re-running a file in an interactive runner\n",[149,872,874,876,878,881,883,885],{"class":151,"line":873},41,[149,875,430],{"class":166},[149,877,285],{"class":159},[149,879,880],{"class":226},"reset",[149,882,291],{"class":166},[149,884,842],{"class":159},[149,886,887],{"class":337}," \u002F\u002F start of a run: forget everything, delete the file\n",[99,889,890,893,894,897,898,901,902,905,906,909,910,912,913,916],{},[103,891,892],{},"ManifestBuilder"," is the same without the file (",[103,895,896],{},"toJSON()"," gives the manifest), and ",[103,899,900],{},"writeManifestFile"," is the atomic write on its own. The writer computes project-relative paths, ",[103,903,904],{},"null","s images that do not exist, hashes the ones that do, derives a ",[103,907,908],{},"native"," renderer from ",[103,911,673],{},", keeps ",[103,914,915],{},"summary"," up to date and sorts entries by test file and name.",[918,919,920],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":145,"searchDepth":163,"depth":163,"links":922},[],"Test-runner integrations use ManifestWriter:","md",null,{"generated":206},{"icon":73},{"title":70,"description":923},"3E7Fpo87qFG6NSE6BrCWABgFpZM-pMYW-FiysAh1fUo",[931,933],{"title":65,"path":66,"stem":67,"description":932,"icon":68,"children":-1},"A run usually produces several manifests.",{"title":75,"path":76,"stem":77,"description":934,"icon":78,"children":-1},"### CTRF",1791993875572]