comparadise-utils 0.0.8 → 0.0.10
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/files.d.ts +7 -0
- package/dist/files.js +17 -0
- package/dist/images.d.ts +7 -1
- package/dist/images.js +27 -9
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2 -2
- package/dist/match-screenshot.d.ts +11 -9
- package/dist/match-screenshot.js +52 -45
- package/dist/screenshots.d.ts +20 -2
- package/dist/screenshots.js +71 -11
- package/package.json +1 -1
- package/dist/on-after-screenshot.d.ts +0 -2
- package/dist/on-after-screenshot.js +0 -51
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a file path that is relative to the root
|
|
3
|
+
* @param {string} type - Value to append to fileName
|
|
4
|
+
* @param {string} path - (optional) FileName which corresponds to a module Id
|
|
5
|
+
* returns a string of just the prefix or the fileName prepended by the prefix
|
|
6
|
+
*/
|
|
7
|
+
export declare function createImageFileName(path: string, type: string): string;
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createImageFileName = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a file path that is relative to the root
|
|
6
|
+
* @param {string} type - Value to append to fileName
|
|
7
|
+
* @param {string} path - (optional) FileName which corresponds to a module Id
|
|
8
|
+
* returns a string of just the prefix or the fileName prepended by the prefix
|
|
9
|
+
*/
|
|
10
|
+
function createImageFileName(path, type) {
|
|
11
|
+
let newPath = path;
|
|
12
|
+
if (path.startsWith('/')) {
|
|
13
|
+
newPath = `.${path}`;
|
|
14
|
+
}
|
|
15
|
+
return `${newPath}/${type}.png`;
|
|
16
|
+
}
|
|
17
|
+
exports.createImageFileName = createImageFileName;
|
package/dist/images.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { PNG } from 'pngjs';
|
|
2
|
+
/**
|
|
3
|
+
* Compares a base and new image and returns the pixel difference
|
|
4
|
+
* and diff PNG for writing the diff image to.
|
|
5
|
+
* @param {string} basePath - Full file path to base image
|
|
6
|
+
* @param {string} actualPath - Full file path to new image
|
|
7
|
+
*/
|
|
2
8
|
export declare function getDiffPixels(basePath: string, actualPath: string): {
|
|
3
|
-
diffPixels:
|
|
9
|
+
diffPixels: any;
|
|
4
10
|
diff: PNG;
|
|
5
11
|
};
|
package/dist/images.js
CHANGED
|
@@ -22,28 +22,33 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
26
|
exports.getDiffPixels = void 0;
|
|
30
27
|
const fs = __importStar(require("fs"));
|
|
31
28
|
const pngjs_1 = require("pngjs");
|
|
32
|
-
const
|
|
29
|
+
const pixelmatch = require('pixelmatch');
|
|
33
30
|
const PIXELMATCH_OPTIONS = {
|
|
34
31
|
threshold: 0.3
|
|
35
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Helper function to create reusable image resizer
|
|
35
|
+
*/
|
|
36
36
|
const createImageResizer = (width, height) => (source) => {
|
|
37
37
|
const resized = new pngjs_1.PNG({ width, height, fill: true });
|
|
38
38
|
pngjs_1.PNG.bitblt(source, resized, 0, 0, source.width, source.height, 0, 0);
|
|
39
39
|
return resized;
|
|
40
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Fills new area added after resize with transparent black color.
|
|
43
|
+
* I like idea of checker board pattern, but it seems to be too complicated
|
|
44
|
+
* to implement considering how low-level pngjs API is.
|
|
45
|
+
*/
|
|
41
46
|
const fillSizeDifference = (width, height) => (image) => {
|
|
42
47
|
const inArea = (x, y) => y > height || x > width;
|
|
43
48
|
for (let y = 0; y < image.height; y++) {
|
|
44
49
|
for (let x = 0; x < image.width; x++) {
|
|
45
50
|
if (inArea(x, y)) {
|
|
46
|
-
const idx = (image.width * y + x) << 2;
|
|
51
|
+
const idx = ((image.width * y) + x) << 2;
|
|
47
52
|
image.data[idx] = 0;
|
|
48
53
|
image.data[idx + 1] = 0;
|
|
49
54
|
image.data[idx + 2] = 0;
|
|
@@ -53,6 +58,10 @@ const fillSizeDifference = (width, height) => (image) => {
|
|
|
53
58
|
}
|
|
54
59
|
return image;
|
|
55
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Aligns images sizes to biggest common value
|
|
63
|
+
* and fills new pixels with transparent pixels
|
|
64
|
+
*/
|
|
56
65
|
function alignImagesToSameSize(firstImage, secondImage) {
|
|
57
66
|
// Keep original sizes to fill extended area later
|
|
58
67
|
const firstImageWidth = firstImage.width;
|
|
@@ -67,16 +76,25 @@ function alignImagesToSameSize(firstImage, secondImage) {
|
|
|
67
76
|
// Fill resized area with black transparent pixels
|
|
68
77
|
return [
|
|
69
78
|
fillSizeDifference(firstImageWidth, firstImageHeight)(resizedFirst),
|
|
70
|
-
fillSizeDifference(secondImageWidth, secondImageHeight)(resizedSecond)
|
|
79
|
+
fillSizeDifference(secondImageWidth, secondImageHeight)(resizedSecond),
|
|
71
80
|
];
|
|
72
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Compares a base and new image and returns the pixel difference
|
|
84
|
+
* and diff PNG for writing the diff image to.
|
|
85
|
+
* @param {string} basePath - Full file path to base image
|
|
86
|
+
* @param {string} actualPath - Full file path to new image
|
|
87
|
+
*/
|
|
73
88
|
function getDiffPixels(basePath, actualPath) {
|
|
74
89
|
const rawBase = pngjs_1.PNG.sync.read(fs.readFileSync(basePath));
|
|
75
90
|
const rawActual = pngjs_1.PNG.sync.read(fs.readFileSync(actualPath));
|
|
76
|
-
const hasSizeMismatch = rawBase.height !== rawActual.height
|
|
77
|
-
|
|
91
|
+
const hasSizeMismatch = (rawBase.height !== rawActual.height
|
|
92
|
+
|| rawBase.width !== rawActual.width);
|
|
93
|
+
const [base, actual] = hasSizeMismatch
|
|
94
|
+
? alignImagesToSameSize(rawBase, rawActual)
|
|
95
|
+
: [rawBase, rawActual];
|
|
78
96
|
const diff = new pngjs_1.PNG({ width: base.width, height: base.height });
|
|
79
|
-
const diffPixels = (
|
|
97
|
+
const diffPixels = pixelmatch(actual.data, base.data, diff.data, diff.width, diff.height, PIXELMATCH_OPTIONS);
|
|
80
98
|
return { diffPixels, diff };
|
|
81
99
|
}
|
|
82
100
|
exports.getDiffPixels = getDiffPixels;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
/// <reference types="cypress" />
|
|
2
2
|
export declare function setupVisualTests(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions): Cypress.PluginConfigOptions;
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Cypress {
|
|
5
|
+
interface Chainable {
|
|
6
|
+
matchScreenshot(args?: MatchScreenshotArgs): Chainable;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setupVisualTests = void 0;
|
|
4
4
|
const screenshots_1 = require("./screenshots");
|
|
5
|
-
const on_after_screenshot_1 = require("./on-after-screenshot");
|
|
6
5
|
function setupVisualTests(on, config) {
|
|
6
|
+
on('after:screenshot', screenshots_1.onAfterScreenshot);
|
|
7
7
|
on('task', {
|
|
8
8
|
baseExists: screenshots_1.baseExists,
|
|
9
9
|
compareScreenshots: screenshots_1.compareScreenshots,
|
|
10
|
+
createNewScreenshot: screenshots_1.createNewScreenshot,
|
|
10
11
|
log: (message) => {
|
|
11
12
|
console.log(message);
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
15
|
});
|
|
15
|
-
on('after:screenshot', on_after_screenshot_1.onAfterScreenshot);
|
|
16
16
|
return config;
|
|
17
17
|
}
|
|
18
18
|
exports.setupVisualTests = setupVisualTests;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/// <reference types="cypress" />
|
|
2
|
-
|
|
2
|
+
declare const PREFIX_DIFFERENTIATOR = "___";
|
|
3
|
+
declare const SUFFIX_TEST_IDENTIFIER = ".spec.ts";
|
|
4
|
+
declare const SCREENSHOTS_FOLDER_NAME = "screenshots";
|
|
5
|
+
declare function forceFont(): false | HTMLStyleElement;
|
|
6
|
+
declare function getTestFolderPathFromScripts(rawName?: string): {
|
|
7
|
+
name: string;
|
|
8
|
+
screenshotsFolder: string;
|
|
9
|
+
};
|
|
10
|
+
interface MatchScreenshotArgs {
|
|
3
11
|
rawName?: string;
|
|
4
12
|
options?: Partial<Cypress.ScreenshotOptions>;
|
|
5
|
-
};
|
|
6
|
-
export declare function matchScreenshot(subject: Cypress.JQueryWithSelector | Window | Document | void, args?: MatchScreenshotArgs): void;
|
|
7
|
-
declare global {
|
|
8
|
-
namespace Cypress {
|
|
9
|
-
interface Chainable {
|
|
10
|
-
matchScreenshot(args?: MatchScreenshotArgs): Chainable;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
13
|
}
|
|
14
|
+
declare function verifyImages(): void;
|
|
15
|
+
declare function matchScreenshot(subject: Cypress.JQueryWithSelector | Window | Document | void, args?: MatchScreenshotArgs): void;
|
package/dist/match-screenshot.js
CHANGED
|
@@ -1,67 +1,74 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (Cypress.$('img:visible').length > 0) {
|
|
6
|
-
cy.document()
|
|
7
|
-
.its('body')
|
|
8
|
-
.find('img')
|
|
9
|
-
.filter(':visible')
|
|
10
|
-
.then(images => {
|
|
11
|
-
if (images) {
|
|
12
|
-
cy.wrap(images).each($img => {
|
|
13
|
-
cy.wrap($img).should('exist').and('have.prop', 'naturalWidth');
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
}
|
|
2
|
+
const PREFIX_DIFFERENTIATOR = '___';
|
|
3
|
+
const SUFFIX_TEST_IDENTIFIER = '.spec.ts';
|
|
4
|
+
const SCREENSHOTS_FOLDER_NAME = 'screenshots';
|
|
19
5
|
function forceFont() {
|
|
20
|
-
const iframe = window.parent.document.querySelector(
|
|
6
|
+
const iframe = window.parent.document.querySelector("iframe");
|
|
21
7
|
const contentDocument = iframe && iframe.contentDocument;
|
|
22
8
|
if (contentDocument) {
|
|
23
9
|
const style = contentDocument.createElement('style');
|
|
24
10
|
style.type = 'text/css';
|
|
25
11
|
style.appendChild(contentDocument.createTextNode('* { font-family: Arial !important; }'));
|
|
26
12
|
contentDocument.head.appendChild(style);
|
|
13
|
+
return style;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
function getTestFolderPathFromScripts(rawName) {
|
|
18
|
+
const relativeTestPath = Cypress.spec.relative;
|
|
19
|
+
if (!relativeTestPath) {
|
|
20
|
+
throw new Error('❌ Could not find matching script in the Cypress DOM to infer the test folder path');
|
|
21
|
+
}
|
|
22
|
+
// i.e. payment-card-cvvdialog
|
|
23
|
+
const testName = relativeTestPath.substring(relativeTestPath.lastIndexOf('/') + 1, relativeTestPath.lastIndexOf(SUFFIX_TEST_IDENTIFIER));
|
|
24
|
+
const name = rawName || testName;
|
|
25
|
+
// i.e. screenshots/packages/flights/forced-choice/test/visual/forced-choice/payment-card-cvvdialog
|
|
26
|
+
const screenshotsFolder = `${SCREENSHOTS_FOLDER_NAME}/${relativeTestPath.substring(0, relativeTestPath.lastIndexOf(testName))}${name}`;
|
|
27
|
+
return {
|
|
28
|
+
name,
|
|
29
|
+
screenshotsFolder
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function verifyImages() {
|
|
33
|
+
if (Cypress.$('img:visible').length > 0) {
|
|
34
|
+
cy.document().its('body').find('img').filter(':visible').then((images) => {
|
|
35
|
+
if (images) {
|
|
36
|
+
cy.wrap(images).each(($img) => {
|
|
37
|
+
cy.wrap($img)
|
|
38
|
+
.should('exist')
|
|
39
|
+
.and('have.prop', 'naturalWidth');
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
27
43
|
}
|
|
28
44
|
}
|
|
29
45
|
function matchScreenshot(subject, args) {
|
|
30
|
-
const { rawName, options = {} } = args
|
|
46
|
+
const { rawName, options = {} } = args ?? {};
|
|
47
|
+
// Set up screen
|
|
31
48
|
forceFont();
|
|
49
|
+
// Making sure each image is visible before taking screenshots
|
|
32
50
|
verifyImages();
|
|
33
|
-
const { screenshotsFolder } =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
const testPath = Cypress.spec.relative;
|
|
38
|
-
const lastSlashIndex = testPath.lastIndexOf('/');
|
|
39
|
-
const testPathWithoutFileName = testPath.substring(0, lastSlashIndex);
|
|
40
|
-
const testFileName = testPath.substring(lastSlashIndex + 1);
|
|
41
|
-
const testFileNameWithoutExtension = testFileName.split('.')[0];
|
|
42
|
-
const testName = rawName || testFileNameWithoutExtension;
|
|
43
|
-
const screenshotPath = `${screenshotsFolder}/${testPathWithoutFileName}/${testName}`;
|
|
44
|
-
cy.task('baseExists', screenshotPath).then(hasBase => {
|
|
45
|
-
if (typeof hasBase !== 'boolean')
|
|
46
|
-
throw new Error('Result of baseExists task was not a boolean.');
|
|
51
|
+
const { name, screenshotsFolder } = getTestFolderPathFromScripts(rawName);
|
|
52
|
+
cy.task('baseExists', screenshotsFolder).then((hasBase) => {
|
|
53
|
+
const type = 'new';
|
|
47
54
|
const target = subject ? cy.wrap(subject) : cy;
|
|
48
|
-
//
|
|
49
|
-
target.screenshot(`${
|
|
55
|
+
// For easy slicing of path ignoring the root screenshot folder
|
|
56
|
+
target.screenshot(`${PREFIX_DIFFERENTIATOR}${screenshotsFolder}/${type}`, options);
|
|
50
57
|
if (!hasBase) {
|
|
51
|
-
cy.task('
|
|
52
|
-
|
|
58
|
+
cy.task('createNewScreenshot', screenshotsFolder).then(() => {
|
|
59
|
+
cy.task('log', `✅ A new base image was created for ${name}. Create this as a new base image via Comparadise!`);
|
|
60
|
+
});
|
|
53
61
|
}
|
|
54
|
-
cy.task('compareScreenshots',
|
|
55
|
-
if (typeof diffPixels !== 'number')
|
|
56
|
-
throw new Error('Result of compareScreenshots task was not a number.');
|
|
62
|
+
cy.task('compareScreenshots', screenshotsFolder).then((diffPixels) => {
|
|
57
63
|
if (diffPixels === 0) {
|
|
58
|
-
cy.log(
|
|
59
|
-
|
|
60
|
-
else {
|
|
61
|
-
cy.task('log', `❌ Actual image of differed by ${diffPixels} pixels.`);
|
|
64
|
+
cy.log(`✅ Actual image of ${name} was the same as base`);
|
|
65
|
+
return null;
|
|
62
66
|
}
|
|
67
|
+
const screenshotUrl = Cypress.env('BUILD_URL') ? `${Cypress.env('BUILD_URL')}artifact/${screenshotsFolder}` : screenshotsFolder;
|
|
68
|
+
cy.task('log', `❌ Actual image of ${name} differed by ${diffPixels} pixels.
|
|
69
|
+
See the diff image for more details >> ${screenshotUrl}/diff.png`);
|
|
63
70
|
});
|
|
71
|
+
return null;
|
|
64
72
|
});
|
|
65
73
|
}
|
|
66
|
-
exports.matchScreenshot = matchScreenshot;
|
|
67
74
|
Cypress.Commands.add('matchScreenshot', { prevSubject: ['optional', 'element', 'window', 'document'] }, matchScreenshot);
|
package/dist/screenshots.d.ts
CHANGED
|
@@ -1,2 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/// <reference types="cypress" />
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a base image exists
|
|
4
|
+
* @param path - Folder path where you can find the base.png image
|
|
5
|
+
* @returns true if path/base.png exists, false if not.
|
|
6
|
+
*/
|
|
7
|
+
export declare function baseExists(path: string): boolean;
|
|
8
|
+
export declare function createNewScreenshot(screenshotFolder: string): null;
|
|
9
|
+
/**
|
|
10
|
+
* Runs a visual regression test.
|
|
11
|
+
* @param screenshotFolder - Full screenshots folder where the base/new/diff
|
|
12
|
+
* images will be compared and written to.
|
|
13
|
+
*/
|
|
14
|
+
export declare function compareScreenshots(screenshotFolder: string): any;
|
|
15
|
+
/**
|
|
16
|
+
* Renames all root cypress screenshots to where the test was actually run.
|
|
17
|
+
* Should NOT be used standalone. Works with the matchScreenshot task.
|
|
18
|
+
* @param {Cypress.ScreenshotDetails} details
|
|
19
|
+
*/
|
|
20
|
+
export declare function onAfterScreenshot(details: Cypress.ScreenshotDetails): Promise<Cypress.AfterScreenshotReturnObject>;
|
package/dist/screenshots.js
CHANGED
|
@@ -23,40 +23,100 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.compareScreenshots = exports.baseExists = void 0;
|
|
26
|
+
exports.onAfterScreenshot = exports.compareScreenshots = exports.createNewScreenshot = exports.baseExists = void 0;
|
|
27
27
|
const fs = __importStar(require("fs"));
|
|
28
|
-
const path_1 = require("path");
|
|
29
28
|
const pngjs_1 = require("pngjs");
|
|
30
29
|
const images_1 = require("./images");
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const files_1 = require("./files");
|
|
31
|
+
/**
|
|
32
|
+
* Checks if a base image exists
|
|
33
|
+
* @param path - Folder path where you can find the base.png image
|
|
34
|
+
* @returns true if path/base.png exists, false if not.
|
|
35
|
+
*/
|
|
36
|
+
function baseExists(path) {
|
|
37
|
+
const fileName = (0, files_1.createImageFileName)(path, 'base');
|
|
33
38
|
const exists = fs.existsSync(fileName);
|
|
34
39
|
if (!exists) {
|
|
35
|
-
console.log(
|
|
40
|
+
console.log('Base image does not exist. This means a new one will be created. If your base should exist, something went wrong.');
|
|
36
41
|
}
|
|
37
42
|
return exists;
|
|
38
43
|
}
|
|
39
44
|
exports.baseExists = baseExists;
|
|
45
|
+
function createNewScreenshot(screenshotFolder) {
|
|
46
|
+
const newImage = pngjs_1.PNG.sync.read(fs.readFileSync((0, files_1.createImageFileName)(screenshotFolder, 'new')));
|
|
47
|
+
fs.writeFile((0, files_1.createImageFileName)(screenshotFolder, 'new'), pngjs_1.PNG.sync.write(newImage), (err) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
console.error('❌Unable to create new.png', err);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
exports.createNewScreenshot = createNewScreenshot;
|
|
55
|
+
/**
|
|
56
|
+
* Runs a visual regression test.
|
|
57
|
+
* @param screenshotFolder - Full screenshots folder where the base/new/diff
|
|
58
|
+
* images will be compared and written to.
|
|
59
|
+
*/
|
|
40
60
|
function compareScreenshots(screenshotFolder) {
|
|
41
|
-
const basePath = (0,
|
|
42
|
-
const actualPath = (0,
|
|
61
|
+
const basePath = (0, files_1.createImageFileName)(screenshotFolder, 'base');
|
|
62
|
+
const actualPath = (0, files_1.createImageFileName)(screenshotFolder, 'new');
|
|
43
63
|
const { diffPixels, diff } = (0, images_1.getDiffPixels)(basePath, actualPath);
|
|
44
64
|
if (diffPixels) {
|
|
45
65
|
// Create diff.png next to base and new for review
|
|
46
|
-
fs.writeFile((0,
|
|
66
|
+
fs.writeFile((0, files_1.createImageFileName)(screenshotFolder, 'diff'), pngjs_1.PNG.sync.write(diff), (err) => {
|
|
47
67
|
if (err) {
|
|
48
|
-
console.error('❌
|
|
68
|
+
console.error('❌Diff exists but unable to create diff.png', err);
|
|
49
69
|
}
|
|
50
70
|
});
|
|
51
71
|
}
|
|
52
72
|
else {
|
|
53
73
|
// Delete created new.png. Not needed if there's no diff
|
|
54
|
-
fs.unlink(actualPath, err => {
|
|
74
|
+
fs.unlink(actualPath, (err) => {
|
|
55
75
|
if (err) {
|
|
56
|
-
console.error('❌
|
|
76
|
+
console.error('❌No diff but unable to deleteactualPath}', err);
|
|
57
77
|
}
|
|
58
78
|
});
|
|
59
79
|
}
|
|
60
80
|
return diffPixels;
|
|
61
81
|
}
|
|
62
82
|
exports.compareScreenshots = compareScreenshots;
|
|
83
|
+
/**
|
|
84
|
+
* Renames all root cypress screenshots to where the test was actually run.
|
|
85
|
+
* Should NOT be used standalone. Works with the matchScreenshot task.
|
|
86
|
+
* @param {Cypress.ScreenshotDetails} details
|
|
87
|
+
*/
|
|
88
|
+
function onAfterScreenshot(details) {
|
|
89
|
+
console.log('🧸 Screenshot was saved to:', details.path);
|
|
90
|
+
if (!details.path.match('cypress')) {
|
|
91
|
+
return Promise.resolve({});
|
|
92
|
+
}
|
|
93
|
+
const getNewPath = (path) => {
|
|
94
|
+
let newPath = path
|
|
95
|
+
.slice(path.lastIndexOf('___') + 3);
|
|
96
|
+
console.log(newPath);
|
|
97
|
+
if (newPath.startsWith('/')) {
|
|
98
|
+
newPath = `.${newPath}`;
|
|
99
|
+
}
|
|
100
|
+
return newPath;
|
|
101
|
+
};
|
|
102
|
+
const newPath = getNewPath(details.path);
|
|
103
|
+
const newPathDir = newPath.substring(0, newPath.lastIndexOf('/'));
|
|
104
|
+
try {
|
|
105
|
+
fs.mkdirSync(newPathDir, { recursive: true });
|
|
106
|
+
console.log('🧸 No screenshot folder found in the package. Created new screenshot folder:', newPathDir);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
console.error('❌ Error creating new screenshot folder:', newPathDir, err);
|
|
110
|
+
}
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
fs.rename(details.path, newPath, (err) => {
|
|
113
|
+
if (err) {
|
|
114
|
+
reject(err);
|
|
115
|
+
}
|
|
116
|
+
// because we renamed/moved the image, resolve with the new path
|
|
117
|
+
// so it is accurate in the test results
|
|
118
|
+
resolve({ path: newPath });
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
exports.onAfterScreenshot = onAfterScreenshot;
|
package/package.json
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.onAfterScreenshot = void 0;
|
|
27
|
-
const fs = __importStar(require("fs"));
|
|
28
|
-
function onAfterScreenshot(details) {
|
|
29
|
-
console.log('🧸 Screenshot was saved to:', details.path);
|
|
30
|
-
if (!details.path.match('visual')) {
|
|
31
|
-
return Promise.resolve({});
|
|
32
|
-
}
|
|
33
|
-
const newPath = details.path.substring(details.path.lastIndexOf('cypress/screenshots'));
|
|
34
|
-
const newPathDir = newPath.substring(0, newPath.lastIndexOf('/'));
|
|
35
|
-
try {
|
|
36
|
-
fs.mkdirSync(newPathDir, { recursive: true });
|
|
37
|
-
console.log('🧸 No screenshot folder found in the package. Created new screenshot folder:', newPathDir);
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
console.error('❌ Error creating new screenshot folder:', newPathDir, err);
|
|
41
|
-
}
|
|
42
|
-
return new Promise((resolve, reject) => {
|
|
43
|
-
fs.rename(details.path, newPath, err => {
|
|
44
|
-
if (err) {
|
|
45
|
-
reject(err);
|
|
46
|
-
}
|
|
47
|
-
resolve({ path: newPath });
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
exports.onAfterScreenshot = onAfterScreenshot;
|