chromascope
Advanced tools
Comparing version 1.1.0 to 1.1.1
# chromascope | ||
## 1.1.1 | ||
### Patch Changes | ||
- cd2dd50: Fixes cookieless runs | ||
## 1.1.0 | ||
@@ -4,0 +10,0 @@ |
#!/usr/bin/env node | ||
var x="1.1.0";var w=class{constructor(t=void 0){this.options={verbose:!1};this.setOptions(t)}setOptions(t){this.options={...this.options,...t}}log(...t){console.log(...t)}error(...t){console.error(...t)}debug(...t){this.options.verbose&&console.log(...t)}},k=new w,c=k;import C from"ora";var B=C({spinner:"orangeBluePulse"}),u=()=>C({spinner:"orangeBluePulse"}),h=B;var M=/^(?:(?:https?|ftp):\/\/)?(?:localhost|\S+(?:\.[^\s.]+)+|\[?[0-9a-fA-F:]+\]?)(?::\d+)?(?:\/[\w#!:.?+=&%@!\-\/]*)?(?:\?[\w&=]+)?$/i,S=e=>M.test(e),y=(e,t)=>{let r=[];return e.split(";").forEach(o=>{if(!o)return;let s=o.indexOf("="),i=o.slice(0,s),n=o.slice(s+1);r.push({name:i.trim(),value:n.trim(),url:t})}),r};import{chromium as W,firefox as I,webkit as j}from"@playwright/test";import m from"fs";import A from"pixelmatch";import{PNG as d}from"pngjs";var P=async(e,t)=>{c.setOptions({verbose:t.options.verbose});let r=[U(e,t),K(e,t),N(e,t)],o=await Promise.allSettled(r),[s,i,n]=o,a=s.status==="fulfilled"?s.value:null,p=i.status==="fulfilled"?i.value:null,f=n.status==="fulfilled"?n.value:null,g=await v(a,p,"chromium-webkit",t),F=await v(a,f,"chromium-firefox",t);return t.options.saveDiff||(t.spinner.text="Cleaning up \u{1F9F9}",m.rmdirSync(t.runFolder,{recursive:!0}),m.readdirSync(t.options.folder).length===0&&m.rmdirSync(t.options.folder)),t.spinner.text="",[{...g,browserName:"\u{1F34E} WebKit"},{...F,browserName:"\u{1F98A} Firefox"}]},D=e=>{c.log(`\u250C\u2500 ${e.browserName}`),c.log(`${e.diffPath?"\u251C\u2500":"\u2514\u2500"} \u{1F449} ${e.pixelChangePercentage.toFixed(2)}% pixel change compared to Chromium (${e.pixelChange}px)`),e.diffPath&&c.log(`\u2514\u2500 \u{1F449} Visual diff stored at ${e.diffPath}`)},K=async(e,t)=>{let r=u().start("Capturing WebKit screenshot \u{1F4F7}"),o=await j.launch(),s=await b(e,o,t);return r.succeed("Captured WebKit screenshot \u{1F4F8}"),s},N=async(e,t)=>{let r=u().start("Capturing Firefox screenshot \u{1F4F7}"),o=await I.launch(),s=await b(e,o,t);return r.succeed("Captured Firefox screenshot \u{1F4F8}"),s},U=async(e,t)=>{let r=u().start("Capturing Chromium screenshot \u{1F4F7}"),o=await W.launch(),s=await b(e,o,t);return r.succeed("Captured Chromium screenshot \u{1F4F8}"),s},b=async(e,t,r)=>{let o=await t.newContext(),i=t.browserType().name(),n=await o.newPage(),a=y(r.options.cookie,e);a.length>0&&(c.debug(`Adding cookies to ${i} context: ${JSON.stringify(a)}`),o.addCookies(y(r.options.cookie,e))),await n.goto(e);let p=r.options.saveDiff?`${r.runFolder}/${i}.png`:void 0;return c.debug(`Saving ${i} screenshot to ${p}`),r.options.element?await n.locator(r.options.element).screenshot({path:p}):await n.screenshot({path:p,fullPage:r.options.fullPage})},v=async(e,t,r,o)=>{if(!e||!t)throw new Error("Screenshot buffer cannot be null");let s=d.sync.read(e),i=d.sync.read(t),n={width:Math.max(s.width,i.width),height:Math.max(s.height,i.height)};(s.width!==i.width||s.height!==i.height)&&(s=$(s,n),i=$(i,n));let a=new d({width:n.width,height:n.height}),p=A(s.data,i.data,a.data,n.width,n.height,{threshold:o.options.threshold}),f="";o.options.saveDiff&&(f=`${o.runFolder}/diff-${r}.png`,o.spinner.text=`Saving ${r} diff \u{1F5C4}\uFE0F`,m.writeFileSync(f,d.sync.write(a)));let g=p/(n.width*n.height)*100;return{pixelChange:p,pixelChangePercentage:g,diffPath:f}},$=(e,{width:t,height:r})=>{if(e.width===t&&e.height===r)return e;c.debug(`Resizing image to ${t}x${r}...`);let o=new Uint8Array(t*r*4);for(let s=0;s<r;s++)for(let i=0;i<t;i++){let n=(s*t+i)*4;if(s<e.height&&i<e.width){let a=(s*e.width+i)*4;o[n]=e.data[a],o[n+1]=e.data[a+1],o[n+2]=e.data[a+2],o[n+3]=e.data[a+3]}else o[n]=0,o[n+1]=0,o[n+2]=0,o[n+3]=0}return{data:Buffer.from(o),width:t,height:r}};function O(e,t){let r=L(),o=`${e.folder}/${r}`;return{runId:r,spinner:t,runFolder:o,options:e}}var L=()=>{let e=new Date,t=e.getFullYear().toString(),r=(e.getMonth()+1).toString().padStart(2,"0"),o=e.getDate().toString().padStart(2,"0"),s=e.getHours().toString().padStart(2,"0"),i=e.getMinutes().toString().padStart(2,"0"),n=e.getSeconds().toString().padStart(2,"0");return`${t}${r}${o}${s}${i}${n}`};import E from"cac";var l=E("chromascope");l.command("diff <url>","Diff the URL in chromium, firefox, and webkit. Using chromium as the base.").option("-e, --element <selector>","Diff only the element with the given selector").option("-f, --full-page","Take a full page screenshot").option("-v, --verbose","Show more output").option("-c, --cookie <cookie>","Add one or more cookies to the context. Format: key=value;key2=value2").option("-s, --save-diff","Save generated diff as png").option("-t, --threshold <threshold>","Set the threshold for the diff",{default:.2}).option("-f, --folder <folder>","Set the base folder for chromascope runs",{default:"chromascope-runs"}).action(async(e,t)=>{h.start("Starting \u2699\uFE0F"),(!e||!S(e))&&(h.fail(),console.error("Please provide a valid url"),process.exit(1));let r=O(t,h);c.setOptions({verbose:t.verbose}),c.debug(`Options provided: ${JSON.stringify(t)}`),e.startsWith("http")||(e=`https://${e}`),c.debug(`Diffing URL: ${e}`),c.debug(`Run ID: ${r.runId}`);let o=await P(e,r);h.succeed("Diff complete \u{1F389}"),o.forEach(D),process.exit(0)});l.help();l.version(x);(async()=>{try{l.parse(process.argv,{run:!1}),await l.runMatchedCommand()}catch(e){h.fail("Failed"),c.error("Error running command: ",e),process.exit(1)}})(); | ||
var b="1.1.1";var w=class{constructor(t=void 0){this.options={verbose:!1};this.setOptions(t)}setOptions(t){this.options={...this.options,...t}}log(...t){console.log(...t)}error(...t){console.error(...t)}debug(...t){this.options.verbose&&console.log(...t)}},k=new w,c=k;import x from"ora";var B=x({spinner:"orangeBluePulse"}),d=()=>x({spinner:"orangeBluePulse"}),p=B;var M=/^(?:(?:https?|ftp):\/\/)?(?:localhost|\S+(?:\.[^\s.]+)+|\[?[0-9a-fA-F:]+\]?)(?::\d+)?(?:\/[\w#!:.?+=&%@!\-\/]*)?(?:\?[\w&=]+)?$/i,S=e=>M.test(e),C=(e,t)=>{let r=[];return e.split(";").forEach(o=>{if(!o)return;let s=o.indexOf("="),i=o.slice(0,s),n=o.slice(s+1);r.push({name:i.trim(),value:n.trim(),url:t})}),r};import{chromium as W,firefox as I,webkit as j}from"@playwright/test";import f from"fs";import K from"pixelmatch";import{PNG as m}from"pngjs";var P=async(e,t)=>{c.setOptions({verbose:t.options.verbose});let r=[A(e,t),U(e,t),N(e,t)],o=await Promise.allSettled(r),[s,i,n]=o,a=s.status==="fulfilled"?s.value:null,h=i.status==="fulfilled"?i.value:null,l=n.status==="fulfilled"?n.value:null,g=await v(a,h,"chromium-webkit",t),F=await v(a,l,"chromium-firefox",t);return!t.options.saveDiff&&f.existsSync(t.options.folder)&&f.existsSync(t.runFolder)&&(t.spinner.text="Cleaning up \u{1F9F9}",f.rmdirSync(t.runFolder,{recursive:!0}),f.readdirSync(t.options.folder).length===0&&f.rmdirSync(t.options.folder)),t.spinner.text="",[{...g,browserName:"\u{1F34E} WebKit"},{...F,browserName:"\u{1F98A} Firefox"}]},D=e=>{c.log(`\u250C\u2500 ${e.browserName}`),c.log(`${e.diffPath?"\u251C\u2500":"\u2514\u2500"} \u{1F449} ${e.pixelChangePercentage.toFixed(2)}% pixel change compared to Chromium (${e.pixelChange}px)`),e.diffPath&&c.log(`\u2514\u2500 \u{1F449} Visual diff stored at ${e.diffPath}`)},U=async(e,t)=>{let r=d().start("Capturing WebKit screenshot \u{1F4F7}"),o=await j.launch(),s=await y(e,o,t);return r.succeed("Captured WebKit screenshot \u{1F4F8}"),s},N=async(e,t)=>{let r=d().start("Capturing Firefox screenshot \u{1F4F7}"),o=await I.launch(),s=await y(e,o,t);return r.succeed("Captured Firefox screenshot \u{1F4F8}"),s},A=async(e,t)=>{let r=d().start("Capturing Chromium screenshot \u{1F4F7}"),o=await W.launch(),s=await y(e,o,t);return r.succeed("Captured Chromium screenshot \u{1F4F8}"),s},y=async(e,t,r)=>{let o=await t.newContext();r.options.cookie&&await o.addCookies(C(r.options.cookie,e));let i=t.browserType().name(),n=await o.newPage();await n.goto(e);let a=r.options.saveDiff?`${r.runFolder}/${i}.png`:void 0;return c.debug(`Saving ${i} screenshot to ${a}`),r.options.element?await n.locator(r.options.element).screenshot({path:a}):await n.screenshot({path:a,fullPage:r.options.fullPage})},v=async(e,t,r,o)=>{if(!e||!t)throw new Error("Screenshot buffer cannot be null");let s=m.sync.read(e),i=m.sync.read(t),n={width:Math.max(s.width,i.width),height:Math.max(s.height,i.height)};(s.width!==i.width||s.height!==i.height)&&(s=$(s,n),i=$(i,n));let a=new m({width:n.width,height:n.height}),h=K(s.data,i.data,a.data,n.width,n.height,{threshold:o.options.threshold}),l="";o.options.saveDiff&&(l=`${o.runFolder}/diff-${r}.png`,o.spinner.text=`Saving ${r} diff \u{1F5C4}\uFE0F`,f.writeFileSync(l,m.sync.write(a)));let g=h/(n.width*n.height)*100;return{pixelChange:h,pixelChangePercentage:g,diffPath:l}},$=(e,{width:t,height:r})=>{if(e.width===t&&e.height===r)return e;c.debug(`Resizing image to ${t}x${r}...`);let o=new Uint8Array(t*r*4);for(let s=0;s<r;s++)for(let i=0;i<t;i++){let n=(s*t+i)*4;if(s<e.height&&i<e.width){let a=(s*e.width+i)*4;o[n]=e.data[a],o[n+1]=e.data[a+1],o[n+2]=e.data[a+2],o[n+3]=e.data[a+3]}else o[n]=0,o[n+1]=0,o[n+2]=0,o[n+3]=0}return{data:Buffer.from(o),width:t,height:r}};function O(e,t){let r=L(),o=`${e.folder}/${r}`;return{runId:r,spinner:t,runFolder:o,options:e}}var L=()=>{let e=new Date,t=e.getFullYear().toString(),r=(e.getMonth()+1).toString().padStart(2,"0"),o=e.getDate().toString().padStart(2,"0"),s=e.getHours().toString().padStart(2,"0"),i=e.getMinutes().toString().padStart(2,"0"),n=e.getSeconds().toString().padStart(2,"0");return`${t}${r}${o}${s}${i}${n}`};import E from"cac";var u=E("chromascope");u.command("diff <url>","Diff the URL in chromium, firefox, and webkit. Using chromium as the base.").option("-e, --element <selector>","Diff only the element with the given selector").option("-f, --full-page","Take a full page screenshot").option("-v, --verbose","Show more output").option("-c, --cookie <cookie>","Add one or more cookies to the context. Format: key=value;key2=value2").option("-s, --save-diff","Save generated diff as png").option("-t, --threshold <threshold>","Set the threshold for the diff",{default:.2}).option("-f, --folder <folder>","Set the base folder for chromascope runs",{default:"chromascope-runs"}).action(async(e,t)=>{p.start("Starting \u2699\uFE0F"),(!e||!S(e))&&(p.fail(),console.error("Please provide a valid url"),process.exit(1));let r=O(t,p);c.setOptions({verbose:t.verbose}),c.debug(`Options provided: ${JSON.stringify(t)}`),e.startsWith("http")||(e=`https://${e}`),c.debug(`Diffing URL: ${e}`),c.debug(`Run ID: ${r.runId}`);let o=await P(e,r);p.succeed("Diff complete \u{1F389}"),o.forEach(D),process.exit(0)});u.help();u.version(b);(async()=>{try{u.parse(process.argv,{run:!1}),await u.runMatchedCommand()}catch(e){p.fail("Failed"),c.error("Error running command: ",e),process.exit(1)}})(); |
{ | ||
"name": "chromascope", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"author": "Stian Haga", | ||
@@ -5,0 +5,0 @@ "license": "ISC", |
Sorry, the diff of this file is not supported yet
19090