Skip to content

Commit 66b9f11

Browse files
Ws/canvas 2 jimp (#362)
* feat: initial setup - added a local module * chore: add new images * chore: temp branch with jimp implementation * feat: add local resemble with Jimp implementation - add resemble fork with Jimp implementation - remove canvas and resemble - revert vitest-fix - update build * chore: update lock * fix: fix cjs * fix: fix default import * fix: fix rotation * chore: small fixes * feat: add `--update-visual-baseline` feature - fix watch mode to prevent errors * chore: create a changeset
1 parent eca2fb4 commit 66b9f11

34 files changed

+1490
-478
lines changed

.changeset/two-geckos-sit.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
"webdriver-image-comparison": major
3+
"@wdio/visual-service": major
4+
---
5+
6+
# 💥 Breaking
7+
8+
This PR replaces Canvas as a dependency with Jimp. This removes the need to use system dependencies and will reduce the number of system dependency errors/issues (node-gyp/canvas and so on). This will, in the end, make the life of our end users way easier due to:
9+
10+
- less errors
11+
- less complex test environments
12+
13+
> [!note]
14+
> Extensive research has been done and we have chosen to "fork" ResembleJS, adjust it by making use of Jimp instead of Canvas and break the browser API because the fork will only be used in a nodejs environment
15+
> Investigation showed that creating a wrapper would even make it slower, so we went for the breaking change in the API by just replacing Canvas with Jimp
16+
17+
> [!important]
18+
> There is a performance impact where Canvas is around 70% faster than Jimp. This has been measured without using WebdriverIO and only comparing images. When the "old" implementation with WebdriverIO combined with Canvas or Jimp is compared, we hardly see a performance impact.
19+
20+
# 🚀 New Features
21+
22+
Update the baseline images through the command line by adding the argument `--update-visual-baseline`. This will
23+
24+
- automatically copy the actual take screenshot and put it in the baseline folder
25+
- if there are differences it will let the test pass because the baseline has been updated
26+
27+
**Usage:**
28+
29+
```sh
30+
npm run test.local.desktop --update-visual-baseline
31+
```
32+
33+
When running logs info/debug mode you will see the following logs added
34+
35+
```logs
36+
[0-0] ..............
37+
[0-0] #####################################################################################
38+
[0-0] INFO:
39+
[0-0] Updated the actual image to
40+
[0-0] /Users/wswebcreation/Git/wdio/visual-testing/localBaseline/chromel/demo-chrome-1366x768.png
41+
[0-0] #####################################################################################
42+
[0-0] ..........
43+
```
44+
45+
# 💅 Polish
46+
47+
- remove Vitest fix
48+
- add app images
49+
- update the build

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"scripts": {
1313
"build": "pnpm run -r build",
14-
"clean": "rimraf coverage build .tmp",
14+
"clean": "rimraf coverage dist .tmp",
1515
"release": "run-s build && changeset publish",
1616
"test": "run-s test:*",
1717
"test:lint": "eslint --cache packages tests",

packages/ocr-service/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"scripts": {
2525
"build": "run-s clean build:*",
2626
"build:tsc": "tsc --project ./tsconfig.json",
27-
"clean": "rimraf coverage build .tmp",
27+
"clean": "rimraf coverage dist .tmp",
2828
"watch": "pnpm run build:tsc -w"
2929
},
3030
"dependencies": {
@@ -37,5 +37,9 @@
3737
"node-tesseract-ocr": "^2.2.1",
3838
"tesseract.js": "^5.1.0",
3939
"xml2js": "^0.6.2"
40+
},
41+
"devDependencies": {
42+
"@types/inquirer": "~9.0.7",
43+
"@types/xml2js": "~0.4.14"
4044
}
41-
}
45+
}

packages/visual-service/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"scripts": {
2323
"build": "run-s clean build:*",
2424
"build:tsc": "tsc --project ./tsconfig.json",
25-
"clean": "rimraf coverage build .tmp",
25+
"clean": "rimraf coverage dist .tmp",
2626
"watch": "pnpm run build:tsc -w"
2727
},
2828
"dependencies": {
@@ -31,5 +31,6 @@
3131
"@wdio/types": "^8.38.2",
3232
"node-fetch": "^3.3.2",
3333
"webdriver-image-comparison": "^5.1.0"
34-
}
35-
}
34+
},
35+
"devDependencies": {}
36+
}

packages/webdriver-image-comparison/package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,24 @@
1717
"url": "https://github.com/webdriverio/visual-testing/issues"
1818
},
1919
"scripts": {
20-
"build": "tsc",
21-
"clean": "rimraf coverage build tmp",
22-
"watch": "npm run build -- -w"
20+
"build": "run-s clean:build copy-js build:*",
21+
"build:tsc": "tsc --project ./tsconfig.json",
22+
"clean:build": "rimraf coverage dist .tmp",
23+
"clean:watch": "rimraf coverage .tmp",
24+
"copy-js": "copyfiles -u 1 src/resemble/resemble.jimp.cjs dist/",
25+
"watch": "run-s clean:watch copy-js watch:*",
26+
"watch:tsc": "pnpm run build:tsc -w",
27+
"watch:js": "node -e \"require('fs').watchFile('src/resemble/resemble.jimp.cjs', () => { require('child_process').exec('npm run copy-js'); });\""
2328
},
2429
"dependencies": {
25-
"canvas": "^2.11.2",
2630
"fs-extra": "^11.2.0",
27-
"resemblejs": "^5.0.0",
31+
"jimp": "^0.22.12",
2832
"@wdio/logger": "^8.38.0"
2933
},
3034
"devDependencies": {
3135
"@types/copyfiles": "~2.4.4",
3236
"@types/fs-extra": "^11.0.4",
33-
"@types/resemblejs": "^4.1.3",
37+
"@types/jimp": "^0.2.28",
3438
"copyfiles": "^2.4.1",
3539
"webdriverio": "^8.38.2"
3640
}

packages/webdriver-image-comparison/src/helpers/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,15 @@ export function isObject(item:unknown) {
313313
}
314314

315315
/**
316-
* Validate if i's storybook
316+
* Validate if it's storybook
317317
*/
318318
export function isStorybook(){
319319
return process.argv.includes('--storybook')
320320
}
321+
322+
/**
323+
* Check if we want to update baseline images
324+
*/
325+
export function updateVisualBaseline(): boolean {
326+
return process.argv.includes('--update-visual-baseline')
327+
}

packages/webdriver-image-comparison/src/methods/images.interfaces.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CanvasRenderingContext2D } from 'canvas'
1+
import type Jimp from 'jimp'
22
import type { RectanglesOutput } from './rectangles.interfaces.js'
33
import type { Folders } from '../base.interfaces.js'
44

@@ -154,8 +154,6 @@ export interface CroppedBase64Image {
154154
export interface RotateBase64ImageOptions {
155155
base64Image: string;
156156
degrees: number;
157-
newHeight: number;
158-
newWidth: number;
159157
}
160158

161159
export interface CropAndConvertToDataURL {
@@ -187,6 +185,13 @@ export interface DimensionsWarning {
187185
type: string,
188186
}
189187

188+
export interface CheckBaselineImageExists {
189+
actualFilePath: string,
190+
baselineFilePath: string,
191+
autoSaveBaseline?: boolean,
192+
updateBaseline?: boolean,
193+
}
194+
190195
export interface RotatedImage {
191196
isWebDriverElementScreenshot: boolean,
192197
isLandscape: boolean,
@@ -195,10 +200,10 @@ export interface RotatedImage {
195200

196201
export interface HandleIOSBezelCorners {
197202
addIOSBezelCorners: boolean,
198-
ctx: CanvasRenderingContext2D,
199203
deviceName: string,
200204
devicePixelRatio: number,
201205
height: number,
206+
image: Jimp,
202207
isLandscape: boolean,
203208
width: number,
204209
}

0 commit comments

Comments
 (0)