[{"data":1,"prerenderedAt":1955},["ShallowReactive",2],{"navigation_docs":3,"-manifest-converting":93,"-manifest-converting-surround":1950},[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":75,"body":95,"description":1943,"extension":1944,"links":1945,"meta":1946,"navigation":1947,"path":76,"seo":1948,"stem":77,"__hash__":1949},"docs\u002F3.manifest\u002F6.converting.md",{"type":96,"value":97,"toc":1931},"minimark",[98,103,122,350,683,714,721,724,752,948,969,976,994,1086,1096,1100,1130,1230,1239,1242,1257,1344,1355,1359,1370,1505,1546,1550,1563,1712,1761,1765,1768,1903,1927],[99,100,102],"h2",{"id":101},"ctrf","CTRF",[104,105,106,112,113,117,118,121],"p",{},[107,108,102],"a",{"href":109,"rel":110},"https:\u002F\u002Fctrf.io",[111],"nofollow"," is the test results format a growing number of reporters write and CI integrations read (PR summaries, Slack messages, dashboards). A manifest becomes a CTRF report with one test of ",[114,115,116],"code",{},"type: \"visual\""," per entry, named after the screenshot, with the baseline, actual and diff images as attachments and everything CTRF has no field for under ",[114,119,120],{},"extra.visualRegression",":",[123,124,129],"pre",{"className":125,"code":126,"language":127,"meta":128,"style":128},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import fs from 'fs';\nimport { readManifestFile, toCtrf, fromCtrf } from 'visual-regression-manifest';\n\nconst manifest = readManifestFile('visual-regression-manifest.json');\nfs.writeFileSync('ctrf-report.json', JSON.stringify(toCtrf(manifest), null, 2));\n\n\u002F\u002F and back: a report made by `toCtrf` converts without loss\nconst same = fromCtrf(JSON.parse(fs.readFileSync('ctrf-report.json', 'utf8')));\n","ts","",[114,130,131,161,198,205,236,288,293,300],{"__ignoreMap":128},[132,133,136,140,144,147,151,155,158],"span",{"class":134,"line":135},"line",1,[132,137,139],{"class":138},"s7zQu","import",[132,141,143],{"class":142},"sTEyZ"," fs ",[132,145,146],{"class":138},"from",[132,148,150],{"class":149},"sMK4o"," '",[132,152,154],{"class":153},"sfazB","fs",[132,156,157],{"class":149},"'",[132,159,160],{"class":149},";\n",[132,162,164,166,169,172,175,178,180,183,186,189,191,194,196],{"class":134,"line":163},2,[132,165,139],{"class":138},[132,167,168],{"class":149}," {",[132,170,171],{"class":142}," readManifestFile",[132,173,174],{"class":149},",",[132,176,177],{"class":142}," toCtrf",[132,179,174],{"class":149},[132,181,182],{"class":142}," fromCtrf",[132,184,185],{"class":149}," }",[132,187,188],{"class":138}," from",[132,190,150],{"class":149},[132,192,193],{"class":153},"visual-regression-manifest",[132,195,157],{"class":149},[132,197,160],{"class":149},[132,199,201],{"class":134,"line":200},3,[132,202,204],{"emptyLinePlaceholder":203},true,"\n",[132,206,208,212,215,218,221,224,226,229,231,234],{"class":134,"line":207},4,[132,209,211],{"class":210},"spNyl","const",[132,213,214],{"class":142}," manifest ",[132,216,217],{"class":149},"=",[132,219,171],{"class":220},"s2Zo4",[132,222,223],{"class":142},"(",[132,225,157],{"class":149},[132,227,228],{"class":153},"visual-regression-manifest.json",[132,230,157],{"class":149},[132,232,233],{"class":142},")",[132,235,160],{"class":149},[132,237,239,241,244,247,249,251,254,256,258,261,263,266,268,271,274,276,279,283,286],{"class":134,"line":238},5,[132,240,154],{"class":142},[132,242,243],{"class":149},".",[132,245,246],{"class":220},"writeFileSync",[132,248,223],{"class":142},[132,250,157],{"class":149},[132,252,253],{"class":153},"ctrf-report.json",[132,255,157],{"class":149},[132,257,174],{"class":149},[132,259,260],{"class":142}," JSON",[132,262,243],{"class":149},[132,264,265],{"class":220},"stringify",[132,267,223],{"class":142},[132,269,270],{"class":220},"toCtrf",[132,272,273],{"class":142},"(manifest)",[132,275,174],{"class":149},[132,277,278],{"class":149}," null,",[132,280,282],{"class":281},"sbssI"," 2",[132,284,285],{"class":142},"))",[132,287,160],{"class":149},[132,289,291],{"class":134,"line":290},6,[132,292,204],{"emptyLinePlaceholder":203},[132,294,296],{"class":134,"line":295},7,[132,297,299],{"class":298},"sHwdD","\u002F\u002F and back: a report made by `toCtrf` converts without loss\n",[132,301,303,305,308,310,312,315,317,320,323,325,328,330,332,334,336,338,340,343,345,348],{"class":134,"line":302},8,[132,304,211],{"class":210},[132,306,307],{"class":142}," same ",[132,309,217],{"class":149},[132,311,182],{"class":220},[132,313,314],{"class":142},"(JSON",[132,316,243],{"class":149},[132,318,319],{"class":220},"parse",[132,321,322],{"class":142},"(fs",[132,324,243],{"class":149},[132,326,327],{"class":220},"readFileSync",[132,329,223],{"class":142},[132,331,157],{"class":149},[132,333,253],{"class":153},[132,335,157],{"class":149},[132,337,174],{"class":149},[132,339,150],{"class":149},[132,341,342],{"class":153},"utf8",[132,344,157],{"class":149},[132,346,347],{"class":142},")))",[132,349,160],{"class":149},[351,352,353,365],"table",{},[354,355,356],"thead",{},[357,358,359,363],"tr",{},[360,361,362],"th",{},"manifest",[360,364,102],{},[366,367,368,385,406,422,463,480,497,521,562,579,599,617,637,671],"tbody",{},[357,369,370,376],{},[371,372,373],"td",{},[114,374,375],{},"tool",[371,377,378,381,382],{},[114,379,380],{},"results.tool",", ",[114,383,384],{},"generatedBy",[357,386,387,395],{},[371,388,389,381,392],{},[114,390,391],{},"createdAt",[114,393,394],{},"updatedAt",[371,396,397,381,400,381,403],{},[114,398,399],{},"summary.start",[114,401,402],{},"summary.stop",[114,404,405],{},"timestamp",[357,407,408,413],{},[371,409,410],{},[114,411,412],{},"summary",[371,414,415,418,419],{},[114,416,417],{},"summary.tests\u002Fpassed\u002Ffailed"," (via the status table above); verbatim in ",[114,420,421],{},"summary.extra",[357,423,424,450],{},[371,425,426,381,429,381,432,381,435,381,438,381,441,381,444,381,447],{},[114,427,428],{},"ci.commit",[114,430,431],{},"branchName",[114,433,434],{},"repositoryName",[114,436,437],{},"repositoryUrl",[114,439,440],{},"buildId",[114,442,443],{},"buildName",[114,445,446],{},"buildNumber",[114,448,449],{},"buildUrl",[371,451,452,455,456,459,460],{},[114,453,454],{},"environment.\u003Csame name>","; ",[114,457,458],{},"ci.buildId"," also as the root ",[114,461,462],{},"runId",[357,464,465,476],{},[371,466,467,381,470,381,473],{},[114,468,469],{},"platform.osPlatform",[114,471,472],{},"osRelease",[114,474,475],{},"osVersion",[371,477,478],{},[114,479,454],{},[357,481,482,492],{},[371,483,484,485,488,489],{},"the rest of ",[114,486,487],{},"ci"," and ",[114,490,491],{},"platform",[371,493,494],{},[114,495,496],{},"environment.extra.visualRegression.{ci, platform}",[357,498,499,516],{},[371,500,501,381,504,381,507,381,510,381,513],{},[114,502,503],{},"specVersion",[114,505,506],{},"projectRoot",[114,508,509],{},"options",[114,511,512],{},"runner",[114,514,515],{},"upload",[371,517,518],{},[114,519,520],{},"results.extra.visualRegression",[357,522,523,544],{},[371,524,525,526,381,529,381,532,381,535,381,538,381,541],{},"entry ",[114,527,528],{},"name",[114,530,531],{},"test.titlePath",[114,533,534],{},"test.filePath",[114,536,537],{},"message",[114,539,540],{},"duration",[114,542,543],{},"test.retry",[371,545,546,381,549,381,552,381,555,381,557,381,559],{},[114,547,548],{},"test.name",[114,550,551],{},"suite",[114,553,554],{},"filePath",[114,556,537],{},[114,558,540],{},[114,560,561],{},"retries",[357,563,564,569],{},[371,565,566],{},[114,567,568],{},"status",[371,570,571,574,575,578],{},[114,572,573],{},"test.status"," (via the table) and ",[114,576,577],{},"test.rawStatus"," (verbatim)",[357,580,581,586],{},[371,582,583],{},[114,584,585],{},"recordedAt",[371,587,588,591,592,595,596,598],{},[114,589,590],{},"test.stop"," (and ",[114,593,594],{},"start"," when ",[114,597,540],{}," is known)",[357,600,601,609],{},[371,602,603,381,606],{},[114,604,605],{},"platform.browser",[114,607,608],{},"target.device.model",[371,610,611,381,614],{},[114,612,613],{},"test.browser",[114,615,616],{},"test.device",[357,618,619,627],{},[371,620,621,381,624],{},[114,622,623],{},"images.baseline\u002Factual\u002Fdiff",[114,625,626],{},"attachments",[371,628,629,632,633,636],{},[114,630,631],{},"test.attachments[]",", with ",[114,634,635],{},"extra.visualRegression.role",", sizes and hashes on the images",[357,638,639,666],{},[371,640,641,381,644,381,647,381,650,381,653,381,656,381,659,381,662,665],{},[114,642,643],{},"comparison",[114,645,646],{},"images",[114,648,649],{},"hashes",[114,651,652],{},"variant",[114,654,655],{},"renderer",[114,657,658],{},"target",[114,660,661],{},"subject",[114,663,664],{},"viewport",", ...",[371,667,668],{},[114,669,670],{},"test.extra.visualRegression",[357,672,673,680],{},[371,674,675,676,679],{},"any other ",[114,677,678],{},"extra"," namespace",[371,681,682],{},"the same namespace on the CTRF object",[104,684,685,688,689,691,692,695,696,699,700,381,703,488,706,709,710,713],{},[114,686,687],{},"fromCtrf"," reads reports made by ",[114,690,270],{}," back without loss (apart from the entry order, which is re-sorted, and the summary, which is recomputed). With ",[114,693,694],{},"{ lenient: true, projectRoot }"," it also converts the visual tests of reports from other reporters, taking the three images from attachments named or tagged ",[114,697,698],{},"baseline","\u002F",[114,701,702],{},"expected",[114,704,705],{},"actual",[114,707,708],{},"diff",", and the status from ",[114,711,712],{},"rawStatus"," or from which images exist.",[99,715,717,718],{"id":716},"playwrights-tohavescreenshot","Playwright's ",[114,719,720],{},"toHaveScreenshot",[104,722,723],{},"Run with the JSON reporter and convert the report:",[123,725,729],{"className":726,"code":727,"language":728,"meta":128,"style":128},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx playwright test --reporter=json > report.json\n","bash",[114,730,731],{"__ignoreMap":128},[132,732,733,737,740,743,746,749],{"class":134,"line":135},[132,734,736],{"class":735},"sBMFI","npx",[132,738,739],{"class":153}," playwright",[132,741,742],{"class":153}," test",[132,744,745],{"class":153}," --reporter=json",[132,747,748],{"class":149}," >",[132,750,751],{"class":153}," report.json\n",[123,753,755],{"className":125,"code":754,"language":127,"meta":128,"style":128},"import fs from 'fs';\nimport {\n  fromPlaywrightReport,\n  writeManifestFile,\n} from 'visual-regression-manifest';\n\nconst manifest = fromPlaywrightReport(\n  JSON.parse(fs.readFileSync('report.json', 'utf8')),\n  {\n    threshold: 0.01, \u002F\u002F your maxDiffPixelRatio, the report does not carry it\n    \u002F\u002F snapshotPathTemplate \u002F snapshotDir: only when changed in playwright.config\n    \u002F\u002F browsers: { chromium: { name: 'chromium', version: '130' } } for richer `platform` blocks\n  },\n);\nwriteManifestFile(\n  'test-results\u002Fvisual-regression-manifest.playwright.json',\n  manifest,\n);\n",[114,756,757,773,780,788,795,810,814,828,864,870,887,893,899,905,912,920,933,941],{"__ignoreMap":128},[132,758,759,761,763,765,767,769,771],{"class":134,"line":135},[132,760,139],{"class":138},[132,762,143],{"class":142},[132,764,146],{"class":138},[132,766,150],{"class":149},[132,768,154],{"class":153},[132,770,157],{"class":149},[132,772,160],{"class":149},[132,774,775,777],{"class":134,"line":163},[132,776,139],{"class":138},[132,778,779],{"class":149}," {\n",[132,781,782,785],{"class":134,"line":200},[132,783,784],{"class":142},"  fromPlaywrightReport",[132,786,787],{"class":149},",\n",[132,789,790,793],{"class":134,"line":207},[132,791,792],{"class":142},"  writeManifestFile",[132,794,787],{"class":149},[132,796,797,800,802,804,806,808],{"class":134,"line":238},[132,798,799],{"class":149},"}",[132,801,188],{"class":138},[132,803,150],{"class":149},[132,805,193],{"class":153},[132,807,157],{"class":149},[132,809,160],{"class":149},[132,811,812],{"class":134,"line":290},[132,813,204],{"emptyLinePlaceholder":203},[132,815,816,818,820,822,825],{"class":134,"line":295},[132,817,211],{"class":210},[132,819,214],{"class":142},[132,821,217],{"class":149},[132,823,824],{"class":220}," fromPlaywrightReport",[132,826,827],{"class":142},"(\n",[132,829,830,833,835,837,839,841,843,845,847,850,852,854,856,858,860,862],{"class":134,"line":302},[132,831,832],{"class":142},"  JSON",[132,834,243],{"class":149},[132,836,319],{"class":220},[132,838,322],{"class":142},[132,840,243],{"class":149},[132,842,327],{"class":220},[132,844,223],{"class":142},[132,846,157],{"class":149},[132,848,849],{"class":153},"report.json",[132,851,157],{"class":149},[132,853,174],{"class":149},[132,855,150],{"class":149},[132,857,342],{"class":153},[132,859,157],{"class":149},[132,861,285],{"class":142},[132,863,787],{"class":149},[132,865,867],{"class":134,"line":866},9,[132,868,869],{"class":149},"  {\n",[132,871,873,877,879,882,884],{"class":134,"line":872},10,[132,874,876],{"class":875},"swJcz","    threshold",[132,878,121],{"class":149},[132,880,881],{"class":281}," 0.01",[132,883,174],{"class":149},[132,885,886],{"class":298}," \u002F\u002F your maxDiffPixelRatio, the report does not carry it\n",[132,888,890],{"class":134,"line":889},11,[132,891,892],{"class":298},"    \u002F\u002F snapshotPathTemplate \u002F snapshotDir: only when changed in playwright.config\n",[132,894,896],{"class":134,"line":895},12,[132,897,898],{"class":298},"    \u002F\u002F browsers: { chromium: { name: 'chromium', version: '130' } } for richer `platform` blocks\n",[132,900,902],{"class":134,"line":901},13,[132,903,904],{"class":149},"  },\n",[132,906,908,910],{"class":134,"line":907},14,[132,909,233],{"class":142},[132,911,160],{"class":149},[132,913,915,918],{"class":134,"line":914},15,[132,916,917],{"class":220},"writeManifestFile",[132,919,827],{"class":142},[132,921,923,926,929,931],{"class":134,"line":922},16,[132,924,925],{"class":149},"  '",[132,927,928],{"class":153},"test-results\u002Fvisual-regression-manifest.playwright.json",[132,930,157],{"class":149},[132,932,787],{"class":149},[132,934,936,939],{"class":134,"line":935},17,[132,937,938],{"class":142},"  manifest",[132,940,787],{"class":149},[132,942,944,946],{"class":134,"line":943},18,[132,945,233],{"class":142},[132,947,160],{"class":149},[104,949,950,951,954,955,488,958,961,962,964,965,968],{},"Only comparisons that left files behind can be recovered: ",[114,952,953],{},"failed"," (expected, actual and diff attachments), ",[114,956,957],{},"missing-baseline",[114,959,960],{},"created"," (actual only). A passing ",[114,963,720],{}," leaves no trace in the report, and of a retried test only the last attempt counts. Baseline paths are computed from the snapshot path template because the report only lists the copies in ",[114,966,967],{},"test-results","; the diff ratio is parsed from the assertion message.",[99,970,972,973],{"id":971},"vitests-tomatchscreenshot","Vitest's ",[114,974,975],{},"toMatchScreenshot",[104,977,978,979,982,983,488,986,989,990,993],{},"Vitest (browser mode) keeps references in ",[114,980,981],{},"__screenshots__\u002F\u003Ctest file>\u002F"," next to the tests and writes ",[114,984,985],{},"\u003Cname>-actual.png",[114,987,988],{},"\u003Cname>-diff.png"," under ",[114,991,992],{},".vitest\u002Fattachments\u002F\u003Ctest file>\u002F"," for failed comparisons. The converter scans the project for both:",[123,995,997],{"className":125,"code":996,"language":127,"meta":128,"style":128},"import { fromVitestScreenshots } from 'visual-regression-manifest';\n\nconst manifest = fromVitestScreenshots({\n  projectRoot: process.cwd(),\n  threshold: 0.01, \u002F\u002F your allowedMismatchedPixelRatio\n  \u002F\u002F roots: ['src', 'tests'], screenshotsDirName, attachmentsDir: when changed\n});\n",[114,998,999,1020,1024,1039,1059,1073,1078],{"__ignoreMap":128},[132,1000,1001,1003,1005,1008,1010,1012,1014,1016,1018],{"class":134,"line":135},[132,1002,139],{"class":138},[132,1004,168],{"class":149},[132,1006,1007],{"class":142}," fromVitestScreenshots",[132,1009,185],{"class":149},[132,1011,188],{"class":138},[132,1013,150],{"class":149},[132,1015,193],{"class":153},[132,1017,157],{"class":149},[132,1019,160],{"class":149},[132,1021,1022],{"class":134,"line":163},[132,1023,204],{"emptyLinePlaceholder":203},[132,1025,1026,1028,1030,1032,1034,1036],{"class":134,"line":200},[132,1027,211],{"class":210},[132,1029,214],{"class":142},[132,1031,217],{"class":149},[132,1033,1007],{"class":220},[132,1035,223],{"class":142},[132,1037,1038],{"class":149},"{\n",[132,1040,1041,1044,1046,1049,1051,1054,1057],{"class":134,"line":207},[132,1042,1043],{"class":875},"  projectRoot",[132,1045,121],{"class":149},[132,1047,1048],{"class":142}," process",[132,1050,243],{"class":149},[132,1052,1053],{"class":220},"cwd",[132,1055,1056],{"class":142},"()",[132,1058,787],{"class":149},[132,1060,1061,1064,1066,1068,1070],{"class":134,"line":238},[132,1062,1063],{"class":875},"  threshold",[132,1065,121],{"class":149},[132,1067,881],{"class":281},[132,1069,174],{"class":149},[132,1071,1072],{"class":298}," \u002F\u002F your allowedMismatchedPixelRatio\n",[132,1074,1075],{"class":134,"line":290},[132,1076,1077],{"class":298},"  \u002F\u002F roots: ['src', 'tests'], screenshotsDirName, attachmentsDir: when changed\n",[132,1079,1080,1082,1084],{"class":134,"line":295},[132,1081,799],{"class":149},[132,1083,233],{"class":142},[132,1085,160],{"class":149},[104,1087,1088,1089,1091,1092,1095],{},"A reference without attachments passed, attachments without a reference are ",[114,1090,957],{},", and the browser and platform are read off the file name (",[114,1093,1094],{},"button-chromium-darwin",").",[99,1097,1099],{"id":1098},"jest-image-snapshot-and-cypress-image-snapshot","jest-image-snapshot and cypress-image-snapshot",[104,1101,1102,1103,1106,1107,1110,1111,1114,1115,1118,1119,1122,1123,595,1126,1129],{},"Baselines are ",[114,1104,1105],{},"\u003Cid>-snap.png"," in ",[114,1108,1109],{},"__image_snapshots__\u002F","; failures leave ",[114,1112,1113],{},"\u003Cid>-diff.png"," (a baseline | diff | received composite unless ",[114,1116,1117],{},"onlyDiff",") in ",[114,1120,1121],{},"__image_snapshots__\u002F__diff_output__\u002F",", plus ",[114,1124,1125],{},"\u003Cid>-received.png",[114,1127,1128],{},"storeReceivedOnFailure"," is on:",[123,1131,1133],{"className":125,"code":1132,"language":127,"meta":128,"style":128},"import { fromJestImageSnapshots } from 'visual-regression-manifest';\n\nconst manifest = fromJestImageSnapshots({\n  projectRoot: process.cwd(),\n  runner: { name: 'cypress' }, \u002F\u002F for cypress-image-snapshot; defaults to jest\n  \u002F\u002F snapshotsDirName, diffDirName, receivedDirName, snapshotPostfix, diffPostfix, receivedPostfix: when customised\n});\n",[114,1134,1135,1156,1160,1174,1190,1217,1222],{"__ignoreMap":128},[132,1136,1137,1139,1141,1144,1146,1148,1150,1152,1154],{"class":134,"line":135},[132,1138,139],{"class":138},[132,1140,168],{"class":149},[132,1142,1143],{"class":142}," fromJestImageSnapshots",[132,1145,185],{"class":149},[132,1147,188],{"class":138},[132,1149,150],{"class":149},[132,1151,193],{"class":153},[132,1153,157],{"class":149},[132,1155,160],{"class":149},[132,1157,1158],{"class":134,"line":163},[132,1159,204],{"emptyLinePlaceholder":203},[132,1161,1162,1164,1166,1168,1170,1172],{"class":134,"line":200},[132,1163,211],{"class":210},[132,1165,214],{"class":142},[132,1167,217],{"class":149},[132,1169,1143],{"class":220},[132,1171,223],{"class":142},[132,1173,1038],{"class":149},[132,1175,1176,1178,1180,1182,1184,1186,1188],{"class":134,"line":207},[132,1177,1043],{"class":875},[132,1179,121],{"class":149},[132,1181,1048],{"class":142},[132,1183,243],{"class":149},[132,1185,1053],{"class":220},[132,1187,1056],{"class":142},[132,1189,787],{"class":149},[132,1191,1192,1195,1197,1199,1202,1204,1206,1209,1211,1214],{"class":134,"line":238},[132,1193,1194],{"class":875},"  runner",[132,1196,121],{"class":149},[132,1198,168],{"class":149},[132,1200,1201],{"class":875}," name",[132,1203,121],{"class":149},[132,1205,150],{"class":149},[132,1207,1208],{"class":153},"cypress",[132,1210,157],{"class":149},[132,1212,1213],{"class":149}," },",[132,1215,1216],{"class":298}," \u002F\u002F for cypress-image-snapshot; defaults to jest\n",[132,1218,1219],{"class":134,"line":290},[132,1220,1221],{"class":298},"  \u002F\u002F snapshotsDirName, diffDirName, receivedDirName, snapshotPostfix, diffPostfix, receivedPostfix: when customised\n",[132,1223,1224,1226,1228],{"class":134,"line":295},[132,1225,799],{"class":149},[132,1227,233],{"class":142},[132,1229,160],{"class":149},[104,1231,1232,1233,1235,1236,1238],{},"The received image is the entry's ",[114,1234,705],{}," when it exists; the diff composite is the entry's ",[114,1237,708],{}," image either way.",[99,1240,1241],{"id":1241},"cypress-visual-regression",[104,1243,1244,1245,381,1248,488,1250,1252,1253,1256],{},"Reads the ",[114,1246,1247],{},"base",[114,1249,705],{},[114,1251,708],{}," folders (",[114,1254,1255],{},"cypress\u002Fsnapshots\u002F..."," by default), nested by spec file:",[123,1258,1260],{"className":125,"code":1259,"language":127,"meta":128,"style":128},"import { fromCypressVisualRegression } from 'visual-regression-manifest';\n\nconst manifest = fromCypressVisualRegression({\n  projectRoot: process.cwd(),\n  threshold: 0.05, \u002F\u002F your errorThreshold\n  \u002F\u002F baseDirectory, actualDirectory, diffDirectory, generateDiff: when changed\n});\n",[114,1261,1262,1283,1287,1301,1317,1331,1336],{"__ignoreMap":128},[132,1263,1264,1266,1268,1271,1273,1275,1277,1279,1281],{"class":134,"line":135},[132,1265,139],{"class":138},[132,1267,168],{"class":149},[132,1269,1270],{"class":142}," fromCypressVisualRegression",[132,1272,185],{"class":149},[132,1274,188],{"class":138},[132,1276,150],{"class":149},[132,1278,193],{"class":153},[132,1280,157],{"class":149},[132,1282,160],{"class":149},[132,1284,1285],{"class":134,"line":163},[132,1286,204],{"emptyLinePlaceholder":203},[132,1288,1289,1291,1293,1295,1297,1299],{"class":134,"line":200},[132,1290,211],{"class":210},[132,1292,214],{"class":142},[132,1294,217],{"class":149},[132,1296,1270],{"class":220},[132,1298,223],{"class":142},[132,1300,1038],{"class":149},[132,1302,1303,1305,1307,1309,1311,1313,1315],{"class":134,"line":207},[132,1304,1043],{"class":875},[132,1306,121],{"class":149},[132,1308,1048],{"class":142},[132,1310,243],{"class":149},[132,1312,1053],{"class":220},[132,1314,1056],{"class":142},[132,1316,787],{"class":149},[132,1318,1319,1321,1323,1326,1328],{"class":134,"line":238},[132,1320,1063],{"class":875},[132,1322,121],{"class":149},[132,1324,1325],{"class":281}," 0.05",[132,1327,174],{"class":149},[132,1329,1330],{"class":298}," \u002F\u002F your errorThreshold\n",[132,1332,1333],{"class":134,"line":290},[132,1334,1335],{"class":298},"  \u002F\u002F baseDirectory, actualDirectory, diffDirectory, generateDiff: when changed\n",[132,1337,1338,1340,1342],{"class":134,"line":295},[132,1339,799],{"class":149},[132,1341,233],{"class":142},[132,1343,160],{"class":149},[104,1345,1346,1347,1350,1351,1354],{},"Cypress writes an actual image for every comparison, so a diff image is what marks a failure (",[114,1348,1349],{},"visualRegressionGenerateDiff: 'fail'",", the default); pass ",[114,1352,1353],{},"generateDiff"," when the run used another mode.",[99,1356,1358],{"id":1357},"backstopjs","BackstopJS",[104,1360,1361,1362,1365,1366,1369],{},"With ",[114,1363,1364],{},"\"report\": [\"json\"]"," BackstopJS writes ",[114,1367,1368],{},"backstop_data\u002Fjson_report\u002FjsonReport.json",". Its paths are relative to that directory:",[123,1371,1373],{"className":125,"code":1372,"language":127,"meta":128,"style":128},"import fs from 'fs';\nimport { fromBackstopReport } from 'visual-regression-manifest';\n\nconst manifest = fromBackstopReport(\n  JSON.parse(\n    fs.readFileSync('backstop_data\u002Fjson_report\u002FjsonReport.json', 'utf8'),\n  ),\n  { projectRoot: process.cwd() }, \u002F\u002F reportDir: when json_report was moved\n);\n",[114,1374,1375,1391,1412,1416,1428,1438,1467,1474,1499],{"__ignoreMap":128},[132,1376,1377,1379,1381,1383,1385,1387,1389],{"class":134,"line":135},[132,1378,139],{"class":138},[132,1380,143],{"class":142},[132,1382,146],{"class":138},[132,1384,150],{"class":149},[132,1386,154],{"class":153},[132,1388,157],{"class":149},[132,1390,160],{"class":149},[132,1392,1393,1395,1397,1400,1402,1404,1406,1408,1410],{"class":134,"line":163},[132,1394,139],{"class":138},[132,1396,168],{"class":149},[132,1398,1399],{"class":142}," fromBackstopReport",[132,1401,185],{"class":149},[132,1403,188],{"class":138},[132,1405,150],{"class":149},[132,1407,193],{"class":153},[132,1409,157],{"class":149},[132,1411,160],{"class":149},[132,1413,1414],{"class":134,"line":200},[132,1415,204],{"emptyLinePlaceholder":203},[132,1417,1418,1420,1422,1424,1426],{"class":134,"line":207},[132,1419,211],{"class":210},[132,1421,214],{"class":142},[132,1423,217],{"class":149},[132,1425,1399],{"class":220},[132,1427,827],{"class":142},[132,1429,1430,1432,1434,1436],{"class":134,"line":238},[132,1431,832],{"class":142},[132,1433,243],{"class":149},[132,1435,319],{"class":220},[132,1437,827],{"class":142},[132,1439,1440,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461,1463,1465],{"class":134,"line":290},[132,1441,1442],{"class":142},"    fs",[132,1444,243],{"class":149},[132,1446,327],{"class":220},[132,1448,223],{"class":142},[132,1450,157],{"class":149},[132,1452,1368],{"class":153},[132,1454,157],{"class":149},[132,1456,174],{"class":149},[132,1458,150],{"class":149},[132,1460,342],{"class":153},[132,1462,157],{"class":149},[132,1464,233],{"class":142},[132,1466,787],{"class":149},[132,1468,1469,1472],{"class":134,"line":295},[132,1470,1471],{"class":142},"  )",[132,1473,787],{"class":149},[132,1475,1476,1479,1482,1484,1486,1488,1490,1493,1496],{"class":134,"line":302},[132,1477,1478],{"class":149},"  {",[132,1480,1481],{"class":875}," projectRoot",[132,1483,121],{"class":149},[132,1485,1048],{"class":142},[132,1487,243],{"class":149},[132,1489,1053],{"class":220},[132,1491,1492],{"class":142},"() ",[132,1494,1495],{"class":149},"},",[132,1497,1498],{"class":298}," \u002F\u002F reportDir: when json_report was moved\n",[132,1500,1501,1503],{"class":134,"line":866},[132,1502,233],{"class":142},[132,1504,160],{"class":149},[104,1506,1507,1508,381,1511,1514,1515,381,1518,1521,1522,1525,1526,1529,1530,1532,1533,381,1536,1539,1540,1542,1543,243],{},"One entry per scenario and viewport (",[114,1509,1510],{},"titlePath: [label, viewportLabel]",[114,1512,1513],{},"variant: viewportLabel","), the mismatch percentage as ",[114,1516,1517],{},"diffRatio",[114,1519,1520],{},"misMatchThreshold"," as ",[114,1523,1524],{},"threshold",", a ",[114,1527,1528],{},"Reference file not found"," error as ",[114,1531,957],{},", and the scenario's ",[114,1534,1535],{},"url",[114,1537,1538],{},"selector"," and the raw ",[114,1541,708],{}," block under ",[114,1544,1545],{},"extra.backstop",[99,1547,1549],{"id":1548},"roborazzi","Roborazzi",[104,1551,1552,488,1555,1558,1559,1562],{},[114,1553,1554],{},"compareRoborazzi*",[114,1556,1557],{},"recordRoborazzi*"," write ",[114,1560,1561],{},"build\u002Ftest-results\u002Froborazzi\u002F\u003Cvariant>\u002Fresults-summary.json"," with absolute paths:",[123,1564,1566],{"className":125,"code":1565,"language":127,"meta":128,"style":128},"import fs from 'fs';\nimport { fromRoborazziResults } from 'visual-regression-manifest';\n\nconst manifest = fromRoborazziResults(\n  JSON.parse(\n    fs.readFileSync(\n      'build\u002Ftest-results\u002Froborazzi\u002Fdebug\u002Fresults-summary.json',\n      'utf8',\n    ),\n  ),\n  { projectRoot: process.cwd(), threshold: 0.01 }, \u002F\u002F your changeThreshold\n);\n",[114,1567,1568,1584,1605,1609,1621,1631,1641,1653,1663,1670,1676,1706],{"__ignoreMap":128},[132,1569,1570,1572,1574,1576,1578,1580,1582],{"class":134,"line":135},[132,1571,139],{"class":138},[132,1573,143],{"class":142},[132,1575,146],{"class":138},[132,1577,150],{"class":149},[132,1579,154],{"class":153},[132,1581,157],{"class":149},[132,1583,160],{"class":149},[132,1585,1586,1588,1590,1593,1595,1597,1599,1601,1603],{"class":134,"line":163},[132,1587,139],{"class":138},[132,1589,168],{"class":149},[132,1591,1592],{"class":142}," fromRoborazziResults",[132,1594,185],{"class":149},[132,1596,188],{"class":138},[132,1598,150],{"class":149},[132,1600,193],{"class":153},[132,1602,157],{"class":149},[132,1604,160],{"class":149},[132,1606,1607],{"class":134,"line":200},[132,1608,204],{"emptyLinePlaceholder":203},[132,1610,1611,1613,1615,1617,1619],{"class":134,"line":207},[132,1612,211],{"class":210},[132,1614,214],{"class":142},[132,1616,217],{"class":149},[132,1618,1592],{"class":220},[132,1620,827],{"class":142},[132,1622,1623,1625,1627,1629],{"class":134,"line":238},[132,1624,832],{"class":142},[132,1626,243],{"class":149},[132,1628,319],{"class":220},[132,1630,827],{"class":142},[132,1632,1633,1635,1637,1639],{"class":134,"line":290},[132,1634,1442],{"class":142},[132,1636,243],{"class":149},[132,1638,327],{"class":220},[132,1640,827],{"class":142},[132,1642,1643,1646,1649,1651],{"class":134,"line":295},[132,1644,1645],{"class":149},"      '",[132,1647,1648],{"class":153},"build\u002Ftest-results\u002Froborazzi\u002Fdebug\u002Fresults-summary.json",[132,1650,157],{"class":149},[132,1652,787],{"class":149},[132,1654,1655,1657,1659,1661],{"class":134,"line":302},[132,1656,1645],{"class":149},[132,1658,342],{"class":153},[132,1660,157],{"class":149},[132,1662,787],{"class":149},[132,1664,1665,1668],{"class":134,"line":866},[132,1666,1667],{"class":142},"    )",[132,1669,787],{"class":149},[132,1671,1672,1674],{"class":134,"line":872},[132,1673,1471],{"class":142},[132,1675,787],{"class":149},[132,1677,1678,1680,1682,1684,1686,1688,1690,1692,1694,1697,1699,1701,1703],{"class":134,"line":889},[132,1679,1478],{"class":149},[132,1681,1481],{"class":875},[132,1683,121],{"class":149},[132,1685,1048],{"class":142},[132,1687,243],{"class":149},[132,1689,1053],{"class":220},[132,1691,1056],{"class":142},[132,1693,174],{"class":149},[132,1695,1696],{"class":875}," threshold",[132,1698,121],{"class":149},[132,1700,881],{"class":281},[132,1702,1213],{"class":149},[132,1704,1705],{"class":298}," \u002F\u002F your changeThreshold\n",[132,1707,1708,1710],{"class":134,"line":895},[132,1709,233],{"class":142},[132,1711,160],{"class":149},[104,1713,1714,1717,1718,1720,1721,1724,1725,1728,1729,1717,1732,381,1734,1717,1737,488,1740,1717,1743,1746,1747,1749,1750,1753,1754,1757,1758,243],{},[114,1715,1716],{},"changed"," is ",[114,1719,953],{}," (with ",[114,1722,1723],{},"diff_percentage"," as the ratio and the ",[114,1726,1727],{},"_compare"," composite as the diff image), ",[114,1730,1731],{},"added",[114,1733,957],{},[114,1735,1736],{},"unchanged",[114,1738,1739],{},"passed",[114,1741,1742],{},"recorded",[114,1744,1745],{},"updated",". Entries carry an emulated Android ",[114,1748,658],{}," and a ",[114,1751,1752],{},"robolectric"," renderer; ",[114,1755,1756],{},"context_data"," lands under ",[114,1759,1760],{},"extra.roborazzi",[99,1762,1764],{"id":1763},"plain-image-files","Plain image files",[104,1766,1767],{},"For any tool that leaves a baseline and, on failure, an actual and a diff image next to it:",[123,1769,1771],{"className":125,"code":1770,"language":127,"meta":128,"style":128},"import { fromImageTriples } from 'visual-regression-manifest';\n\nconst manifest = fromImageTriples({\n  projectRoot: process.cwd(),\n  runner: { name: 'my-tool' },\n  triples: baselines.map((baseline) => ({ baseline })), \u002F\u002F actual\u002Fdiff default to `.actual`\u002F`.diff` siblings\n});\n",[114,1772,1773,1794,1798,1812,1828,1850,1895],{"__ignoreMap":128},[132,1774,1775,1777,1779,1782,1784,1786,1788,1790,1792],{"class":134,"line":135},[132,1776,139],{"class":138},[132,1778,168],{"class":149},[132,1780,1781],{"class":142}," fromImageTriples",[132,1783,185],{"class":149},[132,1785,188],{"class":138},[132,1787,150],{"class":149},[132,1789,193],{"class":153},[132,1791,157],{"class":149},[132,1793,160],{"class":149},[132,1795,1796],{"class":134,"line":163},[132,1797,204],{"emptyLinePlaceholder":203},[132,1799,1800,1802,1804,1806,1808,1810],{"class":134,"line":200},[132,1801,211],{"class":210},[132,1803,214],{"class":142},[132,1805,217],{"class":149},[132,1807,1781],{"class":220},[132,1809,223],{"class":142},[132,1811,1038],{"class":149},[132,1813,1814,1816,1818,1820,1822,1824,1826],{"class":134,"line":207},[132,1815,1043],{"class":875},[132,1817,121],{"class":149},[132,1819,1048],{"class":142},[132,1821,243],{"class":149},[132,1823,1053],{"class":220},[132,1825,1056],{"class":142},[132,1827,787],{"class":149},[132,1829,1830,1832,1834,1836,1838,1840,1842,1845,1847],{"class":134,"line":238},[132,1831,1194],{"class":875},[132,1833,121],{"class":149},[132,1835,168],{"class":149},[132,1837,1201],{"class":875},[132,1839,121],{"class":149},[132,1841,150],{"class":149},[132,1843,1844],{"class":153},"my-tool",[132,1846,157],{"class":149},[132,1848,1849],{"class":149}," },\n",[132,1851,1852,1855,1857,1860,1862,1865,1867,1869,1872,1874,1877,1880,1883,1886,1888,1890,1892],{"class":134,"line":290},[132,1853,1854],{"class":875},"  triples",[132,1856,121],{"class":149},[132,1858,1859],{"class":142}," baselines",[132,1861,243],{"class":149},[132,1863,1864],{"class":220},"map",[132,1866,223],{"class":142},[132,1868,223],{"class":149},[132,1870,698],{"class":1871},"sHdIc",[132,1873,233],{"class":149},[132,1875,1876],{"class":210}," =>",[132,1878,1879],{"class":142}," (",[132,1881,1882],{"class":149},"{",[132,1884,1885],{"class":142}," baseline ",[132,1887,799],{"class":149},[132,1889,285],{"class":142},[132,1891,174],{"class":149},[132,1893,1894],{"class":298}," \u002F\u002F actual\u002Fdiff default to `.actual`\u002F`.diff` siblings\n",[132,1896,1897,1899,1901],{"class":134,"line":295},[132,1898,799],{"class":149},[132,1900,233],{"class":142},[132,1902,160],{"class":149},[104,1904,1905,1906,1909,1910,381,1912,381,1914,381,1916,381,1919,381,1922,381,1924,1926],{},"The status is inferred from which files exist (",[114,1907,1908],{},"inferStatus","), image sizes are read from the PNG headers, and every field can be given explicitly (",[114,1911,705],{},[114,1913,708],{},[114,1915,528],{},[114,1917,1918],{},"testFile",[114,1920,1921],{},"titlePath",[114,1923,568],{},[114,1925,1517],{},", ...).",[1928,1929,1930],"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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .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);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":128,"searchDepth":163,"depth":163,"links":1932},[1933,1934,1936,1938,1939,1940,1941,1942],{"id":101,"depth":163,"text":102},{"id":716,"depth":163,"text":1935},"Playwright's toHaveScreenshot",{"id":971,"depth":163,"text":1937},"Vitest's toMatchScreenshot",{"id":1098,"depth":163,"text":1099},{"id":1241,"depth":163,"text":1241},{"id":1357,"depth":163,"text":1358},{"id":1548,"depth":163,"text":1549},{"id":1763,"depth":163,"text":1764},"### CTRF","md",null,{"generated":203},{"icon":78},{"title":75,"description":1943},"gUVTW5eWSEazBwcWNnSD4zW-67x0atQRgHVIyWCJ4iw",[1951,1953],{"title":70,"path":71,"stem":72,"description":1952,"icon":73,"children":-1},"Test-runner integrations use ManifestWriter:",{"title":80,"path":81,"stem":82,"description":1954,"icon":83,"children":-1},"| export                                                                                                                                                        ",1791993875572]