|
f7eb47b…
|
lmata
|
1 |
"use strict"; |
|
f7eb47b…
|
lmata
|
2 |
var __create = Object.create; |
|
f7eb47b…
|
lmata
|
3 |
var __defProp = Object.defineProperty; |
|
f7eb47b…
|
lmata
|
4 |
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
|
f7eb47b…
|
lmata
|
5 |
var __getOwnPropNames = Object.getOwnPropertyNames; |
|
f7eb47b…
|
lmata
|
6 |
var __getProtoOf = Object.getPrototypeOf; |
|
f7eb47b…
|
lmata
|
7 |
var __hasOwnProp = Object.prototype.hasOwnProperty; |
|
f7eb47b…
|
lmata
|
8 |
var __export = (target, all) => { |
|
f7eb47b…
|
lmata
|
9 |
for (var name in all) |
|
f7eb47b…
|
lmata
|
10 |
__defProp(target, name, { get: all[name], enumerable: true }); |
|
f7eb47b…
|
lmata
|
11 |
}; |
|
f7eb47b…
|
lmata
|
12 |
var __copyProps = (to, from, except, desc) => { |
|
f7eb47b…
|
lmata
|
13 |
if (from && typeof from === "object" || typeof from === "function") { |
|
f7eb47b…
|
lmata
|
14 |
for (let key of __getOwnPropNames(from)) |
|
f7eb47b…
|
lmata
|
15 |
if (!__hasOwnProp.call(to, key) && key !== except) |
|
f7eb47b…
|
lmata
|
16 |
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); |
|
f7eb47b…
|
lmata
|
17 |
} |
|
f7eb47b…
|
lmata
|
18 |
return to; |
|
f7eb47b…
|
lmata
|
19 |
}; |
|
f7eb47b…
|
lmata
|
20 |
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
|
f7eb47b…
|
lmata
|
21 |
// If the importer is in node compatibility mode or this is not an ESM |
|
f7eb47b…
|
lmata
|
22 |
// file that has been converted to a CommonJS file using a Babel- |
|
f7eb47b…
|
lmata
|
23 |
// compatible transform (i.e. "__esModule" has not been set), then set |
|
f7eb47b…
|
lmata
|
24 |
// "default" to the CommonJS "module.exports" for node compatibility. |
|
f7eb47b…
|
lmata
|
25 |
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
|
f7eb47b…
|
lmata
|
26 |
mod |
|
f7eb47b…
|
lmata
|
27 |
)); |
|
f7eb47b…
|
lmata
|
28 |
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
|
f7eb47b…
|
lmata
|
29 |
var toMatchSnapshot_exports = {}; |
|
f7eb47b…
|
lmata
|
30 |
__export(toMatchSnapshot_exports, { |
|
f7eb47b…
|
lmata
|
31 |
toHaveScreenshot: () => toHaveScreenshot, |
|
f7eb47b…
|
lmata
|
32 |
toHaveScreenshotStepTitle: () => toHaveScreenshotStepTitle, |
|
f7eb47b…
|
lmata
|
33 |
toMatchSnapshot: () => toMatchSnapshot |
|
f7eb47b…
|
lmata
|
34 |
}); |
|
f7eb47b…
|
lmata
|
35 |
module.exports = __toCommonJS(toMatchSnapshot_exports); |
|
f7eb47b…
|
lmata
|
36 |
var import_fs = __toESM(require("fs")); |
|
f7eb47b…
|
lmata
|
37 |
var import_path = __toESM(require("path")); |
|
f7eb47b…
|
lmata
|
38 |
var import_utils = require("playwright-core/lib/utils"); |
|
f7eb47b…
|
lmata
|
39 |
var import_utils2 = require("playwright-core/lib/utils"); |
|
f7eb47b…
|
lmata
|
40 |
var import_utilsBundle = require("playwright-core/lib/utilsBundle"); |
|
f7eb47b…
|
lmata
|
41 |
var import_util = require("../util"); |
|
f7eb47b…
|
lmata
|
42 |
var import_globals = require("../common/globals"); |
|
f7eb47b…
|
lmata
|
43 |
const NonConfigProperties = [ |
|
f7eb47b…
|
lmata
|
44 |
"clip", |
|
f7eb47b…
|
lmata
|
45 |
"fullPage", |
|
f7eb47b…
|
lmata
|
46 |
"mask", |
|
f7eb47b…
|
lmata
|
47 |
"maskColor", |
|
f7eb47b…
|
lmata
|
48 |
"omitBackground", |
|
f7eb47b…
|
lmata
|
49 |
"timeout" |
|
f7eb47b…
|
lmata
|
50 |
]; |
|
f7eb47b…
|
lmata
|
51 |
class SnapshotHelper { |
|
f7eb47b…
|
lmata
|
52 |
constructor(state, testInfo, matcherName, locator, anonymousSnapshotExtension, configOptions, nameOrOptions, optOptions) { |
|
f7eb47b…
|
lmata
|
53 |
let name; |
|
f7eb47b…
|
lmata
|
54 |
if (Array.isArray(nameOrOptions) || typeof nameOrOptions === "string") { |
|
f7eb47b…
|
lmata
|
55 |
name = nameOrOptions; |
|
f7eb47b…
|
lmata
|
56 |
this.options = { ...optOptions }; |
|
f7eb47b…
|
lmata
|
57 |
} else { |
|
f7eb47b…
|
lmata
|
58 |
const { name: nameFromOptions, ...options } = nameOrOptions; |
|
f7eb47b…
|
lmata
|
59 |
this.options = options; |
|
f7eb47b…
|
lmata
|
60 |
name = nameFromOptions; |
|
f7eb47b…
|
lmata
|
61 |
} |
|
f7eb47b…
|
lmata
|
62 |
this.name = Array.isArray(name) ? name.join(import_path.default.sep) : name || ""; |
|
f7eb47b…
|
lmata
|
63 |
const resolvedPaths = testInfo._resolveSnapshotPaths(matcherName === "toHaveScreenshot" ? "screenshot" : "snapshot", name, "updateSnapshotIndex", anonymousSnapshotExtension); |
|
f7eb47b…
|
lmata
|
64 |
this.expectedPath = resolvedPaths.absoluteSnapshotPath; |
|
f7eb47b…
|
lmata
|
65 |
this.attachmentBaseName = resolvedPaths.relativeOutputPath; |
|
f7eb47b…
|
lmata
|
66 |
const outputBasePath = testInfo._getOutputPath(resolvedPaths.relativeOutputPath); |
|
f7eb47b…
|
lmata
|
67 |
this.legacyExpectedPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-expected"); |
|
f7eb47b…
|
lmata
|
68 |
this.previousPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-previous"); |
|
f7eb47b…
|
lmata
|
69 |
this.actualPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-actual"); |
|
f7eb47b…
|
lmata
|
70 |
this.diffPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-diff"); |
|
f7eb47b…
|
lmata
|
71 |
const filteredConfigOptions = { ...configOptions }; |
|
f7eb47b…
|
lmata
|
72 |
for (const prop of NonConfigProperties) |
|
f7eb47b…
|
lmata
|
73 |
delete filteredConfigOptions[prop]; |
|
f7eb47b…
|
lmata
|
74 |
this.options = { |
|
f7eb47b…
|
lmata
|
75 |
...filteredConfigOptions, |
|
f7eb47b…
|
lmata
|
76 |
...this.options |
|
f7eb47b…
|
lmata
|
77 |
}; |
|
f7eb47b…
|
lmata
|
78 |
if (this.options._comparator) { |
|
f7eb47b…
|
lmata
|
79 |
this.options.comparator = this.options._comparator; |
|
f7eb47b…
|
lmata
|
80 |
delete this.options._comparator; |
|
f7eb47b…
|
lmata
|
81 |
} |
|
f7eb47b…
|
lmata
|
82 |
if (this.options.maxDiffPixels !== void 0 && this.options.maxDiffPixels < 0) |
|
f7eb47b…
|
lmata
|
83 |
throw new Error("`maxDiffPixels` option value must be non-negative integer"); |
|
f7eb47b…
|
lmata
|
84 |
if (this.options.maxDiffPixelRatio !== void 0 && (this.options.maxDiffPixelRatio < 0 || this.options.maxDiffPixelRatio > 1)) |
|
f7eb47b…
|
lmata
|
85 |
throw new Error("`maxDiffPixelRatio` option value must be between 0 and 1"); |
|
f7eb47b…
|
lmata
|
86 |
this.matcherName = matcherName; |
|
f7eb47b…
|
lmata
|
87 |
this.locator = locator; |
|
f7eb47b…
|
lmata
|
88 |
this.updateSnapshots = testInfo.config.updateSnapshots; |
|
f7eb47b…
|
lmata
|
89 |
this.mimeType = import_utilsBundle.mime.getType(import_path.default.basename(this.expectedPath)) ?? "application/octet-stream"; |
|
f7eb47b…
|
lmata
|
90 |
this.comparator = (0, import_utils.getComparator)(this.mimeType); |
|
f7eb47b…
|
lmata
|
91 |
this.testInfo = testInfo; |
|
f7eb47b…
|
lmata
|
92 |
this.state = state; |
|
f7eb47b…
|
lmata
|
93 |
this.kind = this.mimeType.startsWith("image/") ? "Screenshot" : "Snapshot"; |
|
f7eb47b…
|
lmata
|
94 |
} |
|
f7eb47b…
|
lmata
|
95 |
createMatcherResult(message, pass, log) { |
|
f7eb47b…
|
lmata
|
96 |
const unfiltered = { |
|
f7eb47b…
|
lmata
|
97 |
name: this.matcherName, |
|
f7eb47b…
|
lmata
|
98 |
expected: this.expectedPath, |
|
f7eb47b…
|
lmata
|
99 |
actual: this.actualPath, |
|
f7eb47b…
|
lmata
|
100 |
diff: this.diffPath, |
|
f7eb47b…
|
lmata
|
101 |
pass, |
|
f7eb47b…
|
lmata
|
102 |
message: () => message, |
|
f7eb47b…
|
lmata
|
103 |
log |
|
f7eb47b…
|
lmata
|
104 |
}; |
|
f7eb47b…
|
lmata
|
105 |
return Object.fromEntries(Object.entries(unfiltered).filter(([_, v]) => v !== void 0)); |
|
f7eb47b…
|
lmata
|
106 |
} |
|
f7eb47b…
|
lmata
|
107 |
handleMissingNegated() { |
|
f7eb47b…
|
lmata
|
108 |
const isWriteMissingMode = this.updateSnapshots !== "none"; |
|
f7eb47b…
|
lmata
|
109 |
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? `, matchers using ".not" won't write them automatically.` : "."}`; |
|
f7eb47b…
|
lmata
|
110 |
return this.createMatcherResult(message, true); |
|
f7eb47b…
|
lmata
|
111 |
} |
|
f7eb47b…
|
lmata
|
112 |
handleDifferentNegated() { |
|
f7eb47b…
|
lmata
|
113 |
return this.createMatcherResult("", false); |
|
f7eb47b…
|
lmata
|
114 |
} |
|
f7eb47b…
|
lmata
|
115 |
handleMatchingNegated() { |
|
f7eb47b…
|
lmata
|
116 |
const message = [ |
|
f7eb47b…
|
lmata
|
117 |
import_utils2.colors.red(`${this.kind} comparison failed:`), |
|
f7eb47b…
|
lmata
|
118 |
"", |
|
f7eb47b…
|
lmata
|
119 |
indent("Expected result should be different from the actual one.", " ") |
|
f7eb47b…
|
lmata
|
120 |
].join("\n"); |
|
f7eb47b…
|
lmata
|
121 |
return this.createMatcherResult(message, true); |
|
f7eb47b…
|
lmata
|
122 |
} |
|
f7eb47b…
|
lmata
|
123 |
handleMissing(actual, step) { |
|
f7eb47b…
|
lmata
|
124 |
const isWriteMissingMode = this.updateSnapshots !== "none"; |
|
f7eb47b…
|
lmata
|
125 |
if (isWriteMissingMode) |
|
f7eb47b…
|
lmata
|
126 |
writeFileSync(this.expectedPath, actual); |
|
f7eb47b…
|
lmata
|
127 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-expected"), contentType: this.mimeType, path: this.expectedPath }); |
|
f7eb47b…
|
lmata
|
128 |
writeFileSync(this.actualPath, actual); |
|
f7eb47b…
|
lmata
|
129 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-actual"), contentType: this.mimeType, path: this.actualPath }); |
|
f7eb47b…
|
lmata
|
130 |
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? ", writing actual." : "."}`; |
|
f7eb47b…
|
lmata
|
131 |
if (this.updateSnapshots === "all" || this.updateSnapshots === "changed") { |
|
f7eb47b…
|
lmata
|
132 |
console.log(message); |
|
f7eb47b…
|
lmata
|
133 |
return this.createMatcherResult(message, true); |
|
f7eb47b…
|
lmata
|
134 |
} |
|
f7eb47b…
|
lmata
|
135 |
if (this.updateSnapshots === "missing") { |
|
f7eb47b…
|
lmata
|
136 |
this.testInfo._hasNonRetriableError = true; |
|
f7eb47b…
|
lmata
|
137 |
this.testInfo._failWithError(new Error(message)); |
|
f7eb47b…
|
lmata
|
138 |
return this.createMatcherResult("", true); |
|
f7eb47b…
|
lmata
|
139 |
} |
|
f7eb47b…
|
lmata
|
140 |
return this.createMatcherResult(message, false); |
|
f7eb47b…
|
lmata
|
141 |
} |
|
f7eb47b…
|
lmata
|
142 |
handleDifferent(actual, expected, previous, diff, header, diffError, log, step) { |
|
f7eb47b…
|
lmata
|
143 |
const output = [`${header}${indent(diffError, " ")}`]; |
|
f7eb47b…
|
lmata
|
144 |
if (this.name) { |
|
f7eb47b…
|
lmata
|
145 |
output.push(""); |
|
f7eb47b…
|
lmata
|
146 |
output.push(` Snapshot: ${this.name}`); |
|
f7eb47b…
|
lmata
|
147 |
} |
|
f7eb47b…
|
lmata
|
148 |
if (expected !== void 0) { |
|
f7eb47b…
|
lmata
|
149 |
writeFileSync(this.legacyExpectedPath, expected); |
|
f7eb47b…
|
lmata
|
150 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-expected"), contentType: this.mimeType, path: this.expectedPath }); |
|
f7eb47b…
|
lmata
|
151 |
} |
|
f7eb47b…
|
lmata
|
152 |
if (previous !== void 0) { |
|
f7eb47b…
|
lmata
|
153 |
writeFileSync(this.previousPath, previous); |
|
f7eb47b…
|
lmata
|
154 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-previous"), contentType: this.mimeType, path: this.previousPath }); |
|
f7eb47b…
|
lmata
|
155 |
} |
|
f7eb47b…
|
lmata
|
156 |
if (actual !== void 0) { |
|
f7eb47b…
|
lmata
|
157 |
writeFileSync(this.actualPath, actual); |
|
f7eb47b…
|
lmata
|
158 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-actual"), contentType: this.mimeType, path: this.actualPath }); |
|
f7eb47b…
|
lmata
|
159 |
} |
|
f7eb47b…
|
lmata
|
160 |
if (diff !== void 0) { |
|
f7eb47b…
|
lmata
|
161 |
writeFileSync(this.diffPath, diff); |
|
f7eb47b…
|
lmata
|
162 |
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-diff"), contentType: this.mimeType, path: this.diffPath }); |
|
f7eb47b…
|
lmata
|
163 |
} |
|
f7eb47b…
|
lmata
|
164 |
if (log?.length) |
|
f7eb47b…
|
lmata
|
165 |
output.push((0, import_utils.callLogText)(this.state.utils, log)); |
|
f7eb47b…
|
lmata
|
166 |
else |
|
f7eb47b…
|
lmata
|
167 |
output.push(""); |
|
f7eb47b…
|
lmata
|
168 |
return this.createMatcherResult(output.join("\n"), false, log); |
|
f7eb47b…
|
lmata
|
169 |
} |
|
f7eb47b…
|
lmata
|
170 |
handleMatching() { |
|
f7eb47b…
|
lmata
|
171 |
return this.createMatcherResult("", true); |
|
f7eb47b…
|
lmata
|
172 |
} |
|
f7eb47b…
|
lmata
|
173 |
} |
|
f7eb47b…
|
lmata
|
174 |
function toMatchSnapshot(received, nameOrOptions = {}, optOptions = {}) { |
|
f7eb47b…
|
lmata
|
175 |
const testInfo = (0, import_globals.currentTestInfo)(); |
|
f7eb47b…
|
lmata
|
176 |
if (!testInfo) |
|
f7eb47b…
|
lmata
|
177 |
throw new Error(`toMatchSnapshot() must be called during the test`); |
|
f7eb47b…
|
lmata
|
178 |
if (received instanceof Promise) |
|
f7eb47b…
|
lmata
|
179 |
throw new Error("An unresolved Promise was passed to toMatchSnapshot(), make sure to resolve it by adding await to it."); |
|
f7eb47b…
|
lmata
|
180 |
if (testInfo._projectInternal.ignoreSnapshots) |
|
f7eb47b…
|
lmata
|
181 |
return { pass: !this.isNot, message: () => "", name: "toMatchSnapshot", expected: nameOrOptions }; |
|
f7eb47b…
|
lmata
|
182 |
const configOptions = testInfo._projectInternal.expect?.toMatchSnapshot || {}; |
|
f7eb47b…
|
lmata
|
183 |
const helper = new SnapshotHelper( |
|
f7eb47b…
|
lmata
|
184 |
this, |
|
f7eb47b…
|
lmata
|
185 |
testInfo, |
|
f7eb47b…
|
lmata
|
186 |
"toMatchSnapshot", |
|
f7eb47b…
|
lmata
|
187 |
void 0, |
|
f7eb47b…
|
lmata
|
188 |
"." + determineFileExtension(received), |
|
f7eb47b…
|
lmata
|
189 |
configOptions, |
|
f7eb47b…
|
lmata
|
190 |
nameOrOptions, |
|
f7eb47b…
|
lmata
|
191 |
optOptions |
|
f7eb47b…
|
lmata
|
192 |
); |
|
f7eb47b…
|
lmata
|
193 |
if (this.isNot) { |
|
f7eb47b…
|
lmata
|
194 |
if (!import_fs.default.existsSync(helper.expectedPath)) |
|
f7eb47b…
|
lmata
|
195 |
return helper.handleMissingNegated(); |
|
f7eb47b…
|
lmata
|
196 |
const isDifferent = !!helper.comparator(received, import_fs.default.readFileSync(helper.expectedPath), helper.options); |
|
f7eb47b…
|
lmata
|
197 |
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated(); |
|
f7eb47b…
|
lmata
|
198 |
} |
|
f7eb47b…
|
lmata
|
199 |
if (!import_fs.default.existsSync(helper.expectedPath)) |
|
f7eb47b…
|
lmata
|
200 |
return helper.handleMissing(received, this._stepInfo); |
|
f7eb47b…
|
lmata
|
201 |
const expected = import_fs.default.readFileSync(helper.expectedPath); |
|
f7eb47b…
|
lmata
|
202 |
if (helper.updateSnapshots === "all") { |
|
f7eb47b…
|
lmata
|
203 |
if (!(0, import_utils.compareBuffersOrStrings)(received, expected)) |
|
f7eb47b…
|
lmata
|
204 |
return helper.handleMatching(); |
|
f7eb47b…
|
lmata
|
205 |
writeFileSync(helper.expectedPath, received); |
|
f7eb47b…
|
lmata
|
206 |
console.log(helper.expectedPath + " is not the same, writing actual."); |
|
f7eb47b…
|
lmata
|
207 |
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true); |
|
f7eb47b…
|
lmata
|
208 |
} |
|
f7eb47b…
|
lmata
|
209 |
if (helper.updateSnapshots === "changed") { |
|
f7eb47b…
|
lmata
|
210 |
const result2 = helper.comparator(received, expected, helper.options); |
|
f7eb47b…
|
lmata
|
211 |
if (!result2) |
|
f7eb47b…
|
lmata
|
212 |
return helper.handleMatching(); |
|
f7eb47b…
|
lmata
|
213 |
writeFileSync(helper.expectedPath, received); |
|
f7eb47b…
|
lmata
|
214 |
console.log(helper.expectedPath + " does not match, writing actual."); |
|
f7eb47b…
|
lmata
|
215 |
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true); |
|
f7eb47b…
|
lmata
|
216 |
} |
|
f7eb47b…
|
lmata
|
217 |
const result = helper.comparator(received, expected, helper.options); |
|
f7eb47b…
|
lmata
|
218 |
if (!result) |
|
f7eb47b…
|
lmata
|
219 |
return helper.handleMatching(); |
|
f7eb47b…
|
lmata
|
220 |
const header = (0, import_utils.formatMatcherMessage)(this.utils, { promise: this.promise, isNot: this.isNot, matcherName: "toMatchSnapshot", receiver: (0, import_utils.isString)(received) ? "string" : "Buffer", expectation: "expected" }); |
|
f7eb47b…
|
lmata
|
221 |
return helper.handleDifferent(received, expected, void 0, result.diff, header, result.errorMessage, void 0, this._stepInfo); |
|
f7eb47b…
|
lmata
|
222 |
} |
|
f7eb47b…
|
lmata
|
223 |
function toHaveScreenshotStepTitle(nameOrOptions = {}, optOptions = {}) { |
|
f7eb47b…
|
lmata
|
224 |
let name; |
|
f7eb47b…
|
lmata
|
225 |
if (typeof nameOrOptions === "object" && !Array.isArray(nameOrOptions)) |
|
f7eb47b…
|
lmata
|
226 |
name = nameOrOptions.name; |
|
f7eb47b…
|
lmata
|
227 |
else |
|
f7eb47b…
|
lmata
|
228 |
name = nameOrOptions; |
|
f7eb47b…
|
lmata
|
229 |
return Array.isArray(name) ? name.join(import_path.default.sep) : name || ""; |
|
f7eb47b…
|
lmata
|
230 |
} |
|
f7eb47b…
|
lmata
|
231 |
async function toHaveScreenshot(pageOrLocator, nameOrOptions = {}, optOptions = {}) { |
|
f7eb47b…
|
lmata
|
232 |
const testInfo = (0, import_globals.currentTestInfo)(); |
|
f7eb47b…
|
lmata
|
233 |
if (!testInfo) |
|
f7eb47b…
|
lmata
|
234 |
throw new Error(`toHaveScreenshot() must be called during the test`); |
|
f7eb47b…
|
lmata
|
235 |
if (testInfo._projectInternal.ignoreSnapshots) |
|
f7eb47b…
|
lmata
|
236 |
return { pass: !this.isNot, message: () => "", name: "toHaveScreenshot", expected: nameOrOptions }; |
|
f7eb47b…
|
lmata
|
237 |
(0, import_util.expectTypes)(pageOrLocator, ["Page", "Locator"], "toHaveScreenshot"); |
|
f7eb47b…
|
lmata
|
238 |
const [page, locator] = pageOrLocator.constructor.name === "Page" ? [pageOrLocator, void 0] : [pageOrLocator.page(), pageOrLocator]; |
|
f7eb47b…
|
lmata
|
239 |
const configOptions = testInfo._projectInternal.expect?.toHaveScreenshot || {}; |
|
f7eb47b…
|
lmata
|
240 |
const helper = new SnapshotHelper(this, testInfo, "toHaveScreenshot", locator, void 0, configOptions, nameOrOptions, optOptions); |
|
f7eb47b…
|
lmata
|
241 |
if (!helper.expectedPath.toLowerCase().endsWith(".png")) |
|
f7eb47b…
|
lmata
|
242 |
throw new Error(`Screenshot name "${import_path.default.basename(helper.expectedPath)}" must have '.png' extension`); |
|
f7eb47b…
|
lmata
|
243 |
(0, import_util.expectTypes)(pageOrLocator, ["Page", "Locator"], "toHaveScreenshot"); |
|
f7eb47b…
|
lmata
|
244 |
const style = await loadScreenshotStyles(helper.options.stylePath); |
|
f7eb47b…
|
lmata
|
245 |
const timeout = helper.options.timeout ?? this.timeout; |
|
f7eb47b…
|
lmata
|
246 |
const expectScreenshotOptions = { |
|
f7eb47b…
|
lmata
|
247 |
locator, |
|
f7eb47b…
|
lmata
|
248 |
animations: helper.options.animations ?? "disabled", |
|
f7eb47b…
|
lmata
|
249 |
caret: helper.options.caret ?? "hide", |
|
f7eb47b…
|
lmata
|
250 |
clip: helper.options.clip, |
|
f7eb47b…
|
lmata
|
251 |
fullPage: helper.options.fullPage, |
|
f7eb47b…
|
lmata
|
252 |
mask: helper.options.mask, |
|
f7eb47b…
|
lmata
|
253 |
maskColor: helper.options.maskColor, |
|
f7eb47b…
|
lmata
|
254 |
omitBackground: helper.options.omitBackground, |
|
f7eb47b…
|
lmata
|
255 |
scale: helper.options.scale ?? "css", |
|
f7eb47b…
|
lmata
|
256 |
style, |
|
f7eb47b…
|
lmata
|
257 |
isNot: !!this.isNot, |
|
f7eb47b…
|
lmata
|
258 |
timeout, |
|
f7eb47b…
|
lmata
|
259 |
comparator: helper.options.comparator, |
|
f7eb47b…
|
lmata
|
260 |
maxDiffPixels: helper.options.maxDiffPixels, |
|
f7eb47b…
|
lmata
|
261 |
maxDiffPixelRatio: helper.options.maxDiffPixelRatio, |
|
f7eb47b…
|
lmata
|
262 |
threshold: helper.options.threshold |
|
f7eb47b…
|
lmata
|
263 |
}; |
|
f7eb47b…
|
lmata
|
264 |
const hasSnapshot = import_fs.default.existsSync(helper.expectedPath); |
|
f7eb47b…
|
lmata
|
265 |
if (this.isNot) { |
|
f7eb47b…
|
lmata
|
266 |
if (!hasSnapshot) |
|
f7eb47b…
|
lmata
|
267 |
return helper.handleMissingNegated(); |
|
f7eb47b…
|
lmata
|
268 |
expectScreenshotOptions.expected = await import_fs.default.promises.readFile(helper.expectedPath); |
|
f7eb47b…
|
lmata
|
269 |
const isDifferent = !(await page._expectScreenshot(expectScreenshotOptions)).errorMessage; |
|
f7eb47b…
|
lmata
|
270 |
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated(); |
|
f7eb47b…
|
lmata
|
271 |
} |
|
f7eb47b…
|
lmata
|
272 |
if (helper.updateSnapshots === "none" && !hasSnapshot) |
|
f7eb47b…
|
lmata
|
273 |
return helper.createMatcherResult(`A snapshot doesn't exist at ${helper.expectedPath}.`, false); |
|
f7eb47b…
|
lmata
|
274 |
if (!hasSnapshot) { |
|
f7eb47b…
|
lmata
|
275 |
const { actual: actual2, previous: previous2, diff: diff2, errorMessage: errorMessage2, log: log2, timedOut: timedOut2 } = await page._expectScreenshot(expectScreenshotOptions); |
|
f7eb47b…
|
lmata
|
276 |
if (errorMessage2) { |
|
f7eb47b…
|
lmata
|
277 |
const header2 = (0, import_utils.formatMatcherMessage)(this.utils, { promise: this.promise, isNot: this.isNot, matcherName: "toHaveScreenshot", locator: locator?.toString(), expectation: "expected", timeout, timedOut: timedOut2 }); |
|
f7eb47b…
|
lmata
|
278 |
return helper.handleDifferent(actual2, void 0, previous2, diff2, header2, errorMessage2, log2, this._stepInfo); |
|
f7eb47b…
|
lmata
|
279 |
} |
|
f7eb47b…
|
lmata
|
280 |
return helper.handleMissing(actual2, this._stepInfo); |
|
f7eb47b…
|
lmata
|
281 |
} |
|
f7eb47b…
|
lmata
|
282 |
const expected = await import_fs.default.promises.readFile(helper.expectedPath); |
|
f7eb47b…
|
lmata
|
283 |
expectScreenshotOptions.expected = helper.updateSnapshots === "all" ? void 0 : expected; |
|
f7eb47b…
|
lmata
|
284 |
const { actual, previous, diff, errorMessage, log, timedOut } = await page._expectScreenshot(expectScreenshotOptions); |
|
f7eb47b…
|
lmata
|
285 |
const writeFiles = (actualBuffer) => { |
|
f7eb47b…
|
lmata
|
286 |
writeFileSync(helper.expectedPath, actualBuffer); |
|
f7eb47b…
|
lmata
|
287 |
writeFileSync(helper.actualPath, actualBuffer); |
|
f7eb47b…
|
lmata
|
288 |
console.log(helper.expectedPath + " is re-generated, writing actual."); |
|
f7eb47b…
|
lmata
|
289 |
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true); |
|
f7eb47b…
|
lmata
|
290 |
}; |
|
f7eb47b…
|
lmata
|
291 |
if (!errorMessage) { |
|
f7eb47b…
|
lmata
|
292 |
if (helper.updateSnapshots === "all" && actual && (0, import_utils.compareBuffersOrStrings)(actual, expected)) { |
|
f7eb47b…
|
lmata
|
293 |
console.log(helper.expectedPath + " is re-generated, writing actual."); |
|
f7eb47b…
|
lmata
|
294 |
return writeFiles(actual); |
|
f7eb47b…
|
lmata
|
295 |
} |
|
f7eb47b…
|
lmata
|
296 |
return helper.handleMatching(); |
|
f7eb47b…
|
lmata
|
297 |
} |
|
f7eb47b…
|
lmata
|
298 |
if (helper.updateSnapshots === "changed" || helper.updateSnapshots === "all") { |
|
f7eb47b…
|
lmata
|
299 |
if (actual) |
|
f7eb47b…
|
lmata
|
300 |
return writeFiles(actual); |
|
f7eb47b…
|
lmata
|
301 |
let header2 = (0, import_utils.formatMatcherMessage)(this.utils, { promise: this.promise, isNot: this.isNot, matcherName: "toHaveScreenshot", locator: locator?.toString(), expectation: "expected", timeout, timedOut }); |
|
f7eb47b…
|
lmata
|
302 |
header2 += " Failed to re-generate expected.\n"; |
|
f7eb47b…
|
lmata
|
303 |
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header2, errorMessage, log, this._stepInfo); |
|
f7eb47b…
|
lmata
|
304 |
} |
|
f7eb47b…
|
lmata
|
305 |
const header = (0, import_utils.formatMatcherMessage)(this.utils, { promise: this.promise, isNot: this.isNot, matcherName: "toHaveScreenshot", locator: locator?.toString(), expectation: "expected", timeout, timedOut }); |
|
f7eb47b…
|
lmata
|
306 |
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo); |
|
f7eb47b…
|
lmata
|
307 |
} |
|
f7eb47b…
|
lmata
|
308 |
function writeFileSync(aPath, content) { |
|
f7eb47b…
|
lmata
|
309 |
import_fs.default.mkdirSync(import_path.default.dirname(aPath), { recursive: true }); |
|
f7eb47b…
|
lmata
|
310 |
import_fs.default.writeFileSync(aPath, content); |
|
f7eb47b…
|
lmata
|
311 |
} |
|
f7eb47b…
|
lmata
|
312 |
function indent(lines, tab) { |
|
f7eb47b…
|
lmata
|
313 |
return lines.replace(/^(?=.+$)/gm, tab); |
|
f7eb47b…
|
lmata
|
314 |
} |
|
f7eb47b…
|
lmata
|
315 |
function determineFileExtension(file) { |
|
f7eb47b…
|
lmata
|
316 |
if (typeof file === "string") |
|
f7eb47b…
|
lmata
|
317 |
return "txt"; |
|
f7eb47b…
|
lmata
|
318 |
if (compareMagicBytes(file, [137, 80, 78, 71, 13, 10, 26, 10])) |
|
f7eb47b…
|
lmata
|
319 |
return "png"; |
|
f7eb47b…
|
lmata
|
320 |
if (compareMagicBytes(file, [255, 216, 255])) |
|
f7eb47b…
|
lmata
|
321 |
return "jpg"; |
|
f7eb47b…
|
lmata
|
322 |
return "dat"; |
|
f7eb47b…
|
lmata
|
323 |
} |
|
f7eb47b…
|
lmata
|
324 |
function compareMagicBytes(file, magicBytes) { |
|
f7eb47b…
|
lmata
|
325 |
return Buffer.compare(Buffer.from(magicBytes), file.slice(0, magicBytes.length)) === 0; |
|
f7eb47b…
|
lmata
|
326 |
} |
|
f7eb47b…
|
lmata
|
327 |
async function loadScreenshotStyles(stylePath) { |
|
f7eb47b…
|
lmata
|
328 |
if (!stylePath) |
|
f7eb47b…
|
lmata
|
329 |
return; |
|
f7eb47b…
|
lmata
|
330 |
const stylePaths = Array.isArray(stylePath) ? stylePath : [stylePath]; |
|
f7eb47b…
|
lmata
|
331 |
const styles = await Promise.all(stylePaths.map(async (stylePath2) => { |
|
f7eb47b…
|
lmata
|
332 |
const text = await import_fs.default.promises.readFile(stylePath2, "utf8"); |
|
f7eb47b…
|
lmata
|
333 |
return text.trim(); |
|
f7eb47b…
|
lmata
|
334 |
})); |
|
f7eb47b…
|
lmata
|
335 |
return styles.join("\n").trim() || void 0; |
|
f7eb47b…
|
lmata
|
336 |
} |
|
f7eb47b…
|
lmata
|
337 |
// Annotate the CommonJS export names for ESM import in node: |
|
f7eb47b…
|
lmata
|
338 |
0 && (module.exports = { |
|
f7eb47b…
|
lmata
|
339 |
toHaveScreenshot, |
|
f7eb47b…
|
lmata
|
340 |
toHaveScreenshotStepTitle, |
|
f7eb47b…
|
lmata
|
341 |
toMatchSnapshot |
|
f7eb47b…
|
lmata
|
342 |
}); |