|
1
|
"use strict"; |
|
2
|
var __create = Object.create; |
|
3
|
var __defProp = Object.defineProperty; |
|
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; |
|
5
|
var __getOwnPropNames = Object.getOwnPropertyNames; |
|
6
|
var __getProtoOf = Object.getPrototypeOf; |
|
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty; |
|
8
|
var __export = (target, all) => { |
|
9
|
for (var name in all) |
|
10
|
__defProp(target, name, { get: all[name], enumerable: true }); |
|
11
|
}; |
|
12
|
var __copyProps = (to, from, except, desc) => { |
|
13
|
if (from && typeof from === "object" || typeof from === "function") { |
|
14
|
for (let key of __getOwnPropNames(from)) |
|
15
|
if (!__hasOwnProp.call(to, key) && key !== except) |
|
16
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); |
|
17
|
} |
|
18
|
return to; |
|
19
|
}; |
|
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( |
|
21
|
// If the importer is in node compatibility mode or this is not an ESM |
|
22
|
// file that has been converted to a CommonJS file using a Babel- |
|
23
|
// compatible transform (i.e. "__esModule" has not been set), then set |
|
24
|
// "default" to the CommonJS "module.exports" for node compatibility. |
|
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, |
|
26
|
mod |
|
27
|
)); |
|
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); |
|
29
|
var util_exports = {}; |
|
30
|
__export(util_exports, { |
|
31
|
addSuffixToFilePath: () => addSuffixToFilePath, |
|
32
|
ansiRegex: () => import_utils2.ansiRegex, |
|
33
|
createFileFiltersFromArguments: () => createFileFiltersFromArguments, |
|
34
|
createFileMatcher: () => createFileMatcher, |
|
35
|
createFileMatcherFromArguments: () => createFileMatcherFromArguments, |
|
36
|
createTitleMatcher: () => createTitleMatcher, |
|
37
|
debugTest: () => debugTest, |
|
38
|
errorWithFile: () => errorWithFile, |
|
39
|
expectTypes: () => expectTypes, |
|
40
|
fileExistsAsync: () => fileExistsAsync, |
|
41
|
fileIsModule: () => fileIsModule, |
|
42
|
filterStackFile: () => filterStackFile, |
|
43
|
filterStackTrace: () => filterStackTrace, |
|
44
|
filteredStackTrace: () => filteredStackTrace, |
|
45
|
forceRegExp: () => forceRegExp, |
|
46
|
formatLocation: () => formatLocation, |
|
47
|
getContainedPath: () => getContainedPath, |
|
48
|
getPackageJsonPath: () => getPackageJsonPath, |
|
49
|
mergeObjects: () => mergeObjects, |
|
50
|
normalizeAndSaveAttachment: () => normalizeAndSaveAttachment, |
|
51
|
parseLocationArg: () => parseLocationArg, |
|
52
|
relativeFilePath: () => relativeFilePath, |
|
53
|
removeDirAndLogToConsole: () => removeDirAndLogToConsole, |
|
54
|
resolveImportSpecifierAfterMapping: () => resolveImportSpecifierAfterMapping, |
|
55
|
resolveReporterOutputPath: () => resolveReporterOutputPath, |
|
56
|
sanitizeFilePathBeforeExtension: () => sanitizeFilePathBeforeExtension, |
|
57
|
serializeError: () => serializeError, |
|
58
|
stripAnsiEscapes: () => import_utils2.stripAnsiEscapes, |
|
59
|
trimLongString: () => trimLongString, |
|
60
|
windowsFilesystemFriendlyLength: () => windowsFilesystemFriendlyLength |
|
61
|
}); |
|
62
|
module.exports = __toCommonJS(util_exports); |
|
63
|
var import_fs = __toESM(require("fs")); |
|
64
|
var import_path = __toESM(require("path")); |
|
65
|
var import_url = __toESM(require("url")); |
|
66
|
var import_util = __toESM(require("util")); |
|
67
|
var import_utils = require("playwright-core/lib/utils"); |
|
68
|
var import_utilsBundle = require("playwright-core/lib/utilsBundle"); |
|
69
|
var import_utils2 = require("playwright-core/lib/utils"); |
|
70
|
const PLAYWRIGHT_TEST_PATH = import_path.default.join(__dirname, ".."); |
|
71
|
const PLAYWRIGHT_CORE_PATH = import_path.default.dirname(require.resolve("playwright-core/package.json")); |
|
72
|
function filterStackTrace(e) { |
|
73
|
const name = e.name ? e.name + ": " : ""; |
|
74
|
const cause = e.cause instanceof Error ? filterStackTrace(e.cause) : void 0; |
|
75
|
if (process.env.PWDEBUGIMPL) |
|
76
|
return { message: name + e.message, stack: e.stack || "", cause }; |
|
77
|
const stackLines = (0, import_utils.stringifyStackFrames)(filteredStackTrace(e.stack?.split("\n") || [])); |
|
78
|
return { |
|
79
|
message: name + e.message, |
|
80
|
stack: `${name}${e.message}${stackLines.map((line) => "\n" + line).join("")}`, |
|
81
|
cause |
|
82
|
}; |
|
83
|
} |
|
84
|
function filterStackFile(file) { |
|
85
|
if (!process.env.PWDEBUGIMPL && file.startsWith(PLAYWRIGHT_TEST_PATH)) |
|
86
|
return false; |
|
87
|
if (!process.env.PWDEBUGIMPL && file.startsWith(PLAYWRIGHT_CORE_PATH)) |
|
88
|
return false; |
|
89
|
return true; |
|
90
|
} |
|
91
|
function filteredStackTrace(rawStack) { |
|
92
|
const frames = []; |
|
93
|
for (const line of rawStack) { |
|
94
|
const frame = (0, import_utils.parseStackFrame)(line, import_path.default.sep, !!process.env.PWDEBUGIMPL); |
|
95
|
if (!frame || !frame.file) |
|
96
|
continue; |
|
97
|
if (!filterStackFile(frame.file)) |
|
98
|
continue; |
|
99
|
frames.push(frame); |
|
100
|
} |
|
101
|
return frames; |
|
102
|
} |
|
103
|
function serializeError(error) { |
|
104
|
if (error instanceof Error) |
|
105
|
return filterStackTrace(error); |
|
106
|
return { |
|
107
|
value: import_util.default.inspect(error) |
|
108
|
}; |
|
109
|
} |
|
110
|
function parseLocationArg(arg) { |
|
111
|
const match = /^(.*?):(\d+):?(\d+)?$/.exec(arg); |
|
112
|
return { |
|
113
|
file: match ? match[1] : arg, |
|
114
|
line: match ? parseInt(match[2], 10) : null, |
|
115
|
column: match?.[3] ? parseInt(match[3], 10) : null |
|
116
|
}; |
|
117
|
} |
|
118
|
function createFileFiltersFromArguments(args) { |
|
119
|
return args.map((arg) => { |
|
120
|
const parsed = parseLocationArg(arg); |
|
121
|
return { re: forceRegExp(parsed.file), line: parsed.line, column: parsed.column }; |
|
122
|
}); |
|
123
|
} |
|
124
|
function createFileMatcherFromArguments(args) { |
|
125
|
const filters = createFileFiltersFromArguments(args); |
|
126
|
return createFileMatcher(filters.map((filter) => filter.re || filter.exact || "")); |
|
127
|
} |
|
128
|
function createFileMatcher(patterns) { |
|
129
|
const reList = []; |
|
130
|
const filePatterns = []; |
|
131
|
for (const pattern of Array.isArray(patterns) ? patterns : [patterns]) { |
|
132
|
if ((0, import_utils.isRegExp)(pattern)) { |
|
133
|
reList.push(pattern); |
|
134
|
} else { |
|
135
|
if (!pattern.startsWith("**/")) |
|
136
|
filePatterns.push("**/" + pattern); |
|
137
|
else |
|
138
|
filePatterns.push(pattern); |
|
139
|
} |
|
140
|
} |
|
141
|
return (filePath) => { |
|
142
|
for (const re of reList) { |
|
143
|
re.lastIndex = 0; |
|
144
|
if (re.test(filePath)) |
|
145
|
return true; |
|
146
|
} |
|
147
|
if (import_path.default.sep === "\\") { |
|
148
|
const fileURL = import_url.default.pathToFileURL(filePath).href; |
|
149
|
for (const re of reList) { |
|
150
|
re.lastIndex = 0; |
|
151
|
if (re.test(fileURL)) |
|
152
|
return true; |
|
153
|
} |
|
154
|
} |
|
155
|
for (const pattern of filePatterns) { |
|
156
|
if ((0, import_utilsBundle.minimatch)(filePath, pattern, { nocase: true, dot: true })) |
|
157
|
return true; |
|
158
|
} |
|
159
|
return false; |
|
160
|
}; |
|
161
|
} |
|
162
|
function createTitleMatcher(patterns) { |
|
163
|
const reList = Array.isArray(patterns) ? patterns : [patterns]; |
|
164
|
return (value) => { |
|
165
|
for (const re of reList) { |
|
166
|
re.lastIndex = 0; |
|
167
|
if (re.test(value)) |
|
168
|
return true; |
|
169
|
} |
|
170
|
return false; |
|
171
|
}; |
|
172
|
} |
|
173
|
function mergeObjects(a, b, c) { |
|
174
|
const result = { ...a }; |
|
175
|
for (const x of [b, c].filter(Boolean)) { |
|
176
|
for (const [name, value] of Object.entries(x)) { |
|
177
|
if (!Object.is(value, void 0)) |
|
178
|
result[name] = value; |
|
179
|
} |
|
180
|
} |
|
181
|
return result; |
|
182
|
} |
|
183
|
function forceRegExp(pattern) { |
|
184
|
const match = pattern.match(/^\/(.*)\/([gi]*)$/); |
|
185
|
if (match) |
|
186
|
return new RegExp(match[1], match[2]); |
|
187
|
return new RegExp(pattern, "gi"); |
|
188
|
} |
|
189
|
function relativeFilePath(file) { |
|
190
|
if (!import_path.default.isAbsolute(file)) |
|
191
|
return file; |
|
192
|
return import_path.default.relative(process.cwd(), file); |
|
193
|
} |
|
194
|
function formatLocation(location) { |
|
195
|
return relativeFilePath(location.file) + ":" + location.line + ":" + location.column; |
|
196
|
} |
|
197
|
function errorWithFile(file, message) { |
|
198
|
return new Error(`${relativeFilePath(file)}: ${message}`); |
|
199
|
} |
|
200
|
function expectTypes(receiver, types, matcherName) { |
|
201
|
if (typeof receiver !== "object" || !types.includes(receiver.constructor.name)) { |
|
202
|
const commaSeparated = types.slice(); |
|
203
|
const lastType = commaSeparated.pop(); |
|
204
|
const typesString = commaSeparated.length ? commaSeparated.join(", ") + " or " + lastType : lastType; |
|
205
|
throw new Error(`${matcherName} can be only used with ${typesString} object${types.length > 1 ? "s" : ""}`); |
|
206
|
} |
|
207
|
} |
|
208
|
const windowsFilesystemFriendlyLength = 60; |
|
209
|
function trimLongString(s, length = 100) { |
|
210
|
if (s.length <= length) |
|
211
|
return s; |
|
212
|
const hash = (0, import_utils.calculateSha1)(s); |
|
213
|
const middle = `-${hash.substring(0, 5)}-`; |
|
214
|
const start = Math.floor((length - middle.length) / 2); |
|
215
|
const end = length - middle.length - start; |
|
216
|
return s.substring(0, start) + middle + s.slice(-end); |
|
217
|
} |
|
218
|
function addSuffixToFilePath(filePath, suffix) { |
|
219
|
const ext = import_path.default.extname(filePath); |
|
220
|
const base = filePath.substring(0, filePath.length - ext.length); |
|
221
|
return base + suffix + ext; |
|
222
|
} |
|
223
|
function sanitizeFilePathBeforeExtension(filePath, ext) { |
|
224
|
ext ??= import_path.default.extname(filePath); |
|
225
|
const base = filePath.substring(0, filePath.length - ext.length); |
|
226
|
return (0, import_utils.sanitizeForFilePath)(base) + ext; |
|
227
|
} |
|
228
|
function getContainedPath(parentPath, subPath = "") { |
|
229
|
const resolvedPath = import_path.default.resolve(parentPath, subPath); |
|
230
|
if (resolvedPath === parentPath || resolvedPath.startsWith(parentPath + import_path.default.sep)) |
|
231
|
return resolvedPath; |
|
232
|
return null; |
|
233
|
} |
|
234
|
const debugTest = (0, import_utilsBundle.debug)("pw:test"); |
|
235
|
const folderToPackageJsonPath = /* @__PURE__ */ new Map(); |
|
236
|
function getPackageJsonPath(folderPath) { |
|
237
|
const cached = folderToPackageJsonPath.get(folderPath); |
|
238
|
if (cached !== void 0) |
|
239
|
return cached; |
|
240
|
const packageJsonPath = import_path.default.join(folderPath, "package.json"); |
|
241
|
if (import_fs.default.existsSync(packageJsonPath)) { |
|
242
|
folderToPackageJsonPath.set(folderPath, packageJsonPath); |
|
243
|
return packageJsonPath; |
|
244
|
} |
|
245
|
const parentFolder = import_path.default.dirname(folderPath); |
|
246
|
if (folderPath === parentFolder) { |
|
247
|
folderToPackageJsonPath.set(folderPath, ""); |
|
248
|
return ""; |
|
249
|
} |
|
250
|
const result = getPackageJsonPath(parentFolder); |
|
251
|
folderToPackageJsonPath.set(folderPath, result); |
|
252
|
return result; |
|
253
|
} |
|
254
|
function resolveReporterOutputPath(defaultValue, configDir, configValue) { |
|
255
|
if (configValue) |
|
256
|
return import_path.default.resolve(configDir, configValue); |
|
257
|
let basePath = getPackageJsonPath(configDir); |
|
258
|
basePath = basePath ? import_path.default.dirname(basePath) : process.cwd(); |
|
259
|
return import_path.default.resolve(basePath, defaultValue); |
|
260
|
} |
|
261
|
async function normalizeAndSaveAttachment(outputPath, name, options = {}) { |
|
262
|
if (options.path === void 0 && options.body === void 0) |
|
263
|
return { name, contentType: "text/plain" }; |
|
264
|
if ((options.path !== void 0 ? 1 : 0) + (options.body !== void 0 ? 1 : 0) !== 1) |
|
265
|
throw new Error(`Exactly one of "path" and "body" must be specified`); |
|
266
|
if (options.path !== void 0) { |
|
267
|
const hash = (0, import_utils.calculateSha1)(options.path); |
|
268
|
if (!(0, import_utils.isString)(name)) |
|
269
|
throw new Error('"name" should be string.'); |
|
270
|
const sanitizedNamePrefix = (0, import_utils.sanitizeForFilePath)(name) + "-"; |
|
271
|
const dest = import_path.default.join(outputPath, "attachments", sanitizedNamePrefix + hash + import_path.default.extname(options.path)); |
|
272
|
await import_fs.default.promises.mkdir(import_path.default.dirname(dest), { recursive: true }); |
|
273
|
await import_fs.default.promises.copyFile(options.path, dest); |
|
274
|
const contentType = options.contentType ?? (import_utilsBundle.mime.getType(import_path.default.basename(options.path)) || "application/octet-stream"); |
|
275
|
return { name, contentType, path: dest }; |
|
276
|
} else { |
|
277
|
const contentType = options.contentType ?? (typeof options.body === "string" ? "text/plain" : "application/octet-stream"); |
|
278
|
return { name, contentType, body: typeof options.body === "string" ? Buffer.from(options.body) : options.body }; |
|
279
|
} |
|
280
|
} |
|
281
|
function fileIsModule(file) { |
|
282
|
if (file.endsWith(".mjs") || file.endsWith(".mts")) |
|
283
|
return true; |
|
284
|
if (file.endsWith(".cjs") || file.endsWith(".cts")) |
|
285
|
return false; |
|
286
|
const folder = import_path.default.dirname(file); |
|
287
|
return folderIsModule(folder); |
|
288
|
} |
|
289
|
function folderIsModule(folder) { |
|
290
|
const packageJsonPath = getPackageJsonPath(folder); |
|
291
|
if (!packageJsonPath) |
|
292
|
return false; |
|
293
|
return require(packageJsonPath).type === "module"; |
|
294
|
} |
|
295
|
const packageJsonMainFieldCache = /* @__PURE__ */ new Map(); |
|
296
|
function getMainFieldFromPackageJson(packageJsonPath) { |
|
297
|
if (!packageJsonMainFieldCache.has(packageJsonPath)) { |
|
298
|
let mainField; |
|
299
|
try { |
|
300
|
mainField = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf8")).main; |
|
301
|
} catch { |
|
302
|
} |
|
303
|
packageJsonMainFieldCache.set(packageJsonPath, mainField); |
|
304
|
} |
|
305
|
return packageJsonMainFieldCache.get(packageJsonPath); |
|
306
|
} |
|
307
|
const kExtLookups = /* @__PURE__ */ new Map([ |
|
308
|
[".js", [".jsx", ".ts", ".tsx"]], |
|
309
|
[".jsx", [".tsx"]], |
|
310
|
[".cjs", [".cts"]], |
|
311
|
[".mjs", [".mts"]], |
|
312
|
["", [".js", ".ts", ".jsx", ".tsx", ".cjs", ".mjs", ".cts", ".mts"]] |
|
313
|
]); |
|
314
|
function resolveImportSpecifierExtension(resolved) { |
|
315
|
if (fileExists(resolved)) |
|
316
|
return resolved; |
|
317
|
for (const [ext, others] of kExtLookups) { |
|
318
|
if (!resolved.endsWith(ext)) |
|
319
|
continue; |
|
320
|
for (const other of others) { |
|
321
|
const modified = resolved.substring(0, resolved.length - ext.length) + other; |
|
322
|
if (fileExists(modified)) |
|
323
|
return modified; |
|
324
|
} |
|
325
|
break; |
|
326
|
} |
|
327
|
} |
|
328
|
function resolveImportSpecifierAfterMapping(resolved, afterPathMapping) { |
|
329
|
const resolvedFile = resolveImportSpecifierExtension(resolved); |
|
330
|
if (resolvedFile) |
|
331
|
return resolvedFile; |
|
332
|
if (dirExists(resolved)) { |
|
333
|
const packageJsonPath = import_path.default.join(resolved, "package.json"); |
|
334
|
if (afterPathMapping) { |
|
335
|
const mainField = getMainFieldFromPackageJson(packageJsonPath); |
|
336
|
const mainFieldResolved = mainField ? resolveImportSpecifierExtension(import_path.default.resolve(resolved, mainField)) : void 0; |
|
337
|
return mainFieldResolved || resolveImportSpecifierExtension(import_path.default.join(resolved, "index")); |
|
338
|
} |
|
339
|
if (fileExists(packageJsonPath)) |
|
340
|
return resolved; |
|
341
|
const dirImport = import_path.default.join(resolved, "index"); |
|
342
|
return resolveImportSpecifierExtension(dirImport); |
|
343
|
} |
|
344
|
} |
|
345
|
function fileExists(resolved) { |
|
346
|
return import_fs.default.statSync(resolved, { throwIfNoEntry: false })?.isFile(); |
|
347
|
} |
|
348
|
async function fileExistsAsync(resolved) { |
|
349
|
try { |
|
350
|
const stat = await import_fs.default.promises.stat(resolved); |
|
351
|
return stat.isFile(); |
|
352
|
} catch { |
|
353
|
return false; |
|
354
|
} |
|
355
|
} |
|
356
|
function dirExists(resolved) { |
|
357
|
return import_fs.default.statSync(resolved, { throwIfNoEntry: false })?.isDirectory(); |
|
358
|
} |
|
359
|
async function removeDirAndLogToConsole(dir) { |
|
360
|
try { |
|
361
|
if (!import_fs.default.existsSync(dir)) |
|
362
|
return; |
|
363
|
console.log(`Removing ${await import_fs.default.promises.realpath(dir)}`); |
|
364
|
await import_fs.default.promises.rm(dir, { recursive: true, force: true }); |
|
365
|
} catch { |
|
366
|
} |
|
367
|
} |
|
368
|
// Annotate the CommonJS export names for ESM import in node: |
|
369
|
0 && (module.exports = { |
|
370
|
addSuffixToFilePath, |
|
371
|
ansiRegex, |
|
372
|
createFileFiltersFromArguments, |
|
373
|
createFileMatcher, |
|
374
|
createFileMatcherFromArguments, |
|
375
|
createTitleMatcher, |
|
376
|
debugTest, |
|
377
|
errorWithFile, |
|
378
|
expectTypes, |
|
379
|
fileExistsAsync, |
|
380
|
fileIsModule, |
|
381
|
filterStackFile, |
|
382
|
filterStackTrace, |
|
383
|
filteredStackTrace, |
|
384
|
forceRegExp, |
|
385
|
formatLocation, |
|
386
|
getContainedPath, |
|
387
|
getPackageJsonPath, |
|
388
|
mergeObjects, |
|
389
|
normalizeAndSaveAttachment, |
|
390
|
parseLocationArg, |
|
391
|
relativeFilePath, |
|
392
|
removeDirAndLogToConsole, |
|
393
|
resolveImportSpecifierAfterMapping, |
|
394
|
resolveReporterOutputPath, |
|
395
|
sanitizeFilePathBeforeExtension, |
|
396
|
serializeError, |
|
397
|
stripAnsiEscapes, |
|
398
|
trimLongString, |
|
399
|
windowsFilesystemFriendlyLength |
|
400
|
}); |
|
401
|
|