1
1
import path from "path" ;
2
2
import pixelmatch from "pixelmatch" ;
3
3
import fs from "fs" ;
4
- import { PNG } from "pngjs" ;
4
+ import { PNG , PNGWithMetadata } from "pngjs" ;
5
5
import { FILE_SUFFIX , IMAGE_SNAPSHOT_PREFIX , TASK } from "./constants" ;
6
6
import moveFile from "move-file" ;
7
+ import sharp from "sharp" ;
7
8
8
9
type NotFalsy < T > = T extends false | null | undefined ? never : T ;
9
10
@@ -29,7 +30,25 @@ const fillSizeDifference = (width: number, height: number) => (image: PNG) => {
29
30
return image ;
30
31
} ;
31
32
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
+ ) => {
33
52
const firstImageWidth = firstImage . width ;
34
53
const firstImageHeight = firstImage . height ;
35
54
const secondImageWidth = secondImage . width ;
@@ -63,6 +82,21 @@ export const initPlugin = (
63
82
on : Cypress . PluginEvents ,
64
83
config : Cypress . PluginConfigOptions
65
84
) => {
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
+
66
100
on ( "task" , {
67
101
[ TASK . getScreenshotPath ] ( { title, imagesDir, specPath } ) {
68
102
return path . join (
@@ -86,8 +120,9 @@ export const initPlugin = (
86
120
87
121
return null ;
88
122
} ,
89
- [ TASK . compareImages ] (
123
+ async [ TASK . compareImages ] (
90
124
cfg : {
125
+ scaleFactor : number ;
91
126
title : string ;
92
127
imgNew : string ;
93
128
imgOld : string ;
@@ -100,7 +135,10 @@ export const initPlugin = (
100
135
let errorMsg : string | undefined ;
101
136
102
137
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
+ } ) ;
104
142
const rawImgOld = PNG . sync . read ( fs . readFileSync ( cfg . imgOld ) ) ;
105
143
const isImgSizeDifferent =
106
144
rawImgNew . height !== rawImgOld . height ||
0 commit comments