11import path from "path" ;
22import pixelmatch from "pixelmatch" ;
33import fs from "fs" ;
4- import { PNG } from "pngjs" ;
4+ import { PNG , PNGWithMetadata } from "pngjs" ;
55import { FILE_SUFFIX , IMAGE_SNAPSHOT_PREFIX , TASK } from "./constants" ;
66import moveFile from "move-file" ;
7+ import sharp from "sharp" ;
78
89type NotFalsy < T > = T extends false | null | undefined ? never : T ;
910
@@ -29,7 +30,25 @@ const fillSizeDifference = (width: number, height: number) => (image: PNG) => {
2930 return image ;
3031} ;
3132
32- const alignImagesToSameSize = ( firstImage : PNG , secondImage : PNG ) => {
33+ const importAndScaleImage = async ( cfg : {
34+ scaleFactor : number ;
35+ path : string ;
36+ } ) => {
37+ const imgBuffer = fs . readFileSync ( cfg . path ) ;
38+ const rawImgNew = PNG . sync . read ( imgBuffer ) ;
39+ if ( cfg . scaleFactor === 1 ) return rawImgNew ;
40+
41+ const newImageWidth = Math . ceil ( rawImgNew . width * cfg . scaleFactor ) ;
42+ const newImageHeight = Math . ceil ( rawImgNew . height * cfg . scaleFactor ) ;
43+ await sharp ( imgBuffer ) . resize ( newImageWidth , newImageHeight ) . toFile ( cfg . path ) ;
44+
45+ return PNG . sync . read ( fs . readFileSync ( cfg . path ) ) ;
46+ } ;
47+
48+ const alignImagesToSameSize = (
49+ firstImage : PNGWithMetadata ,
50+ secondImage : PNGWithMetadata
51+ ) => {
3352 const firstImageWidth = firstImage . width ;
3453 const firstImageHeight = firstImage . height ;
3554 const secondImageWidth = secondImage . width ;
@@ -63,6 +82,21 @@ export const initPlugin = (
6382 on : Cypress . PluginEvents ,
6483 config : Cypress . PluginConfigOptions
6584) => {
85+ if ( config . env [ "pluginVisualRegressionForceDeviceScaleFactor" ] !== false ) {
86+ // based on https://github.com/cypress-io/cypress/issues/2102#issuecomment-521299946
87+ on ( "before:browser:launch" , ( browser , launchOptions ) => {
88+ if ( browser . name === "chrome" || browser . name === "chromium" ) {
89+ launchOptions . args . push ( "--force-device-scale-factor=1" ) ;
90+ launchOptions . args . push ( "--high-dpi-support=1" ) ;
91+ } else if ( browser . name === "electron" && browser . isHeaded ) {
92+ // eslint-disable-next-line no-console
93+ console . log (
94+ "There isn't currently a way of setting the device scale factor in Cypress when running headed electron so we disable the image regression commands."
95+ ) ;
96+ }
97+ } ) ;
98+ }
99+
66100 on ( "task" , {
67101 [ TASK . getScreenshotPath ] ( { title, imagesDir, specPath } ) {
68102 return path . join (
@@ -86,8 +120,9 @@ export const initPlugin = (
86120
87121 return null ;
88122 } ,
89- [ TASK . compareImages ] (
123+ async [ TASK . compareImages ] (
90124 cfg : {
125+ scaleFactor : number ;
91126 title : string ;
92127 imgNew : string ;
93128 imgOld : string ;
@@ -100,7 +135,10 @@ export const initPlugin = (
100135 let errorMsg : string | undefined ;
101136
102137 if ( fs . existsSync ( cfg . imgOld ) && ! cfg . updateImages ) {
103- const rawImgNew = PNG . sync . read ( fs . readFileSync ( cfg . imgNew ) ) ;
138+ const rawImgNew = await importAndScaleImage ( {
139+ scaleFactor : cfg . scaleFactor ,
140+ path : cfg . imgNew ,
141+ } ) ;
104142 const rawImgOld = PNG . sync . read ( fs . readFileSync ( cfg . imgOld ) ) ;
105143 const isImgSizeDifferent =
106144 rawImgNew . height !== rawImgOld . height ||
0 commit comments