ftmocks-utils 1.4.8 → 1.4.9
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/package.json +1 -1
- package/src/event-run-utils.js +48 -11
package/package.json
CHANGED
package/src/event-run-utils.js
CHANGED
|
@@ -2,6 +2,32 @@ const path = require("path");
|
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const { getMockDir, nameToFolder } = require("./common-utils");
|
|
4
4
|
|
|
5
|
+
const createDiffImage = async (img1, img2, diffPath) => {
|
|
6
|
+
const pixelmatch = (await import("pixelmatch")).default;
|
|
7
|
+
const { PNG } = (await import("pngjs")).default;
|
|
8
|
+
|
|
9
|
+
const { width, height } = img1;
|
|
10
|
+
|
|
11
|
+
const diff = new PNG({ width, height });
|
|
12
|
+
|
|
13
|
+
const numDiffPixels = pixelmatch(
|
|
14
|
+
img1.data,
|
|
15
|
+
img2.data,
|
|
16
|
+
diff.data,
|
|
17
|
+
width,
|
|
18
|
+
height,
|
|
19
|
+
{
|
|
20
|
+
threshold: 0.1, // sensitivity
|
|
21
|
+
diffColor: [255, 0, 0], // highlight color (red)
|
|
22
|
+
diffMask: false,
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
fs.writeFileSync(diffPath, PNG.sync.write(diff));
|
|
27
|
+
|
|
28
|
+
return numDiffPixels;
|
|
29
|
+
};
|
|
30
|
+
|
|
5
31
|
const matchAndReplaceScreenshot = async (page, event, screenshotsDir) => {
|
|
6
32
|
const pixelmatch = (await import("pixelmatch")).default;
|
|
7
33
|
const { PNG } = (await import("pngjs")).default;
|
|
@@ -13,7 +39,10 @@ const matchAndReplaceScreenshot = async (page, event, screenshotsDir) => {
|
|
|
13
39
|
|
|
14
40
|
if (!fs.existsSync(file)) {
|
|
15
41
|
fs.renameSync(newFile, file);
|
|
16
|
-
return
|
|
42
|
+
return {
|
|
43
|
+
replaced: true,
|
|
44
|
+
diffPath: null,
|
|
45
|
+
};
|
|
17
46
|
}
|
|
18
47
|
|
|
19
48
|
const img1 = PNG.sync.read(fs.readFileSync(file));
|
|
@@ -26,17 +55,27 @@ const matchAndReplaceScreenshot = async (page, event, screenshotsDir) => {
|
|
|
26
55
|
if (diff > 0) {
|
|
27
56
|
console.log(`Screenshot changed → replacing: ${file}`);
|
|
28
57
|
fs.renameSync(newFile, file); // overwrite only when mismatch
|
|
29
|
-
|
|
58
|
+
await createDiffImage(
|
|
59
|
+
img1,
|
|
60
|
+
img2,
|
|
61
|
+
path.join(screenshotsDir, `diff_${event.id}.png`)
|
|
62
|
+
);
|
|
63
|
+
return {
|
|
64
|
+
replaced: true,
|
|
65
|
+
diffPath: `diff_${event.id}.png`,
|
|
66
|
+
};
|
|
30
67
|
} else {
|
|
31
68
|
console.log(`Screenshot did not change → removing temp file: ${newFile}`);
|
|
32
69
|
fs.unlinkSync(newFile); // no change → remove temp file
|
|
33
|
-
return
|
|
70
|
+
return {
|
|
71
|
+
replaced: false,
|
|
72
|
+
diffPath: null,
|
|
73
|
+
};
|
|
34
74
|
}
|
|
35
75
|
};
|
|
36
76
|
|
|
37
77
|
const getLocator = async (page, event) => {
|
|
38
78
|
// Check if the event.target exists on the page before returning it.
|
|
39
|
-
console.log("➡ Getting locator for event", event);
|
|
40
79
|
if (event && event.target && typeof page !== "undefined" && page.locator) {
|
|
41
80
|
let locator = null;
|
|
42
81
|
while (!locator) {
|
|
@@ -64,7 +103,6 @@ const getLocator = async (page, event) => {
|
|
|
64
103
|
} catch (error) {
|
|
65
104
|
console.error("Error getting locator", error, selector);
|
|
66
105
|
}
|
|
67
|
-
console.log("➡ Waiting for locator", event);
|
|
68
106
|
await page.waitForTimeout(500);
|
|
69
107
|
}
|
|
70
108
|
return locator;
|
|
@@ -134,22 +172,24 @@ const runEvent = async ({
|
|
|
134
172
|
healSelectors = false,
|
|
135
173
|
}) => {
|
|
136
174
|
try {
|
|
137
|
-
console.log("➡ Running event", event);
|
|
138
175
|
const beforeEvent = async () => {
|
|
139
176
|
await page.waitForTimeout(delay);
|
|
140
177
|
if (screenshots) {
|
|
141
|
-
const
|
|
178
|
+
const res = await matchAndReplaceScreenshot(
|
|
142
179
|
page,
|
|
143
180
|
event,
|
|
144
181
|
screenshotsDir
|
|
145
182
|
);
|
|
146
|
-
if (replaced) {
|
|
183
|
+
if (res.replaced) {
|
|
147
184
|
const locator = await getLocator(page, event);
|
|
148
185
|
const position = await getSelectorPosition(page, locator);
|
|
149
186
|
event.screenshotInfo = {
|
|
150
187
|
name: `${event.id}.png`,
|
|
151
188
|
position,
|
|
152
189
|
time: new Date().toISOString(),
|
|
190
|
+
diffPath: res.diffPath
|
|
191
|
+
? res.diffPath
|
|
192
|
+
: event.screenshotInfo?.diffPath,
|
|
153
193
|
};
|
|
154
194
|
}
|
|
155
195
|
}
|
|
@@ -243,7 +283,6 @@ const runEvent = async ({
|
|
|
243
283
|
|
|
244
284
|
const isValidEvent = (event) => {
|
|
245
285
|
try {
|
|
246
|
-
console.log("➡ Validating event", event);
|
|
247
286
|
switch (event?.type) {
|
|
248
287
|
case "click":
|
|
249
288
|
return true;
|
|
@@ -321,9 +360,7 @@ const runEventsInPresentationMode = async (page, ftmocksConifg, testName) => {
|
|
|
321
360
|
|
|
322
361
|
// Expose Node function
|
|
323
362
|
await page.exposeFunction("nextEvent", async () => {
|
|
324
|
-
console.log("➡ Next event triggered!");
|
|
325
363
|
if (currentEventIndex === events.length) {
|
|
326
|
-
console.log("➡ No more events to run!");
|
|
327
364
|
return false;
|
|
328
365
|
}
|
|
329
366
|
let result = await runEvent({ page, event: events[currentEventIndex] });
|