storybook-addon-vis 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vitest-plugin.js +1 -1
- package/dist/vitest-plugin.js.map +1 -1
- package/dist/vitest-setup.js +2 -2
- package/dist/vitest-setup.js.map +1 -1
- package/package.json +1 -5
- package/readme.md +5 -4
- package/src/vitest-plugin/commands/get_snapshot_platform.ts +1 -1
- package/src/vitest-setup.spec.ts +7 -4
- package/src/vitest-setup.ts +4 -1
package/dist/vitest-plugin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {copyFile,stat}from'node:fs/promises';import {mkdirp}from'mkdirp';import {join,dirname}from'pathe';import u from'is-ci';import {rimraf}from'rimraf';var s=async({testPath:o,provider:r},t,i)=>{if(r.name==="playwright"){let e=join(dirname(o),i),d=dirname(e);return await mkdirp(d),copyFile(join(dirname(o),t),e)}throw new Error(`provider ${r.name} is not supported`)};var p=async({testPath:o,provider:r},t)=>{if(r.name==="playwright")return stat(join(dirname(o),t)).then(i=>i.isDirectory()).catch(()=>!1);throw new Error(`provider ${r.name} is not supported`)};var a=async()=>`${process.platform
|
|
1
|
+
import {copyFile,stat}from'node:fs/promises';import {mkdirp}from'mkdirp';import {join,dirname}from'pathe';import u from'is-ci';import {rimraf}from'rimraf';var s=async({testPath:o,provider:r},t,i)=>{if(r.name==="playwright"){let e=join(dirname(o),i),d=dirname(e);return await mkdirp(d),copyFile(join(dirname(o),t),e)}throw new Error(`provider ${r.name} is not supported`)};var p=async({testPath:o,provider:r},t)=>{if(r.name==="playwright")return stat(join(dirname(o),t)).then(i=>i.isDirectory()).catch(()=>!1);throw new Error(`provider ${r.name} is not supported`)};var a=async()=>`${u?process.platform:"local"}`;var f=async()=>u;var c=async({testPath:o,provider:r},t)=>{if(r.name==="playwright")return rimraf(join(dirname(o),t));throw new Error(`provider ${r.name} is not supported`)};function M(){return {name:"vitest:storybook-addon-vis",config(){return {test:{browser:{name:"chromium",commands:{existDir:p,copyFile:s,rmDir:c,isCI:f,getSnapshotPlatform:a}}}}}}}export{M as storybookVis};//# sourceMappingURL=vitest-plugin.js.map
|
|
2
2
|
//# sourceMappingURL=vitest-plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vitest-plugin/commands/copy_file.ts","../src/vitest-plugin/commands/exist_dir.ts","../src/vitest-plugin/commands/get_snapshot_platform.ts","../src/vitest-plugin/commands/is_ci.ts","../src/vitest-plugin/commands/rm_dir.ts","../src/vitest-plugin.ts"],"names":["copyFile","testPath","provider","src","dest","destPath","join","dirname","destDir","mkdirp","copyFileFs","existDir","path","stat","s","getSnapshotPlatform","ci","isCI","rmDir","rimraf","storybookVis"],"mappings":"2JAKO,IAAMA,CAAwD,CAAA,MAAO,CAAE,QAAA,CAAAC,EAAU,QAAAC,CAAAA,CAAS,CAAGC,CAAAA,CAAAA,CAAKC,CAAS,GAAA,CACjH,GAAIF,CAAS,CAAA,IAAA,GAAS,
|
|
1
|
+
{"version":3,"sources":["../src/vitest-plugin/commands/copy_file.ts","../src/vitest-plugin/commands/exist_dir.ts","../src/vitest-plugin/commands/get_snapshot_platform.ts","../src/vitest-plugin/commands/is_ci.ts","../src/vitest-plugin/commands/rm_dir.ts","../src/vitest-plugin.ts"],"names":["copyFile","testPath","provider","src","dest","destPath","join","dirname","destDir","mkdirp","copyFileFs","existDir","path","stat","s","getSnapshotPlatform","ci","isCI","rmDir","rimraf","storybookVis"],"mappings":"2JAKO,IAAMA,CAAwD,CAAA,MAAO,CAAE,QAAA,CAAAC,EAAU,QAAAC,CAAAA,CAAS,CAAGC,CAAAA,CAAAA,CAAKC,CAAS,GAAA,CACjH,GAAIF,CAAS,CAAA,IAAA,GAAS,aAAc,CACnC,IAAMG,EAAWC,IAAKC,CAAAA,OAAAA,CAAQN,CAAQ,CAAA,CAAGG,CAAI,CAAA,CACvCI,EAAUD,OAAQF,CAAAA,CAAQ,CAChC,CAAA,OAAA,MAAMI,MAAOD,CAAAA,CAAO,EACbE,QAAWJ,CAAAA,IAAAA,CAAKC,OAAQN,CAAAA,CAAQ,CAAGE,CAAAA,CAAG,EAAGE,CAAQ,CACzD,CAEA,MAAM,IAAI,MAAM,CAAYH,SAAAA,EAAAA,CAAAA,CAAS,IAAI,CAAA,iBAAA,CAAmB,CAC7D,CAAA,CCVO,IAAMS,CAAAA,CAA2C,MAAO,CAAE,SAAAV,CAAU,CAAA,QAAA,CAAAC,CAAS,CAAA,CAAGU,CAAS,GAAA,CAC/F,GAAIV,CAAS,CAAA,IAAA,GAAS,YACrB,CAAA,OAAOW,IAAKP,CAAAA,IAAAA,CAAKC,QAAQN,CAAQ,CAAA,CAAGW,CAAI,CAAC,CACvC,CAAA,IAAA,CAAME,GAAMA,CAAE,CAAA,WAAA,EAAa,CAAA,CAC3B,KAAM,CAAA,IAAM,EAAK,CAGpB,CAAA,MAAM,IAAI,KAAM,CAAA,CAAA,SAAA,EAAYZ,EAAS,IAAI,CAAA,iBAAA,CAAmB,CAC7D,CAAA,CCVO,IAAMa,CAAAA,CAAsB,SAC3B,CAAA,EAAGC,CAAK,CAAA,OAAA,CAAQ,SAAW,OAAO,CAAA,CAAA,CCDnC,IAAMC,EAAO,SAAYD,CAAAA,CCEzB,IAAME,CAAwC,CAAA,MAAO,CAAE,QAAA,CAAAjB,CAAU,CAAA,QAAA,CAAAC,CAAS,CAAGU,CAAAA,CAAAA,GAAS,CAC5F,GAAIV,CAAS,CAAA,IAAA,GAAS,aACrB,OAAOiB,MAAAA,CAAOb,KAAKC,OAAQN,CAAAA,CAAQ,EAAGW,CAAI,CAAC,CAG5C,CAAA,MAAM,IAAI,KAAA,CAAM,YAAYV,CAAS,CAAA,IAAI,CAAmB,iBAAA,CAAA,CAC7D,CCFO,CAAA,SAASkB,GAAe,CAC9B,OAAO,CACN,IAAA,CAAM,4BACN,CAAA,MAAA,EAAS,CACR,OAAO,CACN,IAAM,CAAA,CACL,OAAS,CAAA,CACR,KAAM,UACN,CAAA,QAAA,CAAU,CACT,QAAA,CAAAT,CACA,CAAA,QAAA,CAAAX,EACA,KAAAkB,CAAAA,CAAAA,CACA,IAAAD,CAAAA,CAAAA,CACA,mBAAAF,CAAAA,CACD,CACD,CACD,CACD,CACD,CACD,CACD","file":"vitest-plugin.js","sourcesContent":["import { copyFile as copyFileFs } from 'node:fs/promises'\nimport { mkdirp } from 'mkdirp'\nimport { dirname, join } from 'pathe'\nimport type { BrowserCommand } from 'vitest/node'\n\nexport const copyFile: BrowserCommand<[src: string, dest: string]> = async ({ testPath, provider }, src, dest) => {\n\tif (provider.name === 'playwright') {\n\t\tconst destPath = join(dirname(testPath), dest)\n\t\tconst destDir = dirname(destPath)\n\t\tawait mkdirp(destDir)\n\t\treturn copyFileFs(join(dirname(testPath), src), destPath)\n\t}\n\n\tthrow new Error(`provider ${provider.name} is not supported`)\n}\n","import { stat } from 'node:fs/promises'\nimport { dirname, join } from 'pathe'\nimport type { BrowserCommand } from 'vitest/node'\n\nexport const existDir: BrowserCommand<[path: string]> = async ({ testPath, provider }, path) => {\n\tif (provider.name === 'playwright') {\n\t\treturn stat(join(dirname(testPath), path))\n\t\t\t.then((s) => s.isDirectory())\n\t\t\t.catch(() => false)\n\t}\n\n\tthrow new Error(`provider ${provider.name} is not supported`)\n}\n","import ci from 'is-ci'\n\nexport const getSnapshotPlatform = async () => {\n\treturn `${ci ? process.platform : 'local'}`\n}\n","import ci from 'is-ci'\n\nexport const isCI = async () => ci\n","import { dirname, join } from 'pathe'\nimport { rimraf } from 'rimraf'\nimport type { BrowserCommand } from 'vitest/node'\n\nexport const rmDir: BrowserCommand<[path: string]> = async ({ testPath, provider }, path) => {\n\tif (provider.name === 'playwright') {\n\t\treturn rimraf(join(dirname(testPath), path))\n\t}\n\n\tthrow new Error(`provider ${provider.name} is not supported`)\n}\n","import type { Plugin } from 'vitest/config'\nimport './augment.js'\nimport { copyFile } from './vitest-plugin/commands/copy_file.js'\nimport { existDir } from './vitest-plugin/commands/exist_dir.js'\nimport { getSnapshotPlatform } from './vitest-plugin/commands/get_snapshot_platform.js'\nimport { isCI } from './vitest-plugin/commands/is_ci.js'\nimport { rmDir } from './vitest-plugin/commands/rm_dir.js'\n\nexport function storybookVis() {\n\treturn {\n\t\tname: 'vitest:storybook-addon-vis',\n\t\tconfig() {\n\t\t\treturn {\n\t\t\t\ttest: {\n\t\t\t\t\tbrowser: {\n\t\t\t\t\t\tname: 'chromium',\n\t\t\t\t\t\tcommands: {\n\t\t\t\t\t\t\texistDir,\n\t\t\t\t\t\t\tcopyFile,\n\t\t\t\t\t\t\trmDir,\n\t\t\t\t\t\t\tisCI,\n\t\t\t\t\t\t\tgetSnapshotPlatform,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t},\n\t} satisfies Plugin\n}\n"]}
|
package/dist/vitest-setup.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {join,basename,dirname,relative}from'pathe';import {getByAltText,getByRole,getByTestId,getByText,getByTitle,getByPlaceholderText,getByLabelText}from'@storybook/test';import z from'dedent';import A from'pixelmatch';var g=Symbol.for("storybook-addon-vis/imageSnapshot"),d=Symbol.for("storybook-addon-vis/imageSnapshotStub");function l(t){return new Promise((e,a)=>{let s=new Image;s.src=`data:image/png;base64,${t}`,s.onload=()=>{let
|
|
1
|
+
import {join,basename,dirname,relative}from'pathe';import {getByAltText,getByRole,getByTestId,getByText,getByTitle,getByPlaceholderText,getByLabelText}from'@storybook/test';import z from'dedent';import A from'pixelmatch';var g=Symbol.for("storybook-addon-vis/imageSnapshot"),d=Symbol.for("storybook-addon-vis/imageSnapshotStub");function l(t){return new Promise((e,a)=>{let s=new Image;s.src=`data:image/png;base64,${t}`,s.onload=()=>{let n=document.createElement("canvas");n.width=s.width,n.height=s.height;let r=n.getContext("2d");r.drawImage(s,0,0),e(r.getImageData(0,0,n.width,n.height));},s.onerror=()=>{a(new Error("Failed to load image"));};})}async function S(t){let e=document.createElement("canvas");return e.width=t.width,e.height=t.height,e.getContext("2d").putImageData(t,0,0),new Promise(s=>{e.toBlob(n=>{let r=new FileReader;r.onload=()=>{s(r.result);},r.readAsDataURL(n);});})}var o={name:"",testFilepath:"",taskName:"",snapshot:{}};async function I(t){let e=`${o.snapshotId}-${o.snapshot[o.snapshotId].index++}.png`,a=join(o.baselineDir,e),s=join(o.resultDir,e),n=join(o.diffDir,e),r=await this.screenshot({base64:!0,path:s,element:t?.element}),i=await l(r.base64);return {type:g,snapshotFilename:e,baselinePath:a,resultPath:s,diffPath:n,base64:r.base64,image:i}}var c;globalThis.__vitest_browser__&&import('@vitest/browser/context').then(t=>{c=t,R.extend({imageSnapshot:I});});function at(){return c?.cdp()??{}}var h=new Proxy({},{get(t,e){return t[e]??(c?.commands)[e]}}),R=new Proxy({getByAltText:getByAltText,getByRole:getByRole,getByTestId:getByTestId,getByText:getByText,getByTitle:getByTitle,getByPlaceholder:getByPlaceholderText,getByLabelText:getByLabelText},{get(t,e){return t[e]??c?.page?(c?.page)[e]:()=>{if(e==="imageSnapshot")return {type:d};console.info(`\`page.${e.toString()}\` does not exist when running in browser`);}}}),st=new Proxy({},{get(t,e){return t[e]??(c?.server)[e]}});function b(t){return !!t&&t.type===g}function D(t){if(!b(t))throw new Error("Expected subject to be an image snapshot")}function P(t){return `${t.replace(/[^a-z0-9]/gi,"-").toLowerCase()}`}var $=({width:t,height:e})=>a=>{if(a.width===t&&a.height===e)return a;let s=(r,i)=>i<=a.height&&r<=a.width,n=new ImageData(t,e,{colorSpace:a.colorSpace});for(let r=0;r<e;r++)for(let i=0;i<t;i++){let m=t*r+i<<2;if(s(i,r)){let p=a.width*r+i<<2;n.data[m]=a.data[p],n.data[m+1]=a.data[p+1],n.data[m+2]=a.data[p+2],n.data[m+3]=a.data[p+3];}else n.data[m]=0,n.data[m+1]=0,n.data[m+2]=0,n.data[m+3]=64;}return n};async function lt(t,e){let a=await t;if(a?.type===d)return x;if(!b(a)){if(a?.path&&a?.base64)return {pass:!1,actual:t,message:()=>"`toMatchImageSnapshot()` expects the subject to be the result of `page.imageSnapshot()`, but seems like you are using `page.screenshot()`?"};if(typeof a!="object")return {pass:!1,actual:t,message:()=>`\`toMatchImageSnapshot()\` expects the subject to be an element, locator, or result of \`page.imageSnapshot()\`, but got: \`${t}\``}}D(a);let s=await k(a.baselinePath);if(!s)return await h.copyFile(a.resultPath,a.baselinePath),x;let n=await l(s),[r,i]=M(a.image,n),{pass:m,diffAmount:p,diffImage:f}=N(i,r,e);return m?x:(await C(`${a.diffPath}`,f),{pass:!1,actual:t,message:()=>z`${e?.failureThreshold?e?.failureThresholdType==="percent"?`Expected image to match within ${e.failureThreshold}% but was differ by ${p}%.`:`Expected image to match within ${e.failureThreshold} pixels but was differ by ${p} pixels.`:`Expected image to match but was differ by ${e?.failureThresholdType==="percent"?`${p}%`:`${p} pixels`}.`}
|
|
2
2
|
|
|
3
3
|
Expected: '${a.baselinePath}'
|
|
4
4
|
Actual: '${a.resultPath}'
|
|
5
|
-
Difference: '${a.diffPath}'`})}var x={pass:!0,message:()=>""};function k(t){return h.readFile(t,{encoding:"base64"}).catch(()=>{})}async function C(t,e){let a=(await S(e)).split(",")[1];return h.writeFile(t,a,"base64url")}function M(t,e){if(L(t,e))return [t,e];let a=O(t,e),s
|
|
5
|
+
Difference: '${a.diffPath}'`})}var x={pass:!0,message:()=>""};function k(t){return h.readFile(t,{encoding:"base64"}).catch(()=>{})}async function C(t,e){let a=(await S(e)).split(",")[1];return h.writeFile(t,a,"base64url")}function M(t,e){if(L(t,e))return [t,e];let a=O(t,e),s=$(a);return [s(t),s(e)]}function O(t,e){let a=Math.max(t.width,e.width),s=Math.max(t.height,e.height);return {width:a,height:s}}function L(t,e){return t.width===e.width&&t.height===e.height}function N(t,e,{failureThreshold:a=0,failureThresholdType:s="pixel",diffOptions:n}={}){let{width:r,height:i}=e,m=new ImageData(r,i),p=A(e.data,t.data,m.data,r,i,n),f=U({failureThresholdType:s,width:r,height:i},p);return {pass:f<=a,diffAmount:f,diffImage:m}}function U({failureThresholdType:t,width:e,height:a},s){switch(t){case"pixel":return s;case"percent":return s/(e*a)*100;default:throw new Error(`Invalid failureThresholdType: ${t}`)}}function yt(t){return t.story?.tags?t.story.tags.lastIndexOf("!snapshot")<t.story.tags.lastIndexOf("snapshot"):!1}async function Dt(t,e){o.name=t.name,o.testFilepath=t.file.filepath,o.testFilename=basename(o.testFilepath),o.projectDir=o.testFilepath.slice(0,-o.name.length);let a=join(o.projectDir,e?.snapshotPath??`__snapshots__/${await h.getSnapshotPlatform()}`),s=dirname(o.testFilepath);o.baselineDir=relative(s,join(a,o.testFilename)),o.resultDir=relative(s,join(a,"__results__",o.testFilename)),o.diffDir=relative(s,join(a,"__diff_output__",o.testFilename)),await h.rmDir(o.resultDir),await h.rmDir(o.diffDir);}function Pt(t){o.taskName=t.task.name;let e=o.snapshotId=P(o.taskName);o.snapshot[e]=o.snapshot[e]??{index:1};}export{at as cdp,h as commands,Dt as configureSnapshotBeforeAll,Pt as configureSnapshotBeforeEach,R as page,st as server,yt as shouldTakeSnapshot,lt as toMatchImageSnapshot};//# sourceMappingURL=vitest-setup.js.map
|
|
6
6
|
//# sourceMappingURL=vitest-setup.js.map
|
package/dist/vitest-setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/@vitest/browser/constants.ts","../src/@vitest/browser/page.image_snapshot.ts","../src/image_data.ts","../src/state.ts","../src/@vitest/browser/context.ts","../src/@vitest/browser/image_snapshot.logic.ts","../src/image_resizer.ts","../src/expect.to_match_image_snapshot.ts","../src/tags.ts","../src/vitest-setup.ts"],"names":["imageSnapshotSymbol","imageSnapshotStubSymbol","toImageData","base64","resolve","reject","img","canvas","ctx","toDataURL","imageData","blob","reader","state","imageSnapshot","options","snapshotFilename","baselinePath","join","resultPath","diffPath","screenshot","image","m","page","cdp","commands","target","prop","getByAltText","getByRole","getByTestId","getByText","getByTitle","getByPlaceholderText","getByLabelText","server","isImageSnapshot","subject","assertImageSnapshot","toSnapshotId","taskName","createImageResizer","width","height","inArea","x","y","result","idx","old","toMatchImageSnapshot","actual","success","baseline","tryReadSnapshot","originalImage","resultImage","baselineImage","alignImagesToSameSize","pass","diffAmount","diffImage","compareImage","writeSnapshot","dedent","path","content","image1","image2","isSameSize","size","getMaxSize","resize","failureThreshold","failureThresholdType","diffOptions","pixelDiff","pixelmatch","toThresholdUnit","shouldTakeSnapshot","configureSnapshotBeforeAll","suite","basename","snapshotPath","currentDir","dirname","relative","configureSnapshotBeforeEach","snapshotId"],"mappings":"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","file":"vitest-setup.js","sourcesContent":["export const imageSnapshotSymbol = Symbol.for('storybook-addon-vis/imageSnapshot')\n\nexport const imageSnapshotStubSymbol = Symbol.for('storybook-addon-vis/imageSnapshotStub')\n","import type { BrowserPage } from '@vitest/browser/context'\nimport { join } from 'pathe'\nimport { toImageData } from '../../image_data.js'\nimport { state } from '../../state.js'\nimport { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot, ImageSnapshotOptions } from './types.js'\n\nexport async function imageSnapshot(this: BrowserPage, options?: ImageSnapshotOptions): Promise<ImageSnapshot> {\n\tconst snapshotFilename = `${state.snapshotId}-${state.snapshot[state.snapshotId]!.index++}.png`\n\tconst baselinePath = join(state.baselineDir, snapshotFilename)\n\tconst resultPath = join(state.resultDir, snapshotFilename)\n\tconst diffPath = join(state.diffDir, snapshotFilename)\n\tconst screenshot = await this.screenshot({\n\t\tbase64: true,\n\t\tpath: resultPath,\n\t\telement: options?.element,\n\t})\n\tconst image = await toImageData(screenshot.base64)\n\n\treturn {\n\t\ttype: imageSnapshotSymbol,\n\t\tsnapshotFilename,\n\t\tbaselinePath,\n\t\tresultPath,\n\t\tdiffPath,\n\t\tbase64: screenshot.base64,\n\t\timage,\n\t}\n}\n","export function toImageData(base64: string) {\n\treturn new Promise<ImageData>((resolve, reject) => {\n\t\tconst img = new Image()\n\t\timg.src = `data:image/png;base64,${base64}`\n\n\t\timg.onload = () => {\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = img.width\n\t\t\tcanvas.height = img.height\n\t\t\tconst ctx = canvas.getContext('2d')!\n\t\t\tctx.drawImage(img, 0, 0)\n\t\t\tresolve(ctx.getImageData(0, 0, canvas.width, canvas.height))\n\t\t}\n\n\t\timg.onerror = () => {\n\t\t\treject(new Error('Failed to load image'))\n\t\t}\n\t})\n}\n\nexport async function toDataURL(imageData: ImageData) {\n\tconst canvas = document.createElement('canvas')\n\tcanvas.width = imageData.width\n\tcanvas.height = imageData.height\n\tconst ctx = canvas.getContext('2d')!\n\tctx.putImageData(imageData, 0, 0)\n\treturn new Promise<string>((resolve) => {\n\t\tcanvas.toBlob((blob) => {\n\t\t\tconst reader = new FileReader()\n\t\t\treader.onload = () => {\n\t\t\t\tresolve(reader.result as string)\n\t\t\t}\n\t\t\treader.readAsDataURL(blob!)\n\t\t})\n\t})\n}\n","export const state = {\n\tname: '',\n\ttestFilepath: '',\n\ttaskName: '',\n\tsnapshot: {},\n} as {\n\tname: string\n\ttestFilepath: string\n\ttestFilename: string\n\tprojectDir: string\n\tbaselineDir: string\n\tresultDir: string\n\tdiffDir: string\n\ttaskName: string\n\tsnapshotId: string\n\tsnapshot: Record<string, { index: number }>\n}\n","import {\n\tgetByAltText,\n\tgetByLabelText,\n\tgetByPlaceholderText,\n\tgetByRole,\n\tgetByTestId,\n\tgetByText,\n\tgetByTitle,\n} from '@storybook/test'\nimport type { BrowserCommands, BrowserPage, CDPSession, Platform } from '@vitest/browser/context'\nimport type { SerializedConfig } from 'vitest'\nimport { imageSnapshotStubSymbol } from './constants'\nimport { imageSnapshot } from './page.image_snapshot'\n\nlet ctx: Awaited<typeof import('@vitest/browser/context')>\n\nif ((globalThis as any).__vitest_browser__) {\n\timport('@vitest/browser/context').then((m) => {\n\t\tctx = m\n\t\tpage.extend({ imageSnapshot })\n\t})\n}\n\n// TODO: stub the functions within the `CDPSession`\n// when we better understands the use cases\nexport function cdp(): CDPSession {\n\treturn ctx?.cdp() ?? ({} as any)\n}\n\nexport const commands = new Proxy<BrowserCommands>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.commands as any)[prop]\n\t},\n})\n\nexport const page = new Proxy<BrowserPage>(\n\t{\n\t\tgetByAltText,\n\t\tgetByRole,\n\t\tgetByTestId,\n\t\tgetByText,\n\t\tgetByTitle,\n\t\tgetByPlaceholder: getByPlaceholderText,\n\t\tgetByLabelText,\n\t} as any,\n\t{\n\t\tget(target, prop) {\n\t\t\treturn ((target as any)[prop] ?? ctx?.page)\n\t\t\t\t? (ctx?.page as any)[prop]\n\t\t\t\t: () => {\n\t\t\t\t\t\tif (prop === 'imageSnapshot') {\n\t\t\t\t\t\t\treturn { type: imageSnapshotStubSymbol }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconsole.info(`\\`page.${prop.toString()}\\` does not exist when running in browser`)\n\t\t\t\t\t}\n\t\t},\n\t},\n)\n\nexport const server = new Proxy<{\n\t/**\n\t * Platform the Vitest server is running on.\n\t * The same as calling `process.platform` on the server.\n\t */\n\tplatform: Platform\n\t/**\n\t * Runtime version of the Vitest server.\n\t * The same as calling `process.version` on the server.\n\t */\n\tversion: string\n\t/**\n\t * Name of the browser provider.\n\t */\n\tprovider: string\n\t/**\n\t * Name of the current browser.\n\t */\n\tbrowser: string\n\t/**\n\t * Available commands for the browser.\n\t * @see {@link https://vitest.dev/guide/browser/commands}\n\t */\n\tcommands: BrowserCommands\n\t/**\n\t * Serialized test config.\n\t */\n\tconfig: SerializedConfig\n}>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.server as any)[prop]\n\t},\n})\n","import { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot } from './types.js'\n\nexport function isImageSnapshot(subject: any): subject is ImageSnapshot {\n\treturn !!subject && subject.type === imageSnapshotSymbol\n}\n\nexport function assertImageSnapshot(subject: any): asserts subject is ImageSnapshot {\n\tif (!isImageSnapshot(subject)) {\n\t\tthrow new Error('Expected subject to be an image snapshot')\n\t}\n}\n\nexport function toSnapshotId(taskName: string) {\n\treturn `${taskName.replace(/[^a-z0-9]/gi, '-').toLowerCase()}`\n}\n","export const createImageResizer =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (inArea(x, y)) {\n\t\t\t\t\tconst old = (image.width * y + x) << 2\n\t\t\t\t\tresult.data[idx] = image.data[old]\n\t\t\t\t\tresult.data[idx + 1] = image.data[old + 1]\n\t\t\t\t\tresult.data[idx + 2] = image.data[old + 2]\n\t\t\t\t\tresult.data[idx + 3] = image.data[old + 3]\n\t\t\t\t} else {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n// slower\nexport const createImageResizer2 =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tconst copyBytes = image.width * 4\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tresult.data.set(image.data.slice(y * image.width, copyBytes), y * width * 4)\n\t\t\tfor (let x = image.width; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (!inArea(x, y)) {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport dedent from 'dedent'\nimport pixelmatch from 'pixelmatch'\nimport { imageSnapshotStubSymbol } from './@vitest/browser/constants.js'\nimport { commands } from './@vitest/browser/context.js'\nimport { assertImageSnapshot, isImageSnapshot } from './@vitest/browser/image_snapshot.logic.js'\nimport type { MatchImageSnapshotOptions } from './@vitest/browser/types.js'\nimport { toDataURL, toImageData } from './image_data.js'\nimport { createImageResizer } from './image_resizer.js'\n\nexport async function toMatchImageSnapshot(\n\tactual: any,\n\toptions?: MatchImageSnapshotOptions | undefined,\n): AsyncExpectationResult {\n\tconst subject = await actual\n\tif (subject?.type === imageSnapshotStubSymbol) {\n\t\treturn success\n\t}\n\tif (!isImageSnapshot(subject)) {\n\t\tif (subject?.path && subject?.base64) {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t'`toMatchImageSnapshot()` expects the subject to be the result of `page.imageSnapshot()`, but seems like you are using `page.screenshot()`?',\n\t\t\t}\n\t\t}\n\n\t\tif (typeof subject !== 'object') {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t`\\`toMatchImageSnapshot()\\` expects the subject to be an element, locator, or result of \\`page.imageSnapshot()\\`, but got: \\`${actual}\\``,\n\t\t\t}\n\t\t}\n\t\t// subject = await page.imageSnapshot({ element: actual })\n\t}\n\tassertImageSnapshot(subject)\n\tconst baseline = await tryReadSnapshot(subject.baselinePath)\n\tif (!baseline) {\n\t\tawait commands.copyFile(subject.resultPath, subject.baselinePath)\n\t\treturn success\n\t}\n\n\tconst originalImage = await toImageData(baseline)\n\tconst [resultImage, baselineImage] = alignImagesToSameSize(subject.image, originalImage)\n\n\tconst { pass, diffAmount, diffImage } = compareImage(baselineImage, resultImage, options)\n\tif (!pass) {\n\t\tawait writeSnapshot(`${subject.diffPath}`, diffImage)\n\t\treturn {\n\t\t\tpass: false,\n\t\t\tactual,\n\t\t\tmessage: () =>\n\t\t\t\tdedent`${\n\t\t\t\t\toptions?.failureThreshold\n\t\t\t\t\t\t? options?.failureThresholdType === 'percent'\n\t\t\t\t\t\t\t? `Expected image to match within ${options.failureThreshold}% but was differ by ${diffAmount}%.`\n\t\t\t\t\t\t\t: `Expected image to match within ${options.failureThreshold} pixels but was differ by ${diffAmount} pixels.`\n\t\t\t\t\t\t: `Expected image to match but was differ by ${options?.failureThresholdType === 'percent' ? `${diffAmount}%` : `${diffAmount} pixels`}.`\n\t\t\t\t}\n\n\t\t\tExpected: '${subject.baselinePath}'\n\t\t\tActual: '${subject.resultPath}'\n\t\t\tDifference: '${subject.diffPath}'`,\n\t\t}\n\t}\n\treturn success\n}\n\nconst success = {\n\tpass: true,\n\tmessage: () => '',\n}\n\nfunction tryReadSnapshot(path: string): Promise<string | undefined> {\n\treturn commands.readFile(path, { encoding: 'base64' }).catch(() => undefined)\n}\nasync function writeSnapshot(path: string, image: ImageData) {\n\tconst content = (await toDataURL(image)).split(',')[1]!\n\treturn commands.writeFile(path, content, 'base64url')\n}\n\nfunction alignImagesToSameSize(image1: ImageData, image2: ImageData): [image1: ImageData, image2: ImageData] {\n\tif (isSameSize(image1, image2)) {\n\t\treturn [image1, image2]\n\t}\n\tconst size = getMaxSize(image1, image2)\n\tconst resize = createImageResizer(size)\n\treturn [resize(image1), resize(image2)]\n}\n\nfunction getMaxSize(image1: ImageData, image2: ImageData) {\n\tconst width = Math.max(image1.width, image2.width)\n\tconst height = Math.max(image1.height, image2.height)\n\treturn { width, height }\n}\n\nfunction isSameSize(image1: ImageData, image2: ImageData) {\n\treturn image1.width === image2.width && image1.height === image2.height\n}\n\nfunction compareImage(\n\tbaselineImage: ImageData,\n\tresultImage: ImageData,\n\t{ failureThreshold = 0, failureThresholdType = 'pixel', diffOptions }: MatchImageSnapshotOptions = {},\n) {\n\tconst { width, height } = resultImage\n\tconst diffImage = new ImageData(width, height)\n\n\tconst pixelDiff = pixelmatch(resultImage.data, baselineImage.data, diffImage.data, width, height, diffOptions)\n\tconst diffAmount = toThresholdUnit({ failureThresholdType, width, height }, pixelDiff)\n\n\treturn {\n\t\tpass: diffAmount <= failureThreshold,\n\t\tdiffAmount,\n\t\tdiffImage,\n\t}\n}\n\nfunction toThresholdUnit(\n\t{ failureThresholdType, width, height }: { failureThresholdType: 'pixel' | 'percent'; width: number; height: number },\n\tpixelDiff: number,\n): number {\n\tswitch (failureThresholdType) {\n\t\tcase 'pixel':\n\t\t\treturn pixelDiff\n\t\tcase 'percent':\n\t\t\treturn (pixelDiff / (width * height)) * 100\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid failureThresholdType: ${failureThresholdType}`)\n\t}\n}\n","/**\n * Determine should snapshot be taken.\n *\n * not story: false\n * no `snapshot` tag: false\n * disabled by `!snapshot` tag: false\n */\nexport function shouldTakeSnapshot(ctx: { story?: { tags: string[] } }) {\n\tif (!ctx.story?.tags) return false\n\treturn ctx.story.tags.lastIndexOf('!snapshot') < ctx.story.tags.lastIndexOf('snapshot')\n}\n","import { basename, dirname, join, relative } from 'pathe'\nimport './augment.js'\nimport { commands } from './@vitest/browser/context.js'\nimport { toSnapshotId } from './@vitest/browser/image_snapshot.logic.js'\nimport { state } from './state.js'\n\nexport * from './@vitest/browser/context.js'\nexport * from './expect.to_match_image_snapshot.js'\nexport * from './tags.js'\n\n/**\n * The project parameters for the snapshot.\n *\n * These parameters are set per project in the `.storybook/preview.ts` file.\n */\nexport type VisOptions = {\n\t/**\n\t * The snapshot folder relative to the root of the project.\n\t */\n\tsnapshotPath: string\n}\n\nexport async function configureSnapshotBeforeAll(\n\tsuite: { file: { filepath: string }; name: string },\n\toptions?: VisOptions,\n) {\n\tstate.name = suite.name\n\tstate.testFilepath = suite.file.filepath\n\tstate.testFilename = basename(state.testFilepath)\n\tstate.projectDir = state.testFilepath.slice(0, -state.name.length)\n\tconst snapshotPath = join(state.projectDir, options?.snapshotPath ?? '__snapshots__')\n\tconst currentDir = dirname(state.testFilepath)\n\tstate.baselineDir = relative(currentDir, join(snapshotPath, state.testFilename))\n\tstate.resultDir = relative(currentDir, join(snapshotPath, '__results__', state.testFilename))\n\tstate.diffDir = relative(currentDir, join(snapshotPath, '__diff_output__', state.testFilename))\n\n\tawait commands.rmDir(state.resultDir)\n\tawait commands.rmDir(state.diffDir)\n}\n\nexport function configureSnapshotBeforeEach(ctx: { task: { name: string } }) {\n\tstate.taskName = ctx.task.name\n\tconst snapshotId = (state.snapshotId = toSnapshotId(state.taskName))\n\tstate.snapshot[snapshotId] = state.snapshot[snapshotId] ?? { index: 1 }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/@vitest/browser/constants.ts","../src/@vitest/browser/page.image_snapshot.ts","../src/image_data.ts","../src/state.ts","../src/@vitest/browser/context.ts","../src/@vitest/browser/image_snapshot.logic.ts","../src/image_resizer.ts","../src/expect.to_match_image_snapshot.ts","../src/tags.ts","../src/vitest-setup.ts"],"names":["imageSnapshotSymbol","imageSnapshotStubSymbol","toImageData","base64","resolve","reject","img","canvas","ctx","toDataURL","imageData","blob","reader","state","imageSnapshot","options","snapshotFilename","baselinePath","join","resultPath","diffPath","screenshot","image","m","page","cdp","commands","target","prop","getByAltText","getByRole","getByTestId","getByText","getByTitle","getByPlaceholderText","getByLabelText","server","isImageSnapshot","subject","assertImageSnapshot","toSnapshotId","taskName","createImageResizer","width","height","inArea","x","y","result","idx","old","toMatchImageSnapshot","actual","success","baseline","tryReadSnapshot","originalImage","resultImage","baselineImage","alignImagesToSameSize","pass","diffAmount","diffImage","compareImage","writeSnapshot","dedent","path","content","image1","image2","isSameSize","size","getMaxSize","resize","failureThreshold","failureThresholdType","diffOptions","pixelDiff","pixelmatch","toThresholdUnit","shouldTakeSnapshot","configureSnapshotBeforeAll","suite","basename","snapshotPath","currentDir","dirname","relative","configureSnapshotBeforeEach","snapshotId"],"mappings":"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","file":"vitest-setup.js","sourcesContent":["export const imageSnapshotSymbol = Symbol.for('storybook-addon-vis/imageSnapshot')\n\nexport const imageSnapshotStubSymbol = Symbol.for('storybook-addon-vis/imageSnapshotStub')\n","import type { BrowserPage } from '@vitest/browser/context'\nimport { join } from 'pathe'\nimport { toImageData } from '../../image_data.js'\nimport { state } from '../../state.js'\nimport { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot, ImageSnapshotOptions } from './types.js'\n\nexport async function imageSnapshot(this: BrowserPage, options?: ImageSnapshotOptions): Promise<ImageSnapshot> {\n\tconst snapshotFilename = `${state.snapshotId}-${state.snapshot[state.snapshotId]!.index++}.png`\n\tconst baselinePath = join(state.baselineDir, snapshotFilename)\n\tconst resultPath = join(state.resultDir, snapshotFilename)\n\tconst diffPath = join(state.diffDir, snapshotFilename)\n\tconst screenshot = await this.screenshot({\n\t\tbase64: true,\n\t\tpath: resultPath,\n\t\telement: options?.element,\n\t})\n\tconst image = await toImageData(screenshot.base64)\n\n\treturn {\n\t\ttype: imageSnapshotSymbol,\n\t\tsnapshotFilename,\n\t\tbaselinePath,\n\t\tresultPath,\n\t\tdiffPath,\n\t\tbase64: screenshot.base64,\n\t\timage,\n\t}\n}\n","export function toImageData(base64: string) {\n\treturn new Promise<ImageData>((resolve, reject) => {\n\t\tconst img = new Image()\n\t\timg.src = `data:image/png;base64,${base64}`\n\n\t\timg.onload = () => {\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = img.width\n\t\t\tcanvas.height = img.height\n\t\t\tconst ctx = canvas.getContext('2d')!\n\t\t\tctx.drawImage(img, 0, 0)\n\t\t\tresolve(ctx.getImageData(0, 0, canvas.width, canvas.height))\n\t\t}\n\n\t\timg.onerror = () => {\n\t\t\treject(new Error('Failed to load image'))\n\t\t}\n\t})\n}\n\nexport async function toDataURL(imageData: ImageData) {\n\tconst canvas = document.createElement('canvas')\n\tcanvas.width = imageData.width\n\tcanvas.height = imageData.height\n\tconst ctx = canvas.getContext('2d')!\n\tctx.putImageData(imageData, 0, 0)\n\treturn new Promise<string>((resolve) => {\n\t\tcanvas.toBlob((blob) => {\n\t\t\tconst reader = new FileReader()\n\t\t\treader.onload = () => {\n\t\t\t\tresolve(reader.result as string)\n\t\t\t}\n\t\t\treader.readAsDataURL(blob!)\n\t\t})\n\t})\n}\n","export const state = {\n\tname: '',\n\ttestFilepath: '',\n\ttaskName: '',\n\tsnapshot: {},\n} as {\n\tname: string\n\ttestFilepath: string\n\ttestFilename: string\n\tprojectDir: string\n\tbaselineDir: string\n\tresultDir: string\n\tdiffDir: string\n\ttaskName: string\n\tsnapshotId: string\n\tsnapshot: Record<string, { index: number }>\n}\n","import {\n\tgetByAltText,\n\tgetByLabelText,\n\tgetByPlaceholderText,\n\tgetByRole,\n\tgetByTestId,\n\tgetByText,\n\tgetByTitle,\n} from '@storybook/test'\nimport type { BrowserCommands, BrowserPage, CDPSession, Platform } from '@vitest/browser/context'\nimport type { SerializedConfig } from 'vitest'\nimport { imageSnapshotStubSymbol } from './constants'\nimport { imageSnapshot } from './page.image_snapshot'\n\nlet ctx: Awaited<typeof import('@vitest/browser/context')>\n\nif ((globalThis as any).__vitest_browser__) {\n\timport('@vitest/browser/context').then((m) => {\n\t\tctx = m\n\t\tpage.extend({ imageSnapshot })\n\t})\n}\n\n// TODO: stub the functions within the `CDPSession`\n// when we better understands the use cases\nexport function cdp(): CDPSession {\n\treturn ctx?.cdp() ?? ({} as any)\n}\n\nexport const commands = new Proxy<BrowserCommands>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.commands as any)[prop]\n\t},\n})\n\nexport const page = new Proxy<BrowserPage>(\n\t{\n\t\tgetByAltText,\n\t\tgetByRole,\n\t\tgetByTestId,\n\t\tgetByText,\n\t\tgetByTitle,\n\t\tgetByPlaceholder: getByPlaceholderText,\n\t\tgetByLabelText,\n\t} as any,\n\t{\n\t\tget(target, prop) {\n\t\t\treturn ((target as any)[prop] ?? ctx?.page)\n\t\t\t\t? (ctx?.page as any)[prop]\n\t\t\t\t: () => {\n\t\t\t\t\t\tif (prop === 'imageSnapshot') {\n\t\t\t\t\t\t\treturn { type: imageSnapshotStubSymbol }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconsole.info(`\\`page.${prop.toString()}\\` does not exist when running in browser`)\n\t\t\t\t\t}\n\t\t},\n\t},\n)\n\nexport const server = new Proxy<{\n\t/**\n\t * Platform the Vitest server is running on.\n\t * The same as calling `process.platform` on the server.\n\t */\n\tplatform: Platform\n\t/**\n\t * Runtime version of the Vitest server.\n\t * The same as calling `process.version` on the server.\n\t */\n\tversion: string\n\t/**\n\t * Name of the browser provider.\n\t */\n\tprovider: string\n\t/**\n\t * Name of the current browser.\n\t */\n\tbrowser: string\n\t/**\n\t * Available commands for the browser.\n\t * @see {@link https://vitest.dev/guide/browser/commands}\n\t */\n\tcommands: BrowserCommands\n\t/**\n\t * Serialized test config.\n\t */\n\tconfig: SerializedConfig\n}>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.server as any)[prop]\n\t},\n})\n","import { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot } from './types.js'\n\nexport function isImageSnapshot(subject: any): subject is ImageSnapshot {\n\treturn !!subject && subject.type === imageSnapshotSymbol\n}\n\nexport function assertImageSnapshot(subject: any): asserts subject is ImageSnapshot {\n\tif (!isImageSnapshot(subject)) {\n\t\tthrow new Error('Expected subject to be an image snapshot')\n\t}\n}\n\nexport function toSnapshotId(taskName: string) {\n\treturn `${taskName.replace(/[^a-z0-9]/gi, '-').toLowerCase()}`\n}\n","export const createImageResizer =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (inArea(x, y)) {\n\t\t\t\t\tconst old = (image.width * y + x) << 2\n\t\t\t\t\tresult.data[idx] = image.data[old]\n\t\t\t\t\tresult.data[idx + 1] = image.data[old + 1]\n\t\t\t\t\tresult.data[idx + 2] = image.data[old + 2]\n\t\t\t\t\tresult.data[idx + 3] = image.data[old + 3]\n\t\t\t\t} else {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n// slower\nexport const createImageResizer2 =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tconst copyBytes = image.width * 4\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tresult.data.set(image.data.slice(y * image.width, copyBytes), y * width * 4)\n\t\t\tfor (let x = image.width; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (!inArea(x, y)) {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport dedent from 'dedent'\nimport pixelmatch from 'pixelmatch'\nimport { imageSnapshotStubSymbol } from './@vitest/browser/constants.js'\nimport { commands } from './@vitest/browser/context.js'\nimport { assertImageSnapshot, isImageSnapshot } from './@vitest/browser/image_snapshot.logic.js'\nimport type { MatchImageSnapshotOptions } from './@vitest/browser/types.js'\nimport { toDataURL, toImageData } from './image_data.js'\nimport { createImageResizer } from './image_resizer.js'\n\nexport async function toMatchImageSnapshot(\n\tactual: any,\n\toptions?: MatchImageSnapshotOptions | undefined,\n): AsyncExpectationResult {\n\tconst subject = await actual\n\tif (subject?.type === imageSnapshotStubSymbol) {\n\t\treturn success\n\t}\n\tif (!isImageSnapshot(subject)) {\n\t\tif (subject?.path && subject?.base64) {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t'`toMatchImageSnapshot()` expects the subject to be the result of `page.imageSnapshot()`, but seems like you are using `page.screenshot()`?',\n\t\t\t}\n\t\t}\n\n\t\tif (typeof subject !== 'object') {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t`\\`toMatchImageSnapshot()\\` expects the subject to be an element, locator, or result of \\`page.imageSnapshot()\\`, but got: \\`${actual}\\``,\n\t\t\t}\n\t\t}\n\t\t// subject = await page.imageSnapshot({ element: actual })\n\t}\n\tassertImageSnapshot(subject)\n\tconst baseline = await tryReadSnapshot(subject.baselinePath)\n\tif (!baseline) {\n\t\tawait commands.copyFile(subject.resultPath, subject.baselinePath)\n\t\treturn success\n\t}\n\n\tconst originalImage = await toImageData(baseline)\n\tconst [resultImage, baselineImage] = alignImagesToSameSize(subject.image, originalImage)\n\n\tconst { pass, diffAmount, diffImage } = compareImage(baselineImage, resultImage, options)\n\tif (!pass) {\n\t\tawait writeSnapshot(`${subject.diffPath}`, diffImage)\n\t\treturn {\n\t\t\tpass: false,\n\t\t\tactual,\n\t\t\tmessage: () =>\n\t\t\t\tdedent`${\n\t\t\t\t\toptions?.failureThreshold\n\t\t\t\t\t\t? options?.failureThresholdType === 'percent'\n\t\t\t\t\t\t\t? `Expected image to match within ${options.failureThreshold}% but was differ by ${diffAmount}%.`\n\t\t\t\t\t\t\t: `Expected image to match within ${options.failureThreshold} pixels but was differ by ${diffAmount} pixels.`\n\t\t\t\t\t\t: `Expected image to match but was differ by ${options?.failureThresholdType === 'percent' ? `${diffAmount}%` : `${diffAmount} pixels`}.`\n\t\t\t\t}\n\n\t\t\tExpected: '${subject.baselinePath}'\n\t\t\tActual: '${subject.resultPath}'\n\t\t\tDifference: '${subject.diffPath}'`,\n\t\t}\n\t}\n\treturn success\n}\n\nconst success = {\n\tpass: true,\n\tmessage: () => '',\n}\n\nfunction tryReadSnapshot(path: string): Promise<string | undefined> {\n\treturn commands.readFile(path, { encoding: 'base64' }).catch(() => undefined)\n}\nasync function writeSnapshot(path: string, image: ImageData) {\n\tconst content = (await toDataURL(image)).split(',')[1]!\n\treturn commands.writeFile(path, content, 'base64url')\n}\n\nfunction alignImagesToSameSize(image1: ImageData, image2: ImageData): [image1: ImageData, image2: ImageData] {\n\tif (isSameSize(image1, image2)) {\n\t\treturn [image1, image2]\n\t}\n\tconst size = getMaxSize(image1, image2)\n\tconst resize = createImageResizer(size)\n\treturn [resize(image1), resize(image2)]\n}\n\nfunction getMaxSize(image1: ImageData, image2: ImageData) {\n\tconst width = Math.max(image1.width, image2.width)\n\tconst height = Math.max(image1.height, image2.height)\n\treturn { width, height }\n}\n\nfunction isSameSize(image1: ImageData, image2: ImageData) {\n\treturn image1.width === image2.width && image1.height === image2.height\n}\n\nfunction compareImage(\n\tbaselineImage: ImageData,\n\tresultImage: ImageData,\n\t{ failureThreshold = 0, failureThresholdType = 'pixel', diffOptions }: MatchImageSnapshotOptions = {},\n) {\n\tconst { width, height } = resultImage\n\tconst diffImage = new ImageData(width, height)\n\n\tconst pixelDiff = pixelmatch(resultImage.data, baselineImage.data, diffImage.data, width, height, diffOptions)\n\tconst diffAmount = toThresholdUnit({ failureThresholdType, width, height }, pixelDiff)\n\n\treturn {\n\t\tpass: diffAmount <= failureThreshold,\n\t\tdiffAmount,\n\t\tdiffImage,\n\t}\n}\n\nfunction toThresholdUnit(\n\t{ failureThresholdType, width, height }: { failureThresholdType: 'pixel' | 'percent'; width: number; height: number },\n\tpixelDiff: number,\n): number {\n\tswitch (failureThresholdType) {\n\t\tcase 'pixel':\n\t\t\treturn pixelDiff\n\t\tcase 'percent':\n\t\t\treturn (pixelDiff / (width * height)) * 100\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid failureThresholdType: ${failureThresholdType}`)\n\t}\n}\n","/**\n * Determine should snapshot be taken.\n *\n * not story: false\n * no `snapshot` tag: false\n * disabled by `!snapshot` tag: false\n */\nexport function shouldTakeSnapshot(ctx: { story?: { tags: string[] } }) {\n\tif (!ctx.story?.tags) return false\n\treturn ctx.story.tags.lastIndexOf('!snapshot') < ctx.story.tags.lastIndexOf('snapshot')\n}\n","import { basename, dirname, join, relative } from 'pathe'\nimport './augment.js'\nimport { commands } from './@vitest/browser/context.js'\nimport { toSnapshotId } from './@vitest/browser/image_snapshot.logic.js'\nimport { state } from './state.js'\n\nexport * from './@vitest/browser/context.js'\nexport * from './expect.to_match_image_snapshot.js'\nexport * from './tags.js'\n\n/**\n * The project parameters for the snapshot.\n *\n * These parameters are set per project in the `.storybook/preview.ts` file.\n */\nexport type VisOptions = {\n\t/**\n\t * The snapshot folder relative to the root of the project.\n\t */\n\tsnapshotPath: string\n}\n\nexport async function configureSnapshotBeforeAll(\n\tsuite: { file: { filepath: string }; name: string },\n\toptions?: VisOptions,\n) {\n\tstate.name = suite.name\n\tstate.testFilepath = suite.file.filepath\n\tstate.testFilename = basename(state.testFilepath)\n\tstate.projectDir = state.testFilepath.slice(0, -state.name.length)\n\tconst snapshotPath = join(\n\t\tstate.projectDir,\n\t\toptions?.snapshotPath ?? `__snapshots__/${await commands.getSnapshotPlatform()}`,\n\t)\n\tconst currentDir = dirname(state.testFilepath)\n\tstate.baselineDir = relative(currentDir, join(snapshotPath, state.testFilename))\n\tstate.resultDir = relative(currentDir, join(snapshotPath, '__results__', state.testFilename))\n\tstate.diffDir = relative(currentDir, join(snapshotPath, '__diff_output__', state.testFilename))\n\n\tawait commands.rmDir(state.resultDir)\n\tawait commands.rmDir(state.diffDir)\n}\n\nexport function configureSnapshotBeforeEach(ctx: { task: { name: string } }) {\n\tstate.taskName = ctx.task.name\n\tconst snapshotId = (state.snapshotId = toSnapshotId(state.taskName))\n\tstate.snapshot[snapshotId] = state.snapshot[snapshotId] ?? { index: 1 }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybook-addon-vis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Storybook Vitest Image Snapshot addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"image-snapshot",
|
|
@@ -63,10 +63,7 @@
|
|
|
63
63
|
"@vitejs/plugin-react": "^4.2.1",
|
|
64
64
|
"@vitest/browser": "^2.1.3",
|
|
65
65
|
"@vitest/expect": "^2.1.3",
|
|
66
|
-
"auto": "^11.1.1",
|
|
67
66
|
"boxen": "^7.1.1",
|
|
68
|
-
"prettier": "^3.3.3",
|
|
69
|
-
"prompts": "^2.4.2",
|
|
70
67
|
"react": "^18.2.0",
|
|
71
68
|
"react-dom": "^18.2.0",
|
|
72
69
|
"storybook": "^8.3.6",
|
|
@@ -112,7 +109,6 @@
|
|
|
112
109
|
"dev": "run-p build:watch \"sb --quiet\"",
|
|
113
110
|
"nuke": "rimraf node_modules",
|
|
114
111
|
"prerelease": "zx scripts/prepublish-checks.js",
|
|
115
|
-
"release": "pnpm build && auto shipit",
|
|
116
112
|
"sb": "storybook dev -p 6006",
|
|
117
113
|
"test": "vitest run",
|
|
118
114
|
"w": "vitest"
|
package/readme.md
CHANGED
|
@@ -39,8 +39,9 @@ import { defineConfig } from 'vitest/config'
|
|
|
39
39
|
export default defineConfig({
|
|
40
40
|
plugins: [
|
|
41
41
|
storybookTest(),
|
|
42
|
-
storybookVis()
|
|
43
|
-
|
|
42
|
+
storybookVis()
|
|
43
|
+
],
|
|
44
|
+
test: {
|
|
44
45
|
browser: {
|
|
45
46
|
// ...
|
|
46
47
|
}
|
|
@@ -73,7 +74,7 @@ expect.extend({ toMatchImageSnapshot })
|
|
|
73
74
|
|
|
74
75
|
beforeAll(async (suite) => {
|
|
75
76
|
project.beforeAll()
|
|
76
|
-
await configureSnapshotBeforeAll(suite, /*
|
|
77
|
+
await configureSnapshotBeforeAll(suite, /* options */)
|
|
77
78
|
})
|
|
78
79
|
|
|
79
80
|
beforeEach(configureSnapshotBeforeEach)
|
|
@@ -169,7 +170,7 @@ export const ElementSnapshot = {
|
|
|
169
170
|
// ...
|
|
170
171
|
async play({ canvas }) {
|
|
171
172
|
const element = await canvas.getByTestid('subject')
|
|
172
|
-
await expect(page.imageSnapshot(
|
|
173
|
+
await expect(page.imageSnapshot({ element })).toMatchImageSnapshot()
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
```
|
package/src/vitest-setup.spec.ts
CHANGED
|
@@ -9,10 +9,13 @@ import { configureSnapshotBeforeAll } from './vitest-setup.js'
|
|
|
9
9
|
const { ConversionRoundtrip } = composeStories(ImageDataStories)
|
|
10
10
|
|
|
11
11
|
it('should delete the results and diffs folder when the during `beforeAll`', async ({ task }) => {
|
|
12
|
-
await
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const snapshotPlatform = await commands.getSnapshotPlatform()
|
|
13
|
+
await expect(
|
|
14
|
+
commands.existDir(`../__snapshots__/${snapshotPlatform}/__diff_output__/${basename(task.file.name)}`),
|
|
15
|
+
).resolves.toBe(false)
|
|
16
|
+
await expect(
|
|
17
|
+
commands.existDir(`../__snapshots__/${snapshotPlatform}/__results__/${basename(task.file.name)}`),
|
|
18
|
+
).resolves.toBe(false)
|
|
16
19
|
await ConversionRoundtrip.run()
|
|
17
20
|
await expect(page.imageSnapshot()).toMatchImageSnapshot()
|
|
18
21
|
})
|
package/src/vitest-setup.ts
CHANGED
|
@@ -28,7 +28,10 @@ export async function configureSnapshotBeforeAll(
|
|
|
28
28
|
state.testFilepath = suite.file.filepath
|
|
29
29
|
state.testFilename = basename(state.testFilepath)
|
|
30
30
|
state.projectDir = state.testFilepath.slice(0, -state.name.length)
|
|
31
|
-
const snapshotPath = join(
|
|
31
|
+
const snapshotPath = join(
|
|
32
|
+
state.projectDir,
|
|
33
|
+
options?.snapshotPath ?? `__snapshots__/${await commands.getSnapshotPlatform()}`,
|
|
34
|
+
)
|
|
32
35
|
const currentDir = dirname(state.testFilepath)
|
|
33
36
|
state.baselineDir = relative(currentDir, join(snapshotPath, state.testFilename))
|
|
34
37
|
state.resultDir = relative(currentDir, join(snapshotPath, '__results__', state.testFilename))
|