Implement comprehensive frontend integration testing with Playwright
- Add Playwright E2E testing framework with cross-browser support (Chrome, Firefox) - Create authentication helpers for CalDAV server integration - Implement calendar interaction helpers with event creation, drag-and-drop, and view switching - Add comprehensive drag-and-drop test suite with event cleanup - Configure CI/CD integration with Gitea Actions for headless testing - Support both local development and CI environments with proper dependency management - Include video recording, screenshots, and HTML reporting for test debugging - Handle Firefox-specific timing and interaction challenges with force clicks and timeouts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										611
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/base.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										611
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/base.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,611 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var base_exports = {}; | ||||
| __export(base_exports, { | ||||
|   TerminalReporter: () => TerminalReporter, | ||||
|   fitToWidth: () => fitToWidth, | ||||
|   formatError: () => formatError, | ||||
|   formatFailure: () => formatFailure, | ||||
|   formatResultFailure: () => formatResultFailure, | ||||
|   formatRetry: () => formatRetry, | ||||
|   internalScreen: () => internalScreen, | ||||
|   kOutputSymbol: () => kOutputSymbol, | ||||
|   nonTerminalScreen: () => nonTerminalScreen, | ||||
|   prepareErrorStack: () => prepareErrorStack, | ||||
|   relativeFilePath: () => relativeFilePath, | ||||
|   resolveOutputFile: () => resolveOutputFile, | ||||
|   separator: () => separator, | ||||
|   stepSuffix: () => stepSuffix, | ||||
|   terminalScreen: () => terminalScreen | ||||
| }); | ||||
| module.exports = __toCommonJS(base_exports); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_utilsBundle = require("playwright-core/lib/utilsBundle"); | ||||
| var import_utils2 = require("playwright-core/lib/utils"); | ||||
| var import_util = require("../util"); | ||||
| var import_utilsBundle2 = require("../utilsBundle"); | ||||
| const kOutputSymbol = Symbol("output"); | ||||
| const DEFAULT_TTY_WIDTH = 100; | ||||
| const DEFAULT_TTY_HEIGHT = 40; | ||||
| const originalProcessStdout = process.stdout; | ||||
| const originalProcessStderr = process.stderr; | ||||
| const terminalScreen = (() => { | ||||
|   let isTTY = !!originalProcessStdout.isTTY; | ||||
|   let ttyWidth = originalProcessStdout.columns || 0; | ||||
|   let ttyHeight = originalProcessStdout.rows || 0; | ||||
|   if (process.env.PLAYWRIGHT_FORCE_TTY === "false" || process.env.PLAYWRIGHT_FORCE_TTY === "0") { | ||||
|     isTTY = false; | ||||
|     ttyWidth = 0; | ||||
|     ttyHeight = 0; | ||||
|   } else if (process.env.PLAYWRIGHT_FORCE_TTY === "true" || process.env.PLAYWRIGHT_FORCE_TTY === "1") { | ||||
|     isTTY = true; | ||||
|     ttyWidth = originalProcessStdout.columns || DEFAULT_TTY_WIDTH; | ||||
|     ttyHeight = originalProcessStdout.rows || DEFAULT_TTY_HEIGHT; | ||||
|   } else if (process.env.PLAYWRIGHT_FORCE_TTY) { | ||||
|     isTTY = true; | ||||
|     const sizeMatch = process.env.PLAYWRIGHT_FORCE_TTY.match(/^(\d+)x(\d+)$/); | ||||
|     if (sizeMatch) { | ||||
|       ttyWidth = +sizeMatch[1]; | ||||
|       ttyHeight = +sizeMatch[2]; | ||||
|     } else { | ||||
|       ttyWidth = +process.env.PLAYWRIGHT_FORCE_TTY; | ||||
|       ttyHeight = DEFAULT_TTY_HEIGHT; | ||||
|     } | ||||
|     if (isNaN(ttyWidth)) | ||||
|       ttyWidth = DEFAULT_TTY_WIDTH; | ||||
|     if (isNaN(ttyHeight)) | ||||
|       ttyHeight = DEFAULT_TTY_HEIGHT; | ||||
|   } | ||||
|   let useColors = isTTY; | ||||
|   if (process.env.DEBUG_COLORS === "0" || process.env.DEBUG_COLORS === "false" || process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false") | ||||
|     useColors = false; | ||||
|   else if (process.env.DEBUG_COLORS || process.env.FORCE_COLOR) | ||||
|     useColors = true; | ||||
|   const colors = useColors ? import_utils2.colors : import_utils2.noColors; | ||||
|   return { | ||||
|     resolveFiles: "cwd", | ||||
|     isTTY, | ||||
|     ttyWidth, | ||||
|     ttyHeight, | ||||
|     colors, | ||||
|     stdout: originalProcessStdout, | ||||
|     stderr: originalProcessStderr | ||||
|   }; | ||||
| })(); | ||||
| const nonTerminalScreen = { | ||||
|   colors: terminalScreen.colors, | ||||
|   isTTY: false, | ||||
|   ttyWidth: 0, | ||||
|   ttyHeight: 0, | ||||
|   resolveFiles: "rootDir" | ||||
| }; | ||||
| const internalScreen = { | ||||
|   colors: import_utils2.colors, | ||||
|   isTTY: false, | ||||
|   ttyWidth: 0, | ||||
|   ttyHeight: 0, | ||||
|   resolveFiles: "rootDir" | ||||
| }; | ||||
| class TerminalReporter { | ||||
|   constructor(options = {}) { | ||||
|     this.totalTestCount = 0; | ||||
|     this.fileDurations = /* @__PURE__ */ new Map(); | ||||
|     this._fatalErrors = []; | ||||
|     this._failureCount = 0; | ||||
|     this.screen = options.screen ?? terminalScreen; | ||||
|     this._omitFailures = options.omitFailures || false; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this.config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this.suite = suite; | ||||
|     this.totalTestCount = suite.allTests().length; | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     this._appendOutput({ chunk, type: "stdout" }, result); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     this._appendOutput({ chunk, type: "stderr" }, result); | ||||
|   } | ||||
|   _appendOutput(output, result) { | ||||
|     if (!result) | ||||
|       return; | ||||
|     result[kOutputSymbol] = result[kOutputSymbol] || []; | ||||
|     result[kOutputSymbol].push(output); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     if (result.status !== "skipped" && result.status !== test.expectedStatus) | ||||
|       ++this._failureCount; | ||||
|     const projectName = test.titlePath()[1]; | ||||
|     const relativePath = relativeTestPath(this.screen, this.config, test); | ||||
|     const fileAndProject = (projectName ? `[${projectName}] \u203A ` : "") + relativePath; | ||||
|     const entry = this.fileDurations.get(fileAndProject) || { duration: 0, workers: /* @__PURE__ */ new Set() }; | ||||
|     entry.duration += result.duration; | ||||
|     entry.workers.add(result.workerIndex); | ||||
|     this.fileDurations.set(fileAndProject, entry); | ||||
|   } | ||||
|   onError(error) { | ||||
|     this._fatalErrors.push(error); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     this.result = result; | ||||
|   } | ||||
|   fitToScreen(line, prefix) { | ||||
|     if (!this.screen.ttyWidth) { | ||||
|       return line; | ||||
|     } | ||||
|     return fitToWidth(line, this.screen.ttyWidth, prefix); | ||||
|   } | ||||
|   generateStartingMessage() { | ||||
|     const jobs = this.config.metadata.actualWorkers ?? this.config.workers; | ||||
|     const shardDetails = this.config.shard ? `, shard ${this.config.shard.current} of ${this.config.shard.total}` : ""; | ||||
|     if (!this.totalTestCount) | ||||
|       return ""; | ||||
|     return "\n" + this.screen.colors.dim("Running ") + this.totalTestCount + this.screen.colors.dim(` test${this.totalTestCount !== 1 ? "s" : ""} using `) + jobs + this.screen.colors.dim(` worker${jobs !== 1 ? "s" : ""}${shardDetails}`); | ||||
|   } | ||||
|   getSlowTests() { | ||||
|     if (!this.config.reportSlowTests) | ||||
|       return []; | ||||
|     const fileDurations = [...this.fileDurations.entries()].filter(([key, value]) => value.workers.size === 1).map(([key, value]) => [key, value.duration]); | ||||
|     fileDurations.sort((a, b) => b[1] - a[1]); | ||||
|     const count = Math.min(fileDurations.length, this.config.reportSlowTests.max || Number.POSITIVE_INFINITY); | ||||
|     const threshold = this.config.reportSlowTests.threshold; | ||||
|     return fileDurations.filter(([, duration]) => duration > threshold).slice(0, count); | ||||
|   } | ||||
|   generateSummaryMessage({ didNotRun, skipped, expected, interrupted, unexpected, flaky, fatalErrors }) { | ||||
|     const tokens = []; | ||||
|     if (unexpected.length) { | ||||
|       tokens.push(this.screen.colors.red(`  ${unexpected.length} failed`)); | ||||
|       for (const test of unexpected) | ||||
|         tokens.push(this.screen.colors.red(this.formatTestHeader(test, { indent: "    " }))); | ||||
|     } | ||||
|     if (interrupted.length) { | ||||
|       tokens.push(this.screen.colors.yellow(`  ${interrupted.length} interrupted`)); | ||||
|       for (const test of interrupted) | ||||
|         tokens.push(this.screen.colors.yellow(this.formatTestHeader(test, { indent: "    " }))); | ||||
|     } | ||||
|     if (flaky.length) { | ||||
|       tokens.push(this.screen.colors.yellow(`  ${flaky.length} flaky`)); | ||||
|       for (const test of flaky) | ||||
|         tokens.push(this.screen.colors.yellow(this.formatTestHeader(test, { indent: "    " }))); | ||||
|     } | ||||
|     if (skipped) | ||||
|       tokens.push(this.screen.colors.yellow(`  ${skipped} skipped`)); | ||||
|     if (didNotRun) | ||||
|       tokens.push(this.screen.colors.yellow(`  ${didNotRun} did not run`)); | ||||
|     if (expected) | ||||
|       tokens.push(this.screen.colors.green(`  ${expected} passed`) + this.screen.colors.dim(` (${(0, import_utilsBundle.ms)(this.result.duration)})`)); | ||||
|     if (fatalErrors.length && expected + unexpected.length + interrupted.length + flaky.length > 0) | ||||
|       tokens.push(this.screen.colors.red(`  ${fatalErrors.length === 1 ? "1 error was not a part of any test" : fatalErrors.length + " errors were not a part of any test"}, see above for details`)); | ||||
|     return tokens.join("\n"); | ||||
|   } | ||||
|   generateSummary() { | ||||
|     let didNotRun = 0; | ||||
|     let skipped = 0; | ||||
|     let expected = 0; | ||||
|     const interrupted = []; | ||||
|     const interruptedToPrint = []; | ||||
|     const unexpected = []; | ||||
|     const flaky = []; | ||||
|     this.suite.allTests().forEach((test) => { | ||||
|       switch (test.outcome()) { | ||||
|         case "skipped": { | ||||
|           if (test.results.some((result) => result.status === "interrupted")) { | ||||
|             if (test.results.some((result) => !!result.error)) | ||||
|               interruptedToPrint.push(test); | ||||
|             interrupted.push(test); | ||||
|           } else if (!test.results.length || test.expectedStatus !== "skipped") { | ||||
|             ++didNotRun; | ||||
|           } else { | ||||
|             ++skipped; | ||||
|           } | ||||
|           break; | ||||
|         } | ||||
|         case "expected": | ||||
|           ++expected; | ||||
|           break; | ||||
|         case "unexpected": | ||||
|           unexpected.push(test); | ||||
|           break; | ||||
|         case "flaky": | ||||
|           flaky.push(test); | ||||
|           break; | ||||
|       } | ||||
|     }); | ||||
|     const failuresToPrint = [...unexpected, ...flaky, ...interruptedToPrint]; | ||||
|     return { | ||||
|       didNotRun, | ||||
|       skipped, | ||||
|       expected, | ||||
|       interrupted, | ||||
|       unexpected, | ||||
|       flaky, | ||||
|       failuresToPrint, | ||||
|       fatalErrors: this._fatalErrors | ||||
|     }; | ||||
|   } | ||||
|   epilogue(full) { | ||||
|     const summary = this.generateSummary(); | ||||
|     const summaryMessage = this.generateSummaryMessage(summary); | ||||
|     if (full && summary.failuresToPrint.length && !this._omitFailures) | ||||
|       this._printFailures(summary.failuresToPrint); | ||||
|     this._printSlowTests(); | ||||
|     this._printSummary(summaryMessage); | ||||
|   } | ||||
|   _printFailures(failures) { | ||||
|     this.writeLine(""); | ||||
|     failures.forEach((test, index) => { | ||||
|       this.writeLine(this.formatFailure(test, index + 1)); | ||||
|     }); | ||||
|   } | ||||
|   _printSlowTests() { | ||||
|     const slowTests = this.getSlowTests(); | ||||
|     slowTests.forEach(([file, duration]) => { | ||||
|       this.writeLine(this.screen.colors.yellow("  Slow test file: ") + file + this.screen.colors.yellow(` (${(0, import_utilsBundle.ms)(duration)})`)); | ||||
|     }); | ||||
|     if (slowTests.length) | ||||
|       this.writeLine(this.screen.colors.yellow("  Consider running tests from slow files in parallel. See: https://playwright.dev/docs/test-parallel")); | ||||
|   } | ||||
|   _printSummary(summary) { | ||||
|     if (summary.trim()) | ||||
|       this.writeLine(summary); | ||||
|   } | ||||
|   willRetry(test) { | ||||
|     return test.outcome() === "unexpected" && test.results.length <= test.retries; | ||||
|   } | ||||
|   formatTestTitle(test, step, omitLocation = false) { | ||||
|     return formatTestTitle(this.screen, this.config, test, step, omitLocation); | ||||
|   } | ||||
|   formatTestHeader(test, options = {}) { | ||||
|     return formatTestHeader(this.screen, this.config, test, options); | ||||
|   } | ||||
|   formatFailure(test, index) { | ||||
|     return formatFailure(this.screen, this.config, test, index); | ||||
|   } | ||||
|   formatError(error) { | ||||
|     return formatError(this.screen, error); | ||||
|   } | ||||
|   writeLine(line) { | ||||
|     this.screen.stdout?.write(line ? line + "\n" : "\n"); | ||||
|   } | ||||
| } | ||||
| function formatFailure(screen, config, test, index) { | ||||
|   const lines = []; | ||||
|   const header = formatTestHeader(screen, config, test, { indent: "  ", index, mode: "error" }); | ||||
|   lines.push(screen.colors.red(header)); | ||||
|   for (const result of test.results) { | ||||
|     const resultLines = []; | ||||
|     const errors = formatResultFailure(screen, test, result, "    "); | ||||
|     if (!errors.length) | ||||
|       continue; | ||||
|     if (result.retry) { | ||||
|       resultLines.push(""); | ||||
|       resultLines.push(screen.colors.gray(separator(screen, `    Retry #${result.retry}`))); | ||||
|     } | ||||
|     resultLines.push(...errors.map((error) => "\n" + error.message)); | ||||
|     const attachmentGroups = groupAttachments(result.attachments); | ||||
|     for (let i = 0; i < attachmentGroups.length; ++i) { | ||||
|       const attachment = attachmentGroups[i]; | ||||
|       if (attachment.name === "error-context" && attachment.path) { | ||||
|         resultLines.push(""); | ||||
|         resultLines.push(screen.colors.dim(`    Error Context: ${relativeFilePath(screen, config, attachment.path)}`)); | ||||
|         continue; | ||||
|       } | ||||
|       if (attachment.name.startsWith("_")) | ||||
|         continue; | ||||
|       const hasPrintableContent = attachment.contentType.startsWith("text/"); | ||||
|       if (!attachment.path && !hasPrintableContent) | ||||
|         continue; | ||||
|       resultLines.push(""); | ||||
|       resultLines.push(screen.colors.dim(separator(screen, `    attachment #${i + 1}: ${screen.colors.bold(attachment.name)} (${attachment.contentType})`))); | ||||
|       if (attachment.actual?.path) { | ||||
|         if (attachment.expected?.path) { | ||||
|           const expectedPath = relativeFilePath(screen, config, attachment.expected.path); | ||||
|           resultLines.push(screen.colors.dim(`    Expected: ${expectedPath}`)); | ||||
|         } | ||||
|         const actualPath = relativeFilePath(screen, config, attachment.actual.path); | ||||
|         resultLines.push(screen.colors.dim(`    Received: ${actualPath}`)); | ||||
|         if (attachment.previous?.path) { | ||||
|           const previousPath = relativeFilePath(screen, config, attachment.previous.path); | ||||
|           resultLines.push(screen.colors.dim(`    Previous: ${previousPath}`)); | ||||
|         } | ||||
|         if (attachment.diff?.path) { | ||||
|           const diffPath = relativeFilePath(screen, config, attachment.diff.path); | ||||
|           resultLines.push(screen.colors.dim(`    Diff:     ${diffPath}`)); | ||||
|         } | ||||
|       } else if (attachment.path) { | ||||
|         const relativePath = relativeFilePath(screen, config, attachment.path); | ||||
|         resultLines.push(screen.colors.dim(`    ${relativePath}`)); | ||||
|         if (attachment.name === "trace") { | ||||
|           const packageManagerCommand = (0, import_utils.getPackageManagerExecCommand)(); | ||||
|           resultLines.push(screen.colors.dim(`    Usage:`)); | ||||
|           resultLines.push(""); | ||||
|           resultLines.push(screen.colors.dim(`        ${packageManagerCommand} playwright show-trace ${quotePathIfNeeded(relativePath)}`)); | ||||
|           resultLines.push(""); | ||||
|         } | ||||
|       } else { | ||||
|         if (attachment.contentType.startsWith("text/") && attachment.body) { | ||||
|           let text = attachment.body.toString(); | ||||
|           if (text.length > 300) | ||||
|             text = text.slice(0, 300) + "..."; | ||||
|           for (const line of text.split("\n")) | ||||
|             resultLines.push(screen.colors.dim(`    ${line}`)); | ||||
|         } | ||||
|       } | ||||
|       resultLines.push(screen.colors.dim(separator(screen, "   "))); | ||||
|     } | ||||
|     lines.push(...resultLines); | ||||
|   } | ||||
|   lines.push(""); | ||||
|   return lines.join("\n"); | ||||
| } | ||||
| function formatRetry(screen, result) { | ||||
|   const retryLines = []; | ||||
|   if (result.retry) { | ||||
|     retryLines.push(""); | ||||
|     retryLines.push(screen.colors.gray(separator(screen, `    Retry #${result.retry}`))); | ||||
|   } | ||||
|   return retryLines; | ||||
| } | ||||
| function quotePathIfNeeded(path2) { | ||||
|   if (/\s/.test(path2)) | ||||
|     return `"${path2}"`; | ||||
|   return path2; | ||||
| } | ||||
| function formatResultFailure(screen, test, result, initialIndent) { | ||||
|   const errorDetails = []; | ||||
|   if (result.status === "passed" && test.expectedStatus === "failed") { | ||||
|     errorDetails.push({ | ||||
|       message: indent(screen.colors.red(`Expected to fail, but passed.`), initialIndent) | ||||
|     }); | ||||
|   } | ||||
|   if (result.status === "interrupted") { | ||||
|     errorDetails.push({ | ||||
|       message: indent(screen.colors.red(`Test was interrupted.`), initialIndent) | ||||
|     }); | ||||
|   } | ||||
|   for (const error of result.errors) { | ||||
|     const formattedError = formatError(screen, error); | ||||
|     errorDetails.push({ | ||||
|       message: indent(formattedError.message, initialIndent), | ||||
|       location: formattedError.location | ||||
|     }); | ||||
|   } | ||||
|   return errorDetails; | ||||
| } | ||||
| function relativeFilePath(screen, config, file) { | ||||
|   if (screen.resolveFiles === "cwd") | ||||
|     return import_path.default.relative(process.cwd(), file); | ||||
|   return import_path.default.relative(config.rootDir, file); | ||||
| } | ||||
| function relativeTestPath(screen, config, test) { | ||||
|   return relativeFilePath(screen, config, test.location.file); | ||||
| } | ||||
| function stepSuffix(step) { | ||||
|   const stepTitles = step ? step.titlePath() : []; | ||||
|   return stepTitles.map((t) => t.split("\n")[0]).map((t) => " \u203A " + t).join(""); | ||||
| } | ||||
| function formatTestTitle(screen, config, test, step, omitLocation = false) { | ||||
|   const [, projectName, , ...titles] = test.titlePath(); | ||||
|   let location; | ||||
|   if (omitLocation) | ||||
|     location = `${relativeTestPath(screen, config, test)}`; | ||||
|   else | ||||
|     location = `${relativeTestPath(screen, config, test)}:${test.location.line}:${test.location.column}`; | ||||
|   const projectTitle = projectName ? `[${projectName}] \u203A ` : ""; | ||||
|   const testTitle = `${projectTitle}${location} \u203A ${titles.join(" \u203A ")}`; | ||||
|   const extraTags = test.tags.filter((t) => !testTitle.includes(t)); | ||||
|   return `${testTitle}${stepSuffix(step)}${extraTags.length ? " " + extraTags.join(" ") : ""}`; | ||||
| } | ||||
| function formatTestHeader(screen, config, test, options = {}) { | ||||
|   const title = formatTestTitle(screen, config, test); | ||||
|   const header = `${options.indent || ""}${options.index ? options.index + ") " : ""}${title}`; | ||||
|   let fullHeader = header; | ||||
|   if (options.mode === "error") { | ||||
|     const stepPaths = /* @__PURE__ */ new Set(); | ||||
|     for (const result of test.results.filter((r) => !!r.errors.length)) { | ||||
|       const stepPath = []; | ||||
|       const visit = (steps) => { | ||||
|         const errors = steps.filter((s) => s.error); | ||||
|         if (errors.length > 1) | ||||
|           return; | ||||
|         if (errors.length === 1 && errors[0].category === "test.step") { | ||||
|           stepPath.push(errors[0].title); | ||||
|           visit(errors[0].steps); | ||||
|         } | ||||
|       }; | ||||
|       visit(result.steps); | ||||
|       stepPaths.add(["", ...stepPath].join(" \u203A ")); | ||||
|     } | ||||
|     fullHeader = header + (stepPaths.size === 1 ? stepPaths.values().next().value : ""); | ||||
|   } | ||||
|   return separator(screen, fullHeader); | ||||
| } | ||||
| function formatError(screen, error) { | ||||
|   const message = error.message || error.value || ""; | ||||
|   const stack = error.stack; | ||||
|   if (!stack && !error.location) | ||||
|     return { message }; | ||||
|   const tokens = []; | ||||
|   const parsedStack = stack ? prepareErrorStack(stack) : void 0; | ||||
|   tokens.push(parsedStack?.message || message); | ||||
|   if (error.snippet) { | ||||
|     let snippet = error.snippet; | ||||
|     if (!screen.colors.enabled) | ||||
|       snippet = (0, import_util.stripAnsiEscapes)(snippet); | ||||
|     tokens.push(""); | ||||
|     tokens.push(snippet); | ||||
|   } | ||||
|   if (parsedStack && parsedStack.stackLines.length) | ||||
|     tokens.push(screen.colors.dim(parsedStack.stackLines.join("\n"))); | ||||
|   let location = error.location; | ||||
|   if (parsedStack && !location) | ||||
|     location = parsedStack.location; | ||||
|   if (error.cause) | ||||
|     tokens.push(screen.colors.dim("[cause]: ") + formatError(screen, error.cause).message); | ||||
|   return { | ||||
|     location, | ||||
|     message: tokens.join("\n") | ||||
|   }; | ||||
| } | ||||
| function separator(screen, text = "") { | ||||
|   if (text) | ||||
|     text += " "; | ||||
|   const columns = Math.min(100, screen.ttyWidth || 100); | ||||
|   return text + screen.colors.dim("\u2500".repeat(Math.max(0, columns - (0, import_util.stripAnsiEscapes)(text).length))); | ||||
| } | ||||
| function indent(lines, tab) { | ||||
|   return lines.replace(/^(?=.+$)/gm, tab); | ||||
| } | ||||
| function prepareErrorStack(stack) { | ||||
|   return (0, import_utils.parseErrorStack)(stack, import_path.default.sep, !!process.env.PWDEBUGIMPL); | ||||
| } | ||||
| function characterWidth(c) { | ||||
|   return import_utilsBundle2.getEastAsianWidth.eastAsianWidth(c.codePointAt(0)); | ||||
| } | ||||
| function stringWidth(v) { | ||||
|   let width = 0; | ||||
|   for (const { segment } of new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(v)) | ||||
|     width += characterWidth(segment); | ||||
|   return width; | ||||
| } | ||||
| function suffixOfWidth(v, width) { | ||||
|   const segments = [...new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(v)]; | ||||
|   let suffixBegin = v.length; | ||||
|   for (const { segment, index } of segments.reverse()) { | ||||
|     const segmentWidth = stringWidth(segment); | ||||
|     if (segmentWidth > width) | ||||
|       break; | ||||
|     width -= segmentWidth; | ||||
|     suffixBegin = index; | ||||
|   } | ||||
|   return v.substring(suffixBegin); | ||||
| } | ||||
| function fitToWidth(line, width, prefix) { | ||||
|   const prefixLength = prefix ? (0, import_util.stripAnsiEscapes)(prefix).length : 0; | ||||
|   width -= prefixLength; | ||||
|   if (stringWidth(line) <= width) | ||||
|     return line; | ||||
|   const parts = line.split(import_util.ansiRegex); | ||||
|   const taken = []; | ||||
|   for (let i = parts.length - 1; i >= 0; i--) { | ||||
|     if (i % 2) { | ||||
|       taken.push(parts[i]); | ||||
|     } else { | ||||
|       let part = suffixOfWidth(parts[i], width); | ||||
|       const wasTruncated = part.length < parts[i].length; | ||||
|       if (wasTruncated && parts[i].length > 0) { | ||||
|         part = "\u2026" + suffixOfWidth(parts[i], width - 1); | ||||
|       } | ||||
|       taken.push(part); | ||||
|       width -= stringWidth(part); | ||||
|     } | ||||
|   } | ||||
|   return taken.reverse().join(""); | ||||
| } | ||||
| function resolveFromEnv(name) { | ||||
|   const value = process.env[name]; | ||||
|   if (value) | ||||
|     return import_path.default.resolve(process.cwd(), value); | ||||
|   return void 0; | ||||
| } | ||||
| function resolveOutputFile(reporterName, options) { | ||||
|   const name = reporterName.toUpperCase(); | ||||
|   let outputFile = resolveFromEnv(`PLAYWRIGHT_${name}_OUTPUT_FILE`); | ||||
|   if (!outputFile && options.outputFile) | ||||
|     outputFile = import_path.default.resolve(options.configDir, options.outputFile); | ||||
|   if (outputFile) | ||||
|     return { outputFile }; | ||||
|   let outputDir = resolveFromEnv(`PLAYWRIGHT_${name}_OUTPUT_DIR`); | ||||
|   if (!outputDir && options.outputDir) | ||||
|     outputDir = import_path.default.resolve(options.configDir, options.outputDir); | ||||
|   if (!outputDir && options.default) | ||||
|     outputDir = (0, import_util.resolveReporterOutputPath)(options.default.outputDir, options.configDir, void 0); | ||||
|   if (!outputDir) | ||||
|     outputDir = options.configDir; | ||||
|   const reportName = process.env[`PLAYWRIGHT_${name}_OUTPUT_NAME`] ?? options.fileName ?? options.default?.fileName; | ||||
|   if (!reportName) | ||||
|     return void 0; | ||||
|   outputFile = import_path.default.resolve(outputDir, reportName); | ||||
|   return { outputFile, outputDir }; | ||||
| } | ||||
| function groupAttachments(attachments) { | ||||
|   const result = []; | ||||
|   const attachmentsByPrefix = /* @__PURE__ */ new Map(); | ||||
|   for (const attachment of attachments) { | ||||
|     if (!attachment.path) { | ||||
|       result.push(attachment); | ||||
|       continue; | ||||
|     } | ||||
|     const match = attachment.name.match(/^(.*)-(expected|actual|diff|previous)(\.[^.]+)?$/); | ||||
|     if (!match) { | ||||
|       result.push(attachment); | ||||
|       continue; | ||||
|     } | ||||
|     const [, name, category] = match; | ||||
|     let group = attachmentsByPrefix.get(name); | ||||
|     if (!group) { | ||||
|       group = { ...attachment, name }; | ||||
|       attachmentsByPrefix.set(name, group); | ||||
|       result.push(group); | ||||
|     } | ||||
|     if (category === "expected") | ||||
|       group.expected = attachment; | ||||
|     else if (category === "actual") | ||||
|       group.actual = attachment; | ||||
|     else if (category === "diff") | ||||
|       group.diff = attachment; | ||||
|     else if (category === "previous") | ||||
|       group.previous = attachment; | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   TerminalReporter, | ||||
|   fitToWidth, | ||||
|   formatError, | ||||
|   formatFailure, | ||||
|   formatResultFailure, | ||||
|   formatRetry, | ||||
|   internalScreen, | ||||
|   kOutputSymbol, | ||||
|   nonTerminalScreen, | ||||
|   prepareErrorStack, | ||||
|   relativeFilePath, | ||||
|   resolveOutputFile, | ||||
|   separator, | ||||
|   stepSuffix, | ||||
|   terminalScreen | ||||
| }); | ||||
							
								
								
									
										135
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/blob.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/blob.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var blob_exports = {}; | ||||
| __export(blob_exports, { | ||||
|   BlobReporter: () => BlobReporter, | ||||
|   currentBlobReportVersion: () => currentBlobReportVersion | ||||
| }); | ||||
| module.exports = __toCommonJS(blob_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_stream = require("stream"); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_utils2 = require("playwright-core/lib/utils"); | ||||
| var import_utilsBundle = require("playwright-core/lib/utilsBundle"); | ||||
| var import_zipBundle = require("playwright-core/lib/zipBundle"); | ||||
| var import_base = require("./base"); | ||||
| var import_teleEmitter = require("./teleEmitter"); | ||||
| const currentBlobReportVersion = 2; | ||||
| class BlobReporter extends import_teleEmitter.TeleReporterEmitter { | ||||
|   constructor(options) { | ||||
|     super((message) => this._messages.push(message)); | ||||
|     this._messages = []; | ||||
|     this._attachments = []; | ||||
|     this._options = options; | ||||
|     if (this._options.fileName && !this._options.fileName.endsWith(".zip")) | ||||
|       throw new Error(`Blob report file name must end with .zip extension: ${this._options.fileName}`); | ||||
|     this._salt = (0, import_utils2.createGuid)(); | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     const metadata = { | ||||
|       version: currentBlobReportVersion, | ||||
|       userAgent: (0, import_utils2.getUserAgent)(), | ||||
|       name: process.env.PWTEST_BOT_NAME, | ||||
|       shard: config.shard ?? void 0, | ||||
|       pathSeparator: import_path.default.sep | ||||
|     }; | ||||
|     this._messages.push({ | ||||
|       method: "onBlobReportMetadata", | ||||
|       params: metadata | ||||
|     }); | ||||
|     this._config = config; | ||||
|     super.onConfigure(config); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     await super.onEnd(result); | ||||
|     const zipFileName = await this._prepareOutputFile(); | ||||
|     const zipFile = new import_zipBundle.yazl.ZipFile(); | ||||
|     const zipFinishPromise = new import_utils2.ManualPromise(); | ||||
|     const finishPromise = zipFinishPromise.catch((e) => { | ||||
|       throw new Error(`Failed to write report ${zipFileName}: ` + e.message); | ||||
|     }); | ||||
|     zipFile.on("error", (error) => zipFinishPromise.reject(error)); | ||||
|     zipFile.outputStream.pipe(import_fs.default.createWriteStream(zipFileName)).on("close", () => { | ||||
|       zipFinishPromise.resolve(void 0); | ||||
|     }).on("error", (error) => zipFinishPromise.reject(error)); | ||||
|     for (const { originalPath, zipEntryPath } of this._attachments) { | ||||
|       if (!import_fs.default.statSync(originalPath, { throwIfNoEntry: false })?.isFile()) | ||||
|         continue; | ||||
|       zipFile.addFile(originalPath, zipEntryPath); | ||||
|     } | ||||
|     const lines = this._messages.map((m) => JSON.stringify(m) + "\n"); | ||||
|     const content = import_stream.Readable.from(lines); | ||||
|     zipFile.addReadStream(content, "report.jsonl"); | ||||
|     zipFile.end(); | ||||
|     await finishPromise; | ||||
|   } | ||||
|   async _prepareOutputFile() { | ||||
|     const { outputFile, outputDir } = (0, import_base.resolveOutputFile)("BLOB", { | ||||
|       ...this._options, | ||||
|       default: { | ||||
|         fileName: this._defaultReportName(this._config), | ||||
|         outputDir: "blob-report" | ||||
|       } | ||||
|     }); | ||||
|     if (!process.env.PWTEST_BLOB_DO_NOT_REMOVE) | ||||
|       await (0, import_utils.removeFolders)([outputDir]); | ||||
|     await import_fs.default.promises.mkdir(import_path.default.dirname(outputFile), { recursive: true }); | ||||
|     return outputFile; | ||||
|   } | ||||
|   _defaultReportName(config) { | ||||
|     let reportName = "report"; | ||||
|     if (this._options._commandHash) | ||||
|       reportName += "-" + (0, import_utils.sanitizeForFilePath)(this._options._commandHash); | ||||
|     if (config.shard) { | ||||
|       const paddedNumber = `${config.shard.current}`.padStart(`${config.shard.total}`.length, "0"); | ||||
|       reportName = `${reportName}-${paddedNumber}`; | ||||
|     } | ||||
|     return `${reportName}.zip`; | ||||
|   } | ||||
|   _serializeAttachments(attachments) { | ||||
|     return super._serializeAttachments(attachments).map((attachment) => { | ||||
|       if (!attachment.path) | ||||
|         return attachment; | ||||
|       const sha1 = (0, import_utils2.calculateSha1)(attachment.path + this._salt); | ||||
|       const extension = import_utilsBundle.mime.getExtension(attachment.contentType) || "dat"; | ||||
|       const newPath = `resources/${sha1}.${extension}`; | ||||
|       this._attachments.push({ originalPath: attachment.path, zipEntryPath: newPath }); | ||||
|       return { | ||||
|         ...attachment, | ||||
|         path: newPath | ||||
|       }; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   BlobReporter, | ||||
|   currentBlobReportVersion | ||||
| }); | ||||
							
								
								
									
										82
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/dot.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/dot.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var dot_exports = {}; | ||||
| __export(dot_exports, { | ||||
|   default: () => dot_default | ||||
| }); | ||||
| module.exports = __toCommonJS(dot_exports); | ||||
| var import_base = require("./base"); | ||||
| class DotReporter extends import_base.TerminalReporter { | ||||
|   constructor() { | ||||
|     super(...arguments); | ||||
|     this._counter = 0; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     super.onBegin(suite); | ||||
|     this.writeLine(this.generateStartingMessage()); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     super.onStdOut(chunk, test, result); | ||||
|     if (!this.config.quiet) | ||||
|       this.screen.stdout.write(chunk); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     super.onStdErr(chunk, test, result); | ||||
|     if (!this.config.quiet) | ||||
|       this.screen.stderr.write(chunk); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     super.onTestEnd(test, result); | ||||
|     if (this._counter === 80) { | ||||
|       this.screen.stdout.write("\n"); | ||||
|       this._counter = 0; | ||||
|     } | ||||
|     ++this._counter; | ||||
|     if (result.status === "skipped") { | ||||
|       this.screen.stdout.write(this.screen.colors.yellow("\xB0")); | ||||
|       return; | ||||
|     } | ||||
|     if (this.willRetry(test)) { | ||||
|       this.screen.stdout.write(this.screen.colors.gray("\xD7")); | ||||
|       return; | ||||
|     } | ||||
|     switch (test.outcome()) { | ||||
|       case "expected": | ||||
|         this.screen.stdout.write(this.screen.colors.green("\xB7")); | ||||
|         break; | ||||
|       case "unexpected": | ||||
|         this.screen.stdout.write(this.screen.colors.red(result.status === "timedOut" ? "T" : "F")); | ||||
|         break; | ||||
|       case "flaky": | ||||
|         this.screen.stdout.write(this.screen.colors.yellow("\xB1")); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|   onError(error) { | ||||
|     super.onError(error); | ||||
|     this.writeLine("\n" + this.formatError(error).message); | ||||
|     this._counter = 0; | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     await super.onEnd(result); | ||||
|     this.screen.stdout.write("\n"); | ||||
|     this.epilogue(true); | ||||
|   } | ||||
| } | ||||
| var dot_default = DotReporter; | ||||
							
								
								
									
										32
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/empty.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/empty.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var empty_exports = {}; | ||||
| __export(empty_exports, { | ||||
|   default: () => empty_default | ||||
| }); | ||||
| module.exports = __toCommonJS(empty_exports); | ||||
| class EmptyReporter { | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
| var empty_default = EmptyReporter; | ||||
							
								
								
									
										128
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/github.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/github.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var github_exports = {}; | ||||
| __export(github_exports, { | ||||
|   GitHubReporter: () => GitHubReporter, | ||||
|   default: () => github_default | ||||
| }); | ||||
| module.exports = __toCommonJS(github_exports); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_utilsBundle = require("playwright-core/lib/utilsBundle"); | ||||
| var import_base = require("./base"); | ||||
| var import_util = require("../util"); | ||||
| class GitHubLogger { | ||||
|   _log(message, type = "notice", options = {}) { | ||||
|     message = message.replace(/\n/g, "%0A"); | ||||
|     const configs = Object.entries(options).map(([key, option]) => `${key}=${option}`).join(","); | ||||
|     process.stdout.write((0, import_util.stripAnsiEscapes)(`::${type} ${configs}::${message} | ||||
| `)); | ||||
|   } | ||||
|   debug(message, options) { | ||||
|     this._log(message, "debug", options); | ||||
|   } | ||||
|   error(message, options) { | ||||
|     this._log(message, "error", options); | ||||
|   } | ||||
|   notice(message, options) { | ||||
|     this._log(message, "notice", options); | ||||
|   } | ||||
|   warning(message, options) { | ||||
|     this._log(message, "warning", options); | ||||
|   } | ||||
| } | ||||
| class GitHubReporter extends import_base.TerminalReporter { | ||||
|   constructor(options = {}) { | ||||
|     super(options); | ||||
|     this.githubLogger = new GitHubLogger(); | ||||
|     this.screen = { ...this.screen, colors: import_utils.noColors }; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return false; | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     await super.onEnd(result); | ||||
|     this._printAnnotations(); | ||||
|   } | ||||
|   onError(error) { | ||||
|     const errorMessage = this.formatError(error).message; | ||||
|     this.githubLogger.error(errorMessage); | ||||
|   } | ||||
|   _printAnnotations() { | ||||
|     const summary = this.generateSummary(); | ||||
|     const summaryMessage = this.generateSummaryMessage(summary); | ||||
|     if (summary.failuresToPrint.length) | ||||
|       this._printFailureAnnotations(summary.failuresToPrint); | ||||
|     this._printSlowTestAnnotations(); | ||||
|     this._printSummaryAnnotation(summaryMessage); | ||||
|   } | ||||
|   _printSlowTestAnnotations() { | ||||
|     this.getSlowTests().forEach(([file, duration]) => { | ||||
|       const filePath = workspaceRelativePath(import_path.default.join(process.cwd(), file)); | ||||
|       this.githubLogger.warning(`${filePath} took ${(0, import_utilsBundle.ms)(duration)}`, { | ||||
|         title: "Slow Test", | ||||
|         file: filePath | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
|   _printSummaryAnnotation(summary) { | ||||
|     this.githubLogger.notice(summary, { | ||||
|       title: "\u{1F3AD} Playwright Run Summary" | ||||
|     }); | ||||
|   } | ||||
|   _printFailureAnnotations(failures) { | ||||
|     failures.forEach((test, index) => { | ||||
|       const title = this.formatTestTitle(test); | ||||
|       const header = this.formatTestHeader(test, { indent: "  ", index: index + 1, mode: "error" }); | ||||
|       for (const result of test.results) { | ||||
|         const errors = (0, import_base.formatResultFailure)(this.screen, test, result, "    "); | ||||
|         for (const error of errors) { | ||||
|           const options = { | ||||
|             file: workspaceRelativePath(error.location?.file || test.location.file), | ||||
|             title | ||||
|           }; | ||||
|           if (error.location) { | ||||
|             options.line = error.location.line; | ||||
|             options.col = error.location.column; | ||||
|           } | ||||
|           const message = [header, ...(0, import_base.formatRetry)(this.screen, result), error.message].join("\n"); | ||||
|           this.githubLogger.error(message, options); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| function workspaceRelativePath(filePath) { | ||||
|   return import_path.default.relative(process.env["GITHUB_WORKSPACE"] ?? "", filePath); | ||||
| } | ||||
| var github_default = GitHubReporter; | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   GitHubReporter | ||||
| }); | ||||
							
								
								
									
										631
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/html.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										631
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/html.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,631 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var html_exports = {}; | ||||
| __export(html_exports, { | ||||
|   default: () => html_default, | ||||
|   showHTMLReport: () => showHTMLReport, | ||||
|   startHtmlReportServer: () => startHtmlReportServer | ||||
| }); | ||||
| module.exports = __toCommonJS(html_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_stream = require("stream"); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_utils2 = require("playwright-core/lib/utils"); | ||||
| var import_utilsBundle = require("playwright-core/lib/utilsBundle"); | ||||
| var import_utilsBundle2 = require("playwright-core/lib/utilsBundle"); | ||||
| var import_zipBundle = require("playwright-core/lib/zipBundle"); | ||||
| var import_base = require("./base"); | ||||
| var import_babelBundle = require("../transform/babelBundle"); | ||||
| var import_util = require("../util"); | ||||
| const htmlReportOptions = ["always", "never", "on-failure"]; | ||||
| const isHtmlReportOption = (type) => { | ||||
|   return htmlReportOptions.includes(type); | ||||
| }; | ||||
| class HtmlReporter { | ||||
|   constructor(options) { | ||||
|     this._topLevelErrors = []; | ||||
|     this._options = options; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return false; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this.config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     const { outputFolder, open: open2, attachmentsBaseURL, host, port } = this._resolveOptions(); | ||||
|     this._outputFolder = outputFolder; | ||||
|     this._open = open2; | ||||
|     this._host = host; | ||||
|     this._port = port; | ||||
|     this._attachmentsBaseURL = attachmentsBaseURL; | ||||
|     const reportedWarnings = /* @__PURE__ */ new Set(); | ||||
|     for (const project of this.config.projects) { | ||||
|       if (this._isSubdirectory(outputFolder, project.outputDir) || this._isSubdirectory(project.outputDir, outputFolder)) { | ||||
|         const key = outputFolder + "|" + project.outputDir; | ||||
|         if (reportedWarnings.has(key)) | ||||
|           continue; | ||||
|         reportedWarnings.add(key); | ||||
|         writeLine(import_utils2.colors.red(`Configuration Error: HTML reporter output folder clashes with the tests output folder:`)); | ||||
|         writeLine(` | ||||
|     html reporter folder: ${import_utils2.colors.bold(outputFolder)} | ||||
|     test results folder: ${import_utils2.colors.bold(project.outputDir)}`); | ||||
|         writeLine(""); | ||||
|         writeLine(`HTML reporter will clear its output directory prior to being generated, which will lead to the artifact loss. | ||||
| `); | ||||
|       } | ||||
|     } | ||||
|     this.suite = suite; | ||||
|   } | ||||
|   _resolveOptions() { | ||||
|     const outputFolder = reportFolderFromEnv() ?? (0, import_util.resolveReporterOutputPath)("playwright-report", this._options.configDir, this._options.outputFolder); | ||||
|     return { | ||||
|       outputFolder, | ||||
|       open: getHtmlReportOptionProcessEnv() || this._options.open || "on-failure", | ||||
|       attachmentsBaseURL: process.env.PLAYWRIGHT_HTML_ATTACHMENTS_BASE_URL || this._options.attachmentsBaseURL || "data/", | ||||
|       host: process.env.PLAYWRIGHT_HTML_HOST || this._options.host, | ||||
|       port: process.env.PLAYWRIGHT_HTML_PORT ? +process.env.PLAYWRIGHT_HTML_PORT : this._options.port | ||||
|     }; | ||||
|   } | ||||
|   _isSubdirectory(parentDir, dir) { | ||||
|     const relativePath = import_path.default.relative(parentDir, dir); | ||||
|     return !!relativePath && !relativePath.startsWith("..") && !import_path.default.isAbsolute(relativePath); | ||||
|   } | ||||
|   onError(error) { | ||||
|     this._topLevelErrors.push(error); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     const projectSuites = this.suite.suites; | ||||
|     await (0, import_utils.removeFolders)([this._outputFolder]); | ||||
|     let noSnippets; | ||||
|     if (process.env.PLAYWRIGHT_HTML_NO_SNIPPETS === "false" || process.env.PLAYWRIGHT_HTML_NO_SNIPPETS === "0") | ||||
|       noSnippets = false; | ||||
|     else if (process.env.PLAYWRIGHT_HTML_NO_SNIPPETS) | ||||
|       noSnippets = true; | ||||
|     noSnippets = noSnippets || this._options.noSnippets; | ||||
|     const builder = new HtmlBuilder(this.config, this._outputFolder, this._attachmentsBaseURL, process.env.PLAYWRIGHT_HTML_TITLE || this._options.title, noSnippets); | ||||
|     this._buildResult = await builder.build(this.config.metadata, projectSuites, result, this._topLevelErrors); | ||||
|   } | ||||
|   async onExit() { | ||||
|     if (process.env.CI || !this._buildResult) | ||||
|       return; | ||||
|     const { ok, singleTestId } = this._buildResult; | ||||
|     const shouldOpen = !this._options._isTestServer && (this._open === "always" || !ok && this._open === "on-failure"); | ||||
|     if (shouldOpen) { | ||||
|       await showHTMLReport(this._outputFolder, this._host, this._port, singleTestId); | ||||
|     } else if (this._options._mode === "test" && !this._options._isTestServer) { | ||||
|       const packageManagerCommand = (0, import_utils.getPackageManagerExecCommand)(); | ||||
|       const relativeReportPath = this._outputFolder === standaloneDefaultFolder() ? "" : " " + import_path.default.relative(process.cwd(), this._outputFolder); | ||||
|       const hostArg = this._host ? ` --host ${this._host}` : ""; | ||||
|       const portArg = this._port ? ` --port ${this._port}` : ""; | ||||
|       writeLine(""); | ||||
|       writeLine("To open last HTML report run:"); | ||||
|       writeLine(import_utils2.colors.cyan(` | ||||
|   ${packageManagerCommand} playwright show-report${relativeReportPath}${hostArg}${portArg} | ||||
| `)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| function reportFolderFromEnv() { | ||||
|   const envValue = process.env.PLAYWRIGHT_HTML_OUTPUT_DIR || process.env.PLAYWRIGHT_HTML_REPORT; | ||||
|   return envValue ? import_path.default.resolve(envValue) : void 0; | ||||
| } | ||||
| function getHtmlReportOptionProcessEnv() { | ||||
|   const htmlOpenEnv = process.env.PLAYWRIGHT_HTML_OPEN || process.env.PW_TEST_HTML_REPORT_OPEN; | ||||
|   if (!htmlOpenEnv) | ||||
|     return void 0; | ||||
|   if (!isHtmlReportOption(htmlOpenEnv)) { | ||||
|     writeLine(import_utils2.colors.red(`Configuration Error: HTML reporter Invalid value for PLAYWRIGHT_HTML_OPEN: ${htmlOpenEnv}. Valid values are: ${htmlReportOptions.join(", ")}`)); | ||||
|     return void 0; | ||||
|   } | ||||
|   return htmlOpenEnv; | ||||
| } | ||||
| function standaloneDefaultFolder() { | ||||
|   return reportFolderFromEnv() ?? (0, import_util.resolveReporterOutputPath)("playwright-report", process.cwd(), void 0); | ||||
| } | ||||
| async function showHTMLReport(reportFolder, host = "localhost", port, testId) { | ||||
|   const folder = reportFolder ?? standaloneDefaultFolder(); | ||||
|   try { | ||||
|     (0, import_utils.assert)(import_fs.default.statSync(folder).isDirectory()); | ||||
|   } catch (e) { | ||||
|     writeLine(import_utils2.colors.red(`No report found at "${folder}"`)); | ||||
|     (0, import_utils.gracefullyProcessExitDoNotHang)(1); | ||||
|     return; | ||||
|   } | ||||
|   const server = startHtmlReportServer(folder); | ||||
|   await server.start({ port, host, preferredPort: port ? void 0 : 9323 }); | ||||
|   let url = server.urlPrefix("human-readable"); | ||||
|   writeLine(""); | ||||
|   writeLine(import_utils2.colors.cyan(`  Serving HTML report at ${url}. Press Ctrl+C to quit.`)); | ||||
|   if (testId) | ||||
|     url += `#?testId=${testId}`; | ||||
|   url = url.replace("0.0.0.0", "localhost"); | ||||
|   await (0, import_utilsBundle.open)(url, { wait: true }).catch(() => { | ||||
|   }); | ||||
|   await new Promise(() => { | ||||
|   }); | ||||
| } | ||||
| function startHtmlReportServer(folder) { | ||||
|   const server = new import_utils.HttpServer(); | ||||
|   server.routePrefix("/", (request, response) => { | ||||
|     let relativePath = new URL("http://localhost" + request.url).pathname; | ||||
|     if (relativePath.startsWith("/trace/file")) { | ||||
|       const url = new URL("http://localhost" + request.url); | ||||
|       try { | ||||
|         return server.serveFile(request, response, url.searchParams.get("path")); | ||||
|       } catch (e) { | ||||
|         return false; | ||||
|       } | ||||
|     } | ||||
|     if (relativePath.endsWith("/stall.js")) | ||||
|       return true; | ||||
|     if (relativePath === "/") | ||||
|       relativePath = "/index.html"; | ||||
|     const absolutePath = import_path.default.join(folder, ...relativePath.split("/")); | ||||
|     return server.serveFile(request, response, absolutePath); | ||||
|   }); | ||||
|   return server; | ||||
| } | ||||
| class HtmlBuilder { | ||||
|   constructor(config, outputDir, attachmentsBaseURL, title, noSnippets = false) { | ||||
|     this._stepsInFile = new import_utils.MultiMap(); | ||||
|     this._hasTraces = false; | ||||
|     this._config = config; | ||||
|     this._reportFolder = outputDir; | ||||
|     this._noSnippets = noSnippets; | ||||
|     import_fs.default.mkdirSync(this._reportFolder, { recursive: true }); | ||||
|     this._dataZipFile = new import_zipBundle.yazl.ZipFile(); | ||||
|     this._attachmentsBaseURL = attachmentsBaseURL; | ||||
|     this._title = title; | ||||
|   } | ||||
|   async build(metadata, projectSuites, result, topLevelErrors) { | ||||
|     const data = /* @__PURE__ */ new Map(); | ||||
|     for (const projectSuite of projectSuites) { | ||||
|       for (const fileSuite of projectSuite.suites) { | ||||
|         const fileName = this._relativeLocation(fileSuite.location).file; | ||||
|         const fileId = (0, import_utils.calculateSha1)((0, import_utils.toPosixPath)(fileName)).slice(0, 20); | ||||
|         let fileEntry = data.get(fileId); | ||||
|         if (!fileEntry) { | ||||
|           fileEntry = { | ||||
|             testFile: { fileId, fileName, tests: [] }, | ||||
|             testFileSummary: { fileId, fileName, tests: [], stats: emptyStats() } | ||||
|           }; | ||||
|           data.set(fileId, fileEntry); | ||||
|         } | ||||
|         const { testFile, testFileSummary } = fileEntry; | ||||
|         const testEntries = []; | ||||
|         this._processSuite(fileSuite, projectSuite.project().name, [], testEntries); | ||||
|         for (const test of testEntries) { | ||||
|           testFile.tests.push(test.testCase); | ||||
|           testFileSummary.tests.push(test.testCaseSummary); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if (!this._noSnippets) | ||||
|       createSnippets(this._stepsInFile); | ||||
|     let ok = true; | ||||
|     for (const [fileId, { testFile, testFileSummary }] of data) { | ||||
|       const stats = testFileSummary.stats; | ||||
|       for (const test of testFileSummary.tests) { | ||||
|         if (test.outcome === "expected") | ||||
|           ++stats.expected; | ||||
|         if (test.outcome === "skipped") | ||||
|           ++stats.skipped; | ||||
|         if (test.outcome === "unexpected") | ||||
|           ++stats.unexpected; | ||||
|         if (test.outcome === "flaky") | ||||
|           ++stats.flaky; | ||||
|         ++stats.total; | ||||
|       } | ||||
|       stats.ok = stats.unexpected + stats.flaky === 0; | ||||
|       if (!stats.ok) | ||||
|         ok = false; | ||||
|       const testCaseSummaryComparator = (t1, t2) => { | ||||
|         const w1 = (t1.outcome === "unexpected" ? 1e3 : 0) + (t1.outcome === "flaky" ? 1 : 0); | ||||
|         const w2 = (t2.outcome === "unexpected" ? 1e3 : 0) + (t2.outcome === "flaky" ? 1 : 0); | ||||
|         return w2 - w1; | ||||
|       }; | ||||
|       testFileSummary.tests.sort(testCaseSummaryComparator); | ||||
|       this._addDataFile(fileId + ".json", testFile); | ||||
|     } | ||||
|     const htmlReport = { | ||||
|       metadata, | ||||
|       title: this._title, | ||||
|       startTime: result.startTime.getTime(), | ||||
|       duration: result.duration, | ||||
|       files: [...data.values()].map((e) => e.testFileSummary), | ||||
|       projectNames: projectSuites.map((r) => r.project().name), | ||||
|       stats: { ...[...data.values()].reduce((a, e) => addStats(a, e.testFileSummary.stats), emptyStats()) }, | ||||
|       errors: topLevelErrors.map((error) => (0, import_base.formatError)(import_base.internalScreen, error).message) | ||||
|     }; | ||||
|     htmlReport.files.sort((f1, f2) => { | ||||
|       const w1 = f1.stats.unexpected * 1e3 + f1.stats.flaky; | ||||
|       const w2 = f2.stats.unexpected * 1e3 + f2.stats.flaky; | ||||
|       return w2 - w1; | ||||
|     }); | ||||
|     this._addDataFile("report.json", htmlReport); | ||||
|     let singleTestId; | ||||
|     if (htmlReport.stats.total === 1) { | ||||
|       const testFile = data.values().next().value.testFile; | ||||
|       singleTestId = testFile.tests[0].testId; | ||||
|     } | ||||
|     if (process.env.PW_HMR === "1") { | ||||
|       const redirectFile = import_path.default.join(this._reportFolder, "index.html"); | ||||
|       await this._writeReportData(redirectFile); | ||||
|       async function redirect() { | ||||
|         const hmrURL = new URL("http://localhost:44224"); | ||||
|         const popup = window.open(hmrURL); | ||||
|         const listener = (evt) => { | ||||
|           if (evt.source === popup && evt.data === "ready") { | ||||
|             const element = document.getElementById("playwrightReportBase64"); | ||||
|             popup.postMessage(element?.textContent ?? "", hmrURL.origin); | ||||
|             window.removeEventListener("message", listener); | ||||
|             window.close(); | ||||
|           } | ||||
|         }; | ||||
|         window.addEventListener("message", listener); | ||||
|       } | ||||
|       import_fs.default.appendFileSync(redirectFile, `<script>(${redirect.toString()})()</script>`); | ||||
|       return { ok, singleTestId }; | ||||
|     } | ||||
|     const appFolder = import_path.default.join(require.resolve("playwright-core"), "..", "lib", "vite", "htmlReport"); | ||||
|     await (0, import_utils.copyFileAndMakeWritable)(import_path.default.join(appFolder, "index.html"), import_path.default.join(this._reportFolder, "index.html")); | ||||
|     if (this._hasTraces) { | ||||
|       const traceViewerFolder = import_path.default.join(require.resolve("playwright-core"), "..", "lib", "vite", "traceViewer"); | ||||
|       const traceViewerTargetFolder = import_path.default.join(this._reportFolder, "trace"); | ||||
|       const traceViewerAssetsTargetFolder = import_path.default.join(traceViewerTargetFolder, "assets"); | ||||
|       import_fs.default.mkdirSync(traceViewerAssetsTargetFolder, { recursive: true }); | ||||
|       for (const file of import_fs.default.readdirSync(traceViewerFolder)) { | ||||
|         if (file.endsWith(".map") || file.includes("watch") || file.includes("assets")) | ||||
|           continue; | ||||
|         await (0, import_utils.copyFileAndMakeWritable)(import_path.default.join(traceViewerFolder, file), import_path.default.join(traceViewerTargetFolder, file)); | ||||
|       } | ||||
|       for (const file of import_fs.default.readdirSync(import_path.default.join(traceViewerFolder, "assets"))) { | ||||
|         if (file.endsWith(".map") || file.includes("xtermModule")) | ||||
|           continue; | ||||
|         await (0, import_utils.copyFileAndMakeWritable)(import_path.default.join(traceViewerFolder, "assets", file), import_path.default.join(traceViewerAssetsTargetFolder, file)); | ||||
|       } | ||||
|     } | ||||
|     await this._writeReportData(import_path.default.join(this._reportFolder, "index.html")); | ||||
|     return { ok, singleTestId }; | ||||
|   } | ||||
|   async _writeReportData(filePath) { | ||||
|     import_fs.default.appendFileSync(filePath, '<script id="playwrightReportBase64" type="application/zip">data:application/zip;base64,'); | ||||
|     await new Promise((f) => { | ||||
|       this._dataZipFile.end(void 0, () => { | ||||
|         this._dataZipFile.outputStream.pipe(new Base64Encoder()).pipe(import_fs.default.createWriteStream(filePath, { flags: "a" })).on("close", f); | ||||
|       }); | ||||
|     }); | ||||
|     import_fs.default.appendFileSync(filePath, "</script>"); | ||||
|   } | ||||
|   _addDataFile(fileName, data) { | ||||
|     this._dataZipFile.addBuffer(Buffer.from(JSON.stringify(data)), fileName); | ||||
|   } | ||||
|   _processSuite(suite, projectName, path2, outTests) { | ||||
|     const newPath = [...path2, suite.title]; | ||||
|     suite.entries().forEach((e) => { | ||||
|       if (e.type === "test") | ||||
|         outTests.push(this._createTestEntry(e, projectName, newPath)); | ||||
|       else | ||||
|         this._processSuite(e, projectName, newPath, outTests); | ||||
|     }); | ||||
|   } | ||||
|   _createTestEntry(test, projectName, path2) { | ||||
|     const duration = test.results.reduce((a, r) => a + r.duration, 0); | ||||
|     const location = this._relativeLocation(test.location); | ||||
|     path2 = path2.slice(1).filter((path3) => path3.length > 0); | ||||
|     const results = test.results.map((r) => this._createTestResult(test, r)); | ||||
|     return { | ||||
|       testCase: { | ||||
|         testId: test.id, | ||||
|         title: test.title, | ||||
|         projectName, | ||||
|         location, | ||||
|         duration, | ||||
|         annotations: this._serializeAnnotations(test.annotations), | ||||
|         tags: test.tags, | ||||
|         outcome: test.outcome(), | ||||
|         path: path2, | ||||
|         results, | ||||
|         ok: test.outcome() === "expected" || test.outcome() === "flaky" | ||||
|       }, | ||||
|       testCaseSummary: { | ||||
|         testId: test.id, | ||||
|         title: test.title, | ||||
|         projectName, | ||||
|         location, | ||||
|         duration, | ||||
|         annotations: this._serializeAnnotations(test.annotations), | ||||
|         tags: test.tags, | ||||
|         outcome: test.outcome(), | ||||
|         path: path2, | ||||
|         ok: test.outcome() === "expected" || test.outcome() === "flaky", | ||||
|         results: results.map((result) => { | ||||
|           return { attachments: result.attachments.map((a) => ({ name: a.name, contentType: a.contentType, path: a.path })) }; | ||||
|         }) | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|   _serializeAttachments(attachments) { | ||||
|     let lastAttachment; | ||||
|     return attachments.map((a) => { | ||||
|       if (a.name === "trace") | ||||
|         this._hasTraces = true; | ||||
|       if ((a.name === "stdout" || a.name === "stderr") && a.contentType === "text/plain") { | ||||
|         if (lastAttachment && lastAttachment.name === a.name && lastAttachment.contentType === a.contentType) { | ||||
|           lastAttachment.body += (0, import_util.stripAnsiEscapes)(a.body); | ||||
|           return null; | ||||
|         } | ||||
|         a.body = (0, import_util.stripAnsiEscapes)(a.body); | ||||
|         lastAttachment = a; | ||||
|         return a; | ||||
|       } | ||||
|       if (a.path) { | ||||
|         let fileName = a.path; | ||||
|         try { | ||||
|           const buffer = import_fs.default.readFileSync(a.path); | ||||
|           const sha1 = (0, import_utils.calculateSha1)(buffer) + import_path.default.extname(a.path); | ||||
|           fileName = this._attachmentsBaseURL + sha1; | ||||
|           import_fs.default.mkdirSync(import_path.default.join(this._reportFolder, "data"), { recursive: true }); | ||||
|           import_fs.default.writeFileSync(import_path.default.join(this._reportFolder, "data", sha1), buffer); | ||||
|         } catch (e) { | ||||
|         } | ||||
|         return { | ||||
|           name: a.name, | ||||
|           contentType: a.contentType, | ||||
|           path: fileName, | ||||
|           body: a.body | ||||
|         }; | ||||
|       } | ||||
|       if (a.body instanceof Buffer) { | ||||
|         if (isTextContentType(a.contentType)) { | ||||
|           const charset = a.contentType.match(/charset=(.*)/)?.[1]; | ||||
|           try { | ||||
|             const body = a.body.toString(charset || "utf-8"); | ||||
|             return { | ||||
|               name: a.name, | ||||
|               contentType: a.contentType, | ||||
|               body | ||||
|             }; | ||||
|           } catch (e) { | ||||
|           } | ||||
|         } | ||||
|         import_fs.default.mkdirSync(import_path.default.join(this._reportFolder, "data"), { recursive: true }); | ||||
|         const extension = (0, import_utils.sanitizeForFilePath)(import_path.default.extname(a.name).replace(/^\./, "")) || import_utilsBundle2.mime.getExtension(a.contentType) || "dat"; | ||||
|         const sha1 = (0, import_utils.calculateSha1)(a.body) + "." + extension; | ||||
|         import_fs.default.writeFileSync(import_path.default.join(this._reportFolder, "data", sha1), a.body); | ||||
|         return { | ||||
|           name: a.name, | ||||
|           contentType: a.contentType, | ||||
|           path: this._attachmentsBaseURL + sha1 | ||||
|         }; | ||||
|       } | ||||
|       return { | ||||
|         name: a.name, | ||||
|         contentType: a.contentType, | ||||
|         body: a.body | ||||
|       }; | ||||
|     }).filter(Boolean); | ||||
|   } | ||||
|   _serializeAnnotations(annotations) { | ||||
|     return annotations.map((a) => ({ | ||||
|       type: a.type, | ||||
|       description: a.description === void 0 ? void 0 : String(a.description), | ||||
|       location: a.location ? { | ||||
|         file: a.location.file, | ||||
|         line: a.location.line, | ||||
|         column: a.location.column | ||||
|       } : void 0 | ||||
|     })); | ||||
|   } | ||||
|   _createTestResult(test, result) { | ||||
|     return { | ||||
|       duration: result.duration, | ||||
|       startTime: result.startTime.toISOString(), | ||||
|       retry: result.retry, | ||||
|       steps: dedupeSteps(result.steps).map((s) => this._createTestStep(s, result)), | ||||
|       errors: (0, import_base.formatResultFailure)(import_base.internalScreen, test, result, "").map((error) => { | ||||
|         return { | ||||
|           message: error.message, | ||||
|           codeframe: error.location ? createErrorCodeframe(error.message, error.location) : void 0 | ||||
|         }; | ||||
|       }), | ||||
|       status: result.status, | ||||
|       annotations: this._serializeAnnotations(result.annotations), | ||||
|       attachments: this._serializeAttachments([ | ||||
|         ...result.attachments, | ||||
|         ...result.stdout.map((m) => stdioAttachment(m, "stdout")), | ||||
|         ...result.stderr.map((m) => stdioAttachment(m, "stderr")) | ||||
|       ]) | ||||
|     }; | ||||
|   } | ||||
|   _createTestStep(dedupedStep, result) { | ||||
|     const { step, duration, count } = dedupedStep; | ||||
|     const skipped = dedupedStep.step.annotations?.find((a) => a.type === "skip"); | ||||
|     let title = step.title; | ||||
|     if (skipped) | ||||
|       title = `${title} (skipped${skipped.description ? ": " + skipped.description : ""})`; | ||||
|     const testStep = { | ||||
|       title, | ||||
|       startTime: step.startTime.toISOString(), | ||||
|       duration, | ||||
|       steps: dedupeSteps(step.steps).map((s) => this._createTestStep(s, result)), | ||||
|       attachments: step.attachments.map((s) => { | ||||
|         const index = result.attachments.indexOf(s); | ||||
|         if (index === -1) | ||||
|           throw new Error("Unexpected, attachment not found"); | ||||
|         return index; | ||||
|       }), | ||||
|       location: this._relativeLocation(step.location), | ||||
|       error: step.error?.message, | ||||
|       count, | ||||
|       skipped: !!skipped | ||||
|     }; | ||||
|     if (step.location) | ||||
|       this._stepsInFile.set(step.location.file, testStep); | ||||
|     return testStep; | ||||
|   } | ||||
|   _relativeLocation(location) { | ||||
|     if (!location) | ||||
|       return void 0; | ||||
|     const file = (0, import_utils.toPosixPath)(import_path.default.relative(this._config.rootDir, location.file)); | ||||
|     return { | ||||
|       file, | ||||
|       line: location.line, | ||||
|       column: location.column | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| const emptyStats = () => { | ||||
|   return { | ||||
|     total: 0, | ||||
|     expected: 0, | ||||
|     unexpected: 0, | ||||
|     flaky: 0, | ||||
|     skipped: 0, | ||||
|     ok: true | ||||
|   }; | ||||
| }; | ||||
| const addStats = (stats, delta) => { | ||||
|   stats.total += delta.total; | ||||
|   stats.skipped += delta.skipped; | ||||
|   stats.expected += delta.expected; | ||||
|   stats.unexpected += delta.unexpected; | ||||
|   stats.flaky += delta.flaky; | ||||
|   stats.ok = stats.ok && delta.ok; | ||||
|   return stats; | ||||
| }; | ||||
| class Base64Encoder extends import_stream.Transform { | ||||
|   _transform(chunk, encoding, callback) { | ||||
|     if (this._remainder) { | ||||
|       chunk = Buffer.concat([this._remainder, chunk]); | ||||
|       this._remainder = void 0; | ||||
|     } | ||||
|     const remaining = chunk.length % 3; | ||||
|     if (remaining) { | ||||
|       this._remainder = chunk.slice(chunk.length - remaining); | ||||
|       chunk = chunk.slice(0, chunk.length - remaining); | ||||
|     } | ||||
|     chunk = chunk.toString("base64"); | ||||
|     this.push(Buffer.from(chunk)); | ||||
|     callback(); | ||||
|   } | ||||
|   _flush(callback) { | ||||
|     if (this._remainder) | ||||
|       this.push(Buffer.from(this._remainder.toString("base64"))); | ||||
|     callback(); | ||||
|   } | ||||
| } | ||||
| function isTextContentType(contentType) { | ||||
|   return contentType.startsWith("text/") || contentType.startsWith("application/json"); | ||||
| } | ||||
| function stdioAttachment(chunk, type) { | ||||
|   return { | ||||
|     name: type, | ||||
|     contentType: "text/plain", | ||||
|     body: typeof chunk === "string" ? chunk : chunk.toString("utf-8") | ||||
|   }; | ||||
| } | ||||
| function dedupeSteps(steps) { | ||||
|   const result = []; | ||||
|   let lastResult = void 0; | ||||
|   for (const step of steps) { | ||||
|     const canDedupe = !step.error && step.duration >= 0 && step.location?.file && !step.steps.length; | ||||
|     const lastStep = lastResult?.step; | ||||
|     if (canDedupe && lastResult && lastStep && step.category === lastStep.category && step.title === lastStep.title && step.location?.file === lastStep.location?.file && step.location?.line === lastStep.location?.line && step.location?.column === lastStep.location?.column) { | ||||
|       ++lastResult.count; | ||||
|       lastResult.duration += step.duration; | ||||
|       continue; | ||||
|     } | ||||
|     lastResult = { step, count: 1, duration: step.duration }; | ||||
|     result.push(lastResult); | ||||
|     if (!canDedupe) | ||||
|       lastResult = void 0; | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
| function createSnippets(stepsInFile) { | ||||
|   for (const file of stepsInFile.keys()) { | ||||
|     let source; | ||||
|     try { | ||||
|       source = import_fs.default.readFileSync(file, "utf-8") + "\n//"; | ||||
|     } catch (e) { | ||||
|       continue; | ||||
|     } | ||||
|     const lines = source.split("\n").length; | ||||
|     const highlighted = (0, import_babelBundle.codeFrameColumns)(source, { start: { line: lines, column: 1 } }, { highlightCode: true, linesAbove: lines, linesBelow: 0 }); | ||||
|     const highlightedLines = highlighted.split("\n"); | ||||
|     const lineWithArrow = highlightedLines[highlightedLines.length - 1]; | ||||
|     for (const step of stepsInFile.get(file)) { | ||||
|       if (step.location.line < 2 || step.location.line >= lines) | ||||
|         continue; | ||||
|       const snippetLines = highlightedLines.slice(step.location.line - 2, step.location.line + 1); | ||||
|       const index = lineWithArrow.indexOf("^"); | ||||
|       const shiftedArrow = lineWithArrow.slice(0, index) + " ".repeat(step.location.column - 1) + lineWithArrow.slice(index); | ||||
|       snippetLines.splice(2, 0, shiftedArrow); | ||||
|       step.snippet = snippetLines.join("\n"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| function createErrorCodeframe(message, location) { | ||||
|   let source; | ||||
|   try { | ||||
|     source = import_fs.default.readFileSync(location.file, "utf-8") + "\n//"; | ||||
|   } catch (e) { | ||||
|     return; | ||||
|   } | ||||
|   return (0, import_babelBundle.codeFrameColumns)( | ||||
|     source, | ||||
|     { | ||||
|       start: { | ||||
|         line: location.line, | ||||
|         column: location.column | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       highlightCode: false, | ||||
|       linesAbove: 100, | ||||
|       linesBelow: 100, | ||||
|       message: (0, import_util.stripAnsiEscapes)(message).split("\n")[0] || void 0 | ||||
|     } | ||||
|   ); | ||||
| } | ||||
| function writeLine(line) { | ||||
|   process.stdout.write(line + "\n"); | ||||
| } | ||||
| var html_default = HtmlReporter; | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   showHTMLReport, | ||||
|   startHtmlReportServer | ||||
| }); | ||||
							
								
								
									
										130
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/internalReporter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/internalReporter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var internalReporter_exports = {}; | ||||
| __export(internalReporter_exports, { | ||||
|   InternalReporter: () => InternalReporter | ||||
| }); | ||||
| module.exports = __toCommonJS(internalReporter_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_base = require("./base"); | ||||
| var import_multiplexer = require("./multiplexer"); | ||||
| var import_test = require("../common/test"); | ||||
| var import_babelBundle = require("../transform/babelBundle"); | ||||
| var import_reporterV2 = require("./reporterV2"); | ||||
| class InternalReporter { | ||||
|   constructor(reporters) { | ||||
|     this._didBegin = false; | ||||
|     this._reporter = new import_multiplexer.Multiplexer(reporters.map(import_reporterV2.wrapReporterAsV2)); | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this._config = config; | ||||
|     this._startTime = /* @__PURE__ */ new Date(); | ||||
|     this._monotonicStartTime = (0, import_utils.monotonicTime)(); | ||||
|     this._reporter.onConfigure?.(config); | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this._didBegin = true; | ||||
|     this._reporter.onBegin?.(suite); | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     this._reporter.onTestBegin?.(test, result); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     this._reporter.onStdOut?.(chunk, test, result); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     this._reporter.onStdErr?.(chunk, test, result); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     this._addSnippetToTestErrors(test, result); | ||||
|     this._reporter.onTestEnd?.(test, result); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     if (!this._didBegin) { | ||||
|       this.onBegin(new import_test.Suite("", "root")); | ||||
|     } | ||||
|     return await this._reporter.onEnd?.({ | ||||
|       ...result, | ||||
|       startTime: this._startTime, | ||||
|       duration: (0, import_utils.monotonicTime)() - this._monotonicStartTime | ||||
|     }); | ||||
|   } | ||||
|   async onExit() { | ||||
|     await this._reporter.onExit?.(); | ||||
|   } | ||||
|   onError(error) { | ||||
|     addLocationAndSnippetToError(this._config, error); | ||||
|     this._reporter.onError?.(error); | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     this._reporter.onStepBegin?.(test, result, step); | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     this._addSnippetToStepError(test, step); | ||||
|     this._reporter.onStepEnd?.(test, result, step); | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return this._reporter.printsToStdio ? this._reporter.printsToStdio() : true; | ||||
|   } | ||||
|   _addSnippetToTestErrors(test, result) { | ||||
|     for (const error of result.errors) | ||||
|       addLocationAndSnippetToError(this._config, error, test.location.file); | ||||
|   } | ||||
|   _addSnippetToStepError(test, step) { | ||||
|     if (step.error) | ||||
|       addLocationAndSnippetToError(this._config, step.error, test.location.file); | ||||
|   } | ||||
| } | ||||
| function addLocationAndSnippetToError(config, error, file) { | ||||
|   if (error.stack && !error.location) | ||||
|     error.location = (0, import_base.prepareErrorStack)(error.stack).location; | ||||
|   const location = error.location; | ||||
|   if (!location) | ||||
|     return; | ||||
|   try { | ||||
|     const tokens = []; | ||||
|     const source = import_fs.default.readFileSync(location.file, "utf8"); | ||||
|     const codeFrame = (0, import_babelBundle.codeFrameColumns)(source, { start: location }, { highlightCode: true }); | ||||
|     if (!file || import_fs.default.realpathSync(file) !== location.file) { | ||||
|       tokens.push(import_base.internalScreen.colors.gray(`   at `) + `${(0, import_base.relativeFilePath)(import_base.internalScreen, config, location.file)}:${location.line}`); | ||||
|       tokens.push(""); | ||||
|     } | ||||
|     tokens.push(codeFrame); | ||||
|     error.snippet = tokens.join("\n"); | ||||
|   } catch (e) { | ||||
|   } | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   InternalReporter | ||||
| }); | ||||
							
								
								
									
										254
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/json.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/json.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,254 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var json_exports = {}; | ||||
| __export(json_exports, { | ||||
|   default: () => json_default, | ||||
|   serializePatterns: () => serializePatterns | ||||
| }); | ||||
| module.exports = __toCommonJS(json_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_base = require("./base"); | ||||
| var import_config = require("../common/config"); | ||||
| class JSONReporter { | ||||
|   constructor(options) { | ||||
|     this._errors = []; | ||||
|     this._resolvedOutputFile = (0, import_base.resolveOutputFile)("JSON", options)?.outputFile; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return !this._resolvedOutputFile; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this.config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this.suite = suite; | ||||
|   } | ||||
|   onError(error) { | ||||
|     this._errors.push(error); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     await outputReport(this._serializeReport(result), this._resolvedOutputFile); | ||||
|   } | ||||
|   _serializeReport(result) { | ||||
|     const report = { | ||||
|       config: { | ||||
|         ...removePrivateFields(this.config), | ||||
|         rootDir: (0, import_utils.toPosixPath)(this.config.rootDir), | ||||
|         projects: this.config.projects.map((project) => { | ||||
|           return { | ||||
|             outputDir: (0, import_utils.toPosixPath)(project.outputDir), | ||||
|             repeatEach: project.repeatEach, | ||||
|             retries: project.retries, | ||||
|             metadata: project.metadata, | ||||
|             id: (0, import_config.getProjectId)(project), | ||||
|             name: project.name, | ||||
|             testDir: (0, import_utils.toPosixPath)(project.testDir), | ||||
|             testIgnore: serializePatterns(project.testIgnore), | ||||
|             testMatch: serializePatterns(project.testMatch), | ||||
|             timeout: project.timeout | ||||
|           }; | ||||
|         }) | ||||
|       }, | ||||
|       suites: this._mergeSuites(this.suite.suites), | ||||
|       errors: this._errors, | ||||
|       stats: { | ||||
|         startTime: result.startTime.toISOString(), | ||||
|         duration: result.duration, | ||||
|         expected: 0, | ||||
|         skipped: 0, | ||||
|         unexpected: 0, | ||||
|         flaky: 0 | ||||
|       } | ||||
|     }; | ||||
|     for (const test of this.suite.allTests()) | ||||
|       ++report.stats[test.outcome()]; | ||||
|     return report; | ||||
|   } | ||||
|   _mergeSuites(suites) { | ||||
|     const fileSuites = new import_utils.MultiMap(); | ||||
|     for (const projectSuite of suites) { | ||||
|       const projectId = (0, import_config.getProjectId)(projectSuite.project()); | ||||
|       const projectName = projectSuite.project().name; | ||||
|       for (const fileSuite of projectSuite.suites) { | ||||
|         const file = fileSuite.location.file; | ||||
|         const serialized = this._serializeSuite(projectId, projectName, fileSuite); | ||||
|         if (serialized) | ||||
|           fileSuites.set(file, serialized); | ||||
|       } | ||||
|     } | ||||
|     const results = []; | ||||
|     for (const [, suites2] of fileSuites) { | ||||
|       const result = { | ||||
|         title: suites2[0].title, | ||||
|         file: suites2[0].file, | ||||
|         column: 0, | ||||
|         line: 0, | ||||
|         specs: [] | ||||
|       }; | ||||
|       for (const suite of suites2) | ||||
|         this._mergeTestsFromSuite(result, suite); | ||||
|       results.push(result); | ||||
|     } | ||||
|     return results; | ||||
|   } | ||||
|   _relativeLocation(location) { | ||||
|     if (!location) | ||||
|       return { file: "", line: 0, column: 0 }; | ||||
|     return { | ||||
|       file: (0, import_utils.toPosixPath)(import_path.default.relative(this.config.rootDir, location.file)), | ||||
|       line: location.line, | ||||
|       column: location.column | ||||
|     }; | ||||
|   } | ||||
|   _locationMatches(s1, s2) { | ||||
|     return s1.file === s2.file && s1.line === s2.line && s1.column === s2.column; | ||||
|   } | ||||
|   _mergeTestsFromSuite(to, from) { | ||||
|     for (const fromSuite of from.suites || []) { | ||||
|       const toSuite = (to.suites || []).find((s) => s.title === fromSuite.title && this._locationMatches(s, fromSuite)); | ||||
|       if (toSuite) { | ||||
|         this._mergeTestsFromSuite(toSuite, fromSuite); | ||||
|       } else { | ||||
|         if (!to.suites) | ||||
|           to.suites = []; | ||||
|         to.suites.push(fromSuite); | ||||
|       } | ||||
|     } | ||||
|     for (const spec of from.specs || []) { | ||||
|       const toSpec = to.specs.find((s) => s.title === spec.title && s.file === (0, import_utils.toPosixPath)(import_path.default.relative(this.config.rootDir, spec.file)) && s.line === spec.line && s.column === spec.column); | ||||
|       if (toSpec) | ||||
|         toSpec.tests.push(...spec.tests); | ||||
|       else | ||||
|         to.specs.push(spec); | ||||
|     } | ||||
|   } | ||||
|   _serializeSuite(projectId, projectName, suite) { | ||||
|     if (!suite.allTests().length) | ||||
|       return null; | ||||
|     const suites = suite.suites.map((suite2) => this._serializeSuite(projectId, projectName, suite2)).filter((s) => s); | ||||
|     return { | ||||
|       title: suite.title, | ||||
|       ...this._relativeLocation(suite.location), | ||||
|       specs: suite.tests.map((test) => this._serializeTestSpec(projectId, projectName, test)), | ||||
|       suites: suites.length ? suites : void 0 | ||||
|     }; | ||||
|   } | ||||
|   _serializeTestSpec(projectId, projectName, test) { | ||||
|     return { | ||||
|       title: test.title, | ||||
|       ok: test.ok(), | ||||
|       tags: test.tags.map((tag) => tag.substring(1)), | ||||
|       // Strip '@'. | ||||
|       tests: [this._serializeTest(projectId, projectName, test)], | ||||
|       id: test.id, | ||||
|       ...this._relativeLocation(test.location) | ||||
|     }; | ||||
|   } | ||||
|   _serializeTest(projectId, projectName, test) { | ||||
|     return { | ||||
|       timeout: test.timeout, | ||||
|       annotations: test.annotations, | ||||
|       expectedStatus: test.expectedStatus, | ||||
|       projectId, | ||||
|       projectName, | ||||
|       results: test.results.map((r) => this._serializeTestResult(r, test)), | ||||
|       status: test.outcome() | ||||
|     }; | ||||
|   } | ||||
|   _serializeTestResult(result, test) { | ||||
|     const steps = result.steps.filter((s) => s.category === "test.step"); | ||||
|     const jsonResult = { | ||||
|       workerIndex: result.workerIndex, | ||||
|       parallelIndex: result.parallelIndex, | ||||
|       status: result.status, | ||||
|       duration: result.duration, | ||||
|       error: result.error, | ||||
|       errors: result.errors.map((e) => this._serializeError(e)), | ||||
|       stdout: result.stdout.map((s) => stdioEntry(s)), | ||||
|       stderr: result.stderr.map((s) => stdioEntry(s)), | ||||
|       retry: result.retry, | ||||
|       steps: steps.length ? steps.map((s) => this._serializeTestStep(s)) : void 0, | ||||
|       startTime: result.startTime.toISOString(), | ||||
|       annotations: result.annotations, | ||||
|       attachments: result.attachments.map((a) => ({ | ||||
|         name: a.name, | ||||
|         contentType: a.contentType, | ||||
|         path: a.path, | ||||
|         body: a.body?.toString("base64") | ||||
|       })) | ||||
|     }; | ||||
|     if (result.error?.stack) | ||||
|       jsonResult.errorLocation = (0, import_base.prepareErrorStack)(result.error.stack).location; | ||||
|     return jsonResult; | ||||
|   } | ||||
|   _serializeError(error) { | ||||
|     return (0, import_base.formatError)(import_base.nonTerminalScreen, error); | ||||
|   } | ||||
|   _serializeTestStep(step) { | ||||
|     const steps = step.steps.filter((s) => s.category === "test.step"); | ||||
|     return { | ||||
|       title: step.title, | ||||
|       duration: step.duration, | ||||
|       error: step.error, | ||||
|       steps: steps.length ? steps.map((s) => this._serializeTestStep(s)) : void 0 | ||||
|     }; | ||||
|   } | ||||
| } | ||||
| async function outputReport(report, resolvedOutputFile) { | ||||
|   const reportString = JSON.stringify(report, void 0, 2); | ||||
|   if (resolvedOutputFile) { | ||||
|     await import_fs.default.promises.mkdir(import_path.default.dirname(resolvedOutputFile), { recursive: true }); | ||||
|     await import_fs.default.promises.writeFile(resolvedOutputFile, reportString); | ||||
|   } else { | ||||
|     console.log(reportString); | ||||
|   } | ||||
| } | ||||
| function stdioEntry(s) { | ||||
|   if (typeof s === "string") | ||||
|     return { text: s }; | ||||
|   return { buffer: s.toString("base64") }; | ||||
| } | ||||
| function removePrivateFields(config) { | ||||
|   return Object.fromEntries(Object.entries(config).filter(([name, value]) => !name.startsWith("_"))); | ||||
| } | ||||
| function serializePatterns(patterns) { | ||||
|   if (!Array.isArray(patterns)) | ||||
|     patterns = [patterns]; | ||||
|   return patterns.map((s) => s.toString()); | ||||
| } | ||||
| var json_default = JSONReporter; | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   serializePatterns | ||||
| }); | ||||
							
								
								
									
										230
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/junit.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/junit.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var junit_exports = {}; | ||||
| __export(junit_exports, { | ||||
|   default: () => junit_default | ||||
| }); | ||||
| module.exports = __toCommonJS(junit_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_base = require("./base"); | ||||
| var import_util = require("../util"); | ||||
| class JUnitReporter { | ||||
|   constructor(options) { | ||||
|     this.totalTests = 0; | ||||
|     this.totalFailures = 0; | ||||
|     this.totalSkipped = 0; | ||||
|     this.stripANSIControlSequences = false; | ||||
|     this.includeProjectInTestName = false; | ||||
|     this.stripANSIControlSequences = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_JUNIT_STRIP_ANSI", !!options.stripANSIControlSequences); | ||||
|     this.includeProjectInTestName = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME", !!options.includeProjectInTestName); | ||||
|     this.configDir = options.configDir; | ||||
|     this.resolvedOutputFile = (0, import_base.resolveOutputFile)("JUNIT", options)?.outputFile; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return !this.resolvedOutputFile; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this.config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this.suite = suite; | ||||
|     this.timestamp = /* @__PURE__ */ new Date(); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     const children = []; | ||||
|     for (const projectSuite of this.suite.suites) { | ||||
|       for (const fileSuite of projectSuite.suites) | ||||
|         children.push(await this._buildTestSuite(projectSuite.title, fileSuite)); | ||||
|     } | ||||
|     const tokens = []; | ||||
|     const self = this; | ||||
|     const root = { | ||||
|       name: "testsuites", | ||||
|       attributes: { | ||||
|         id: process.env[`PLAYWRIGHT_JUNIT_SUITE_ID`] || "", | ||||
|         name: process.env[`PLAYWRIGHT_JUNIT_SUITE_NAME`] || "", | ||||
|         tests: self.totalTests, | ||||
|         failures: self.totalFailures, | ||||
|         skipped: self.totalSkipped, | ||||
|         errors: 0, | ||||
|         time: result.duration / 1e3 | ||||
|       }, | ||||
|       children | ||||
|     }; | ||||
|     serializeXML(root, tokens, this.stripANSIControlSequences); | ||||
|     const reportString = tokens.join("\n"); | ||||
|     if (this.resolvedOutputFile) { | ||||
|       await import_fs.default.promises.mkdir(import_path.default.dirname(this.resolvedOutputFile), { recursive: true }); | ||||
|       await import_fs.default.promises.writeFile(this.resolvedOutputFile, reportString); | ||||
|     } else { | ||||
|       console.log(reportString); | ||||
|     } | ||||
|   } | ||||
|   async _buildTestSuite(projectName, suite) { | ||||
|     let tests = 0; | ||||
|     let skipped = 0; | ||||
|     let failures = 0; | ||||
|     let duration = 0; | ||||
|     const children = []; | ||||
|     const testCaseNamePrefix = projectName && this.includeProjectInTestName ? `[${projectName}] ` : ""; | ||||
|     for (const test of suite.allTests()) { | ||||
|       ++tests; | ||||
|       if (test.outcome() === "skipped") | ||||
|         ++skipped; | ||||
|       if (!test.ok()) | ||||
|         ++failures; | ||||
|       for (const result of test.results) | ||||
|         duration += result.duration; | ||||
|       await this._addTestCase(suite.title, testCaseNamePrefix, test, children); | ||||
|     } | ||||
|     this.totalTests += tests; | ||||
|     this.totalSkipped += skipped; | ||||
|     this.totalFailures += failures; | ||||
|     const entry = { | ||||
|       name: "testsuite", | ||||
|       attributes: { | ||||
|         name: suite.title, | ||||
|         timestamp: this.timestamp.toISOString(), | ||||
|         hostname: projectName, | ||||
|         tests, | ||||
|         failures, | ||||
|         skipped, | ||||
|         time: duration / 1e3, | ||||
|         errors: 0 | ||||
|       }, | ||||
|       children | ||||
|     }; | ||||
|     return entry; | ||||
|   } | ||||
|   async _addTestCase(suiteName, namePrefix, test, entries) { | ||||
|     const entry = { | ||||
|       name: "testcase", | ||||
|       attributes: { | ||||
|         // Skip root, project, file | ||||
|         name: namePrefix + test.titlePath().slice(3).join(" \u203A "), | ||||
|         // filename | ||||
|         classname: suiteName, | ||||
|         time: test.results.reduce((acc, value) => acc + value.duration, 0) / 1e3 | ||||
|       }, | ||||
|       children: [] | ||||
|     }; | ||||
|     entries.push(entry); | ||||
|     const properties = { | ||||
|       name: "properties", | ||||
|       children: [] | ||||
|     }; | ||||
|     for (const annotation of test.annotations) { | ||||
|       const property = { | ||||
|         name: "property", | ||||
|         attributes: { | ||||
|           name: annotation.type, | ||||
|           value: annotation?.description ? annotation.description : "" | ||||
|         } | ||||
|       }; | ||||
|       properties.children?.push(property); | ||||
|     } | ||||
|     if (properties.children?.length) | ||||
|       entry.children.push(properties); | ||||
|     if (test.outcome() === "skipped") { | ||||
|       entry.children.push({ name: "skipped" }); | ||||
|       return; | ||||
|     } | ||||
|     if (!test.ok()) { | ||||
|       entry.children.push({ | ||||
|         name: "failure", | ||||
|         attributes: { | ||||
|           message: `${import_path.default.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`, | ||||
|           type: "FAILURE" | ||||
|         }, | ||||
|         text: (0, import_util.stripAnsiEscapes)((0, import_base.formatFailure)(import_base.nonTerminalScreen, this.config, test)) | ||||
|       }); | ||||
|     } | ||||
|     const systemOut = []; | ||||
|     const systemErr = []; | ||||
|     for (const result of test.results) { | ||||
|       systemOut.push(...result.stdout.map((item) => item.toString())); | ||||
|       systemErr.push(...result.stderr.map((item) => item.toString())); | ||||
|       for (const attachment of result.attachments) { | ||||
|         if (!attachment.path) | ||||
|           continue; | ||||
|         let attachmentPath = import_path.default.relative(this.configDir, attachment.path); | ||||
|         try { | ||||
|           if (this.resolvedOutputFile) | ||||
|             attachmentPath = import_path.default.relative(import_path.default.dirname(this.resolvedOutputFile), attachment.path); | ||||
|         } catch { | ||||
|           systemOut.push(` | ||||
| Warning: Unable to make attachment path ${attachment.path} relative to report output file ${this.resolvedOutputFile}`); | ||||
|         } | ||||
|         try { | ||||
|           await import_fs.default.promises.access(attachment.path); | ||||
|           systemOut.push(` | ||||
| [[ATTACHMENT|${attachmentPath}]] | ||||
| `); | ||||
|         } catch { | ||||
|           systemErr.push(` | ||||
| Warning: attachment ${attachmentPath} is missing`); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if (systemOut.length) | ||||
|       entry.children.push({ name: "system-out", text: systemOut.join("") }); | ||||
|     if (systemErr.length) | ||||
|       entry.children.push({ name: "system-err", text: systemErr.join("") }); | ||||
|   } | ||||
| } | ||||
| function serializeXML(entry, tokens, stripANSIControlSequences) { | ||||
|   const attrs = []; | ||||
|   for (const [name, value] of Object.entries(entry.attributes || {})) | ||||
|     attrs.push(`${name}="${escape(String(value), stripANSIControlSequences, false)}"`); | ||||
|   tokens.push(`<${entry.name}${attrs.length ? " " : ""}${attrs.join(" ")}>`); | ||||
|   for (const child of entry.children || []) | ||||
|     serializeXML(child, tokens, stripANSIControlSequences); | ||||
|   if (entry.text) | ||||
|     tokens.push(escape(entry.text, stripANSIControlSequences, true)); | ||||
|   tokens.push(`</${entry.name}>`); | ||||
| } | ||||
| const discouragedXMLCharacters = /[\u0000-\u0008\u000b-\u000c\u000e-\u001f\u007f-\u0084\u0086-\u009f]/g; | ||||
| function escape(text, stripANSIControlSequences, isCharacterData) { | ||||
|   if (stripANSIControlSequences) | ||||
|     text = (0, import_util.stripAnsiEscapes)(text); | ||||
|   if (isCharacterData) { | ||||
|     text = "<![CDATA[" + text.replace(/]]>/g, "]]>") + "]]>"; | ||||
|   } else { | ||||
|     const escapeRe = /[&"'<>]/g; | ||||
|     text = text.replace(escapeRe, (c) => ({ "&": "&", '"': """, "'": "'", "<": "<", ">": ">" })[c]); | ||||
|   } | ||||
|   text = text.replace(discouragedXMLCharacters, ""); | ||||
|   return text; | ||||
| } | ||||
| var junit_default = JUnitReporter; | ||||
							
								
								
									
										113
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/line.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/line.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var line_exports = {}; | ||||
| __export(line_exports, { | ||||
|   default: () => line_default | ||||
| }); | ||||
| module.exports = __toCommonJS(line_exports); | ||||
| var import_base = require("./base"); | ||||
| class LineReporter extends import_base.TerminalReporter { | ||||
|   constructor() { | ||||
|     super(...arguments); | ||||
|     this._current = 0; | ||||
|     this._failures = 0; | ||||
|     this._didBegin = false; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     super.onBegin(suite); | ||||
|     const startingMessage = this.generateStartingMessage(); | ||||
|     if (startingMessage) { | ||||
|       this.writeLine(startingMessage); | ||||
|       this.writeLine(); | ||||
|     } | ||||
|     this._didBegin = true; | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     super.onStdOut(chunk, test, result); | ||||
|     this._dumpToStdio(test, chunk, this.screen.stdout); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     super.onStdErr(chunk, test, result); | ||||
|     this._dumpToStdio(test, chunk, this.screen.stderr); | ||||
|   } | ||||
|   _dumpToStdio(test, chunk, stream) { | ||||
|     if (this.config.quiet) | ||||
|       return; | ||||
|     if (!process.env.PW_TEST_DEBUG_REPORTERS) | ||||
|       stream.write(`\x1B[1A\x1B[2K`); | ||||
|     if (test && this._lastTest !== test) { | ||||
|       const title = this.screen.colors.dim(this.formatTestTitle(test)); | ||||
|       stream.write(this.fitToScreen(title) + ` | ||||
| `); | ||||
|       this._lastTest = test; | ||||
|     } | ||||
|     stream.write(chunk); | ||||
|     if (chunk[chunk.length - 1] !== "\n") | ||||
|       this.writeLine(); | ||||
|     this.writeLine(); | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     ++this._current; | ||||
|     this._updateLine(test, result, void 0); | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     if (this.screen.isTTY && step.category === "test.step") | ||||
|       this._updateLine(test, result, step); | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     if (this.screen.isTTY && step.category === "test.step") | ||||
|       this._updateLine(test, result, step.parent); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     super.onTestEnd(test, result); | ||||
|     if (!this.willRetry(test) && (test.outcome() === "flaky" || test.outcome() === "unexpected" || result.status === "interrupted")) { | ||||
|       if (!process.env.PW_TEST_DEBUG_REPORTERS) | ||||
|         this.screen.stdout.write(`\x1B[1A\x1B[2K`); | ||||
|       this.writeLine(this.formatFailure(test, ++this._failures)); | ||||
|       this.writeLine(); | ||||
|     } | ||||
|   } | ||||
|   _updateLine(test, result, step) { | ||||
|     const retriesPrefix = this.totalTestCount < this._current ? ` (retries)` : ``; | ||||
|     const prefix = `[${this._current}/${this.totalTestCount}]${retriesPrefix} `; | ||||
|     const currentRetrySuffix = result.retry ? this.screen.colors.yellow(` (retry #${result.retry})`) : ""; | ||||
|     const title = this.formatTestTitle(test, step) + currentRetrySuffix; | ||||
|     if (process.env.PW_TEST_DEBUG_REPORTERS) | ||||
|       this.screen.stdout.write(`${prefix + title} | ||||
| `); | ||||
|     else | ||||
|       this.screen.stdout.write(`\x1B[1A\x1B[2K${prefix + this.fitToScreen(title, prefix)} | ||||
| `); | ||||
|   } | ||||
|   onError(error) { | ||||
|     super.onError(error); | ||||
|     const message = this.formatError(error).message + "\n"; | ||||
|     if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin) | ||||
|       this.screen.stdout.write(`\x1B[1A\x1B[2K`); | ||||
|     this.screen.stdout.write(message); | ||||
|     this.writeLine(); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin) | ||||
|       this.screen.stdout.write(`\x1B[1A\x1B[2K`); | ||||
|     await super.onEnd(result); | ||||
|     this.epilogue(false); | ||||
|   } | ||||
| } | ||||
| var line_default = LineReporter; | ||||
							
								
								
									
										231
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/list.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/list.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var list_exports = {}; | ||||
| __export(list_exports, { | ||||
|   default: () => list_default | ||||
| }); | ||||
| module.exports = __toCommonJS(list_exports); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_utilsBundle = require("playwright-core/lib/utilsBundle"); | ||||
| var import_base = require("./base"); | ||||
| var import_util = require("../util"); | ||||
| const DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === "win32" && process.env.TERM_PROGRAM !== "vscode" && !process.env.WT_SESSION; | ||||
| const POSITIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "ok" : "\u2713"; | ||||
| const NEGATIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "x" : "\u2718"; | ||||
| class ListReporter extends import_base.TerminalReporter { | ||||
|   constructor(options) { | ||||
|     super(options); | ||||
|     this._lastRow = 0; | ||||
|     this._lastColumn = 0; | ||||
|     this._testRows = /* @__PURE__ */ new Map(); | ||||
|     this._stepRows = /* @__PURE__ */ new Map(); | ||||
|     this._resultIndex = /* @__PURE__ */ new Map(); | ||||
|     this._stepIndex = /* @__PURE__ */ new Map(); | ||||
|     this._needNewLine = false; | ||||
|     this._printSteps = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps); | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     super.onBegin(suite); | ||||
|     const startingMessage = this.generateStartingMessage(); | ||||
|     if (startingMessage) { | ||||
|       this.writeLine(startingMessage); | ||||
|       this.writeLine(""); | ||||
|     } | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     const index = String(this._resultIndex.size + 1); | ||||
|     this._resultIndex.set(result, index); | ||||
|     if (!this.screen.isTTY) | ||||
|       return; | ||||
|     this._maybeWriteNewLine(); | ||||
|     this._testRows.set(test, this._lastRow); | ||||
|     const prefix = this._testPrefix(index, ""); | ||||
|     const line = this.screen.colors.dim(this.formatTestTitle(test)) + this._retrySuffix(result); | ||||
|     this._appendLine(line, prefix); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     super.onStdOut(chunk, test, result); | ||||
|     this._dumpToStdio(test, chunk, this.screen.stdout); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     super.onStdErr(chunk, test, result); | ||||
|     this._dumpToStdio(test, chunk, this.screen.stderr); | ||||
|   } | ||||
|   getStepIndex(testIndex, result, step) { | ||||
|     if (this._stepIndex.has(step)) | ||||
|       return this._stepIndex.get(step); | ||||
|     const ordinal = (result[lastStepOrdinalSymbol] || 0) + 1; | ||||
|     result[lastStepOrdinalSymbol] = ordinal; | ||||
|     const stepIndex = `${testIndex}.${ordinal}`; | ||||
|     this._stepIndex.set(step, stepIndex); | ||||
|     return stepIndex; | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     if (step.category !== "test.step") | ||||
|       return; | ||||
|     const testIndex = this._resultIndex.get(result) || ""; | ||||
|     if (!this.screen.isTTY) | ||||
|       return; | ||||
|     if (this._printSteps) { | ||||
|       this._maybeWriteNewLine(); | ||||
|       this._stepRows.set(step, this._lastRow); | ||||
|       const prefix = this._testPrefix(this.getStepIndex(testIndex, result, step), ""); | ||||
|       const line = test.title + this.screen.colors.dim((0, import_base.stepSuffix)(step)); | ||||
|       this._appendLine(line, prefix); | ||||
|     } else { | ||||
|       this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step)) + this._retrySuffix(result), this._testPrefix(testIndex, "")); | ||||
|     } | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     if (step.category !== "test.step") | ||||
|       return; | ||||
|     const testIndex = this._resultIndex.get(result) || ""; | ||||
|     if (!this._printSteps) { | ||||
|       if (this.screen.isTTY) | ||||
|         this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step.parent)) + this._retrySuffix(result), this._testPrefix(testIndex, "")); | ||||
|       return; | ||||
|     } | ||||
|     const index = this.getStepIndex(testIndex, result, step); | ||||
|     const title = this.screen.isTTY ? test.title + this.screen.colors.dim((0, import_base.stepSuffix)(step)) : this.formatTestTitle(test, step); | ||||
|     const prefix = this._testPrefix(index, ""); | ||||
|     let text = ""; | ||||
|     if (step.error) | ||||
|       text = this.screen.colors.red(title); | ||||
|     else | ||||
|       text = title; | ||||
|     text += this.screen.colors.dim(` (${(0, import_utilsBundle.ms)(step.duration)})`); | ||||
|     this._updateOrAppendLine(this._stepRows, step, text, prefix); | ||||
|   } | ||||
|   _maybeWriteNewLine() { | ||||
|     if (this._needNewLine) { | ||||
|       this._needNewLine = false; | ||||
|       this.screen.stdout.write("\n"); | ||||
|       ++this._lastRow; | ||||
|       this._lastColumn = 0; | ||||
|     } | ||||
|   } | ||||
|   _updateLineCountAndNewLineFlagForOutput(text) { | ||||
|     this._needNewLine = text[text.length - 1] !== "\n"; | ||||
|     if (!this.screen.ttyWidth) | ||||
|       return; | ||||
|     for (const ch of text) { | ||||
|       if (ch === "\n") { | ||||
|         this._lastColumn = 0; | ||||
|         ++this._lastRow; | ||||
|         continue; | ||||
|       } | ||||
|       ++this._lastColumn; | ||||
|       if (this._lastColumn > this.screen.ttyWidth) { | ||||
|         this._lastColumn = 0; | ||||
|         ++this._lastRow; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   _dumpToStdio(test, chunk, stream) { | ||||
|     if (this.config.quiet) | ||||
|       return; | ||||
|     const text = chunk.toString("utf-8"); | ||||
|     this._updateLineCountAndNewLineFlagForOutput(text); | ||||
|     stream.write(chunk); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     super.onTestEnd(test, result); | ||||
|     const title = this.formatTestTitle(test); | ||||
|     let prefix = ""; | ||||
|     let text = ""; | ||||
|     let index = this._resultIndex.get(result); | ||||
|     if (!index) { | ||||
|       index = String(this._resultIndex.size + 1); | ||||
|       this._resultIndex.set(result, index); | ||||
|     } | ||||
|     if (result.status === "skipped") { | ||||
|       prefix = this._testPrefix(index, this.screen.colors.green("-")); | ||||
|       text = this.screen.colors.cyan(title) + this._retrySuffix(result); | ||||
|     } else { | ||||
|       const statusMark = result.status === "passed" ? POSITIVE_STATUS_MARK : NEGATIVE_STATUS_MARK; | ||||
|       if (result.status === test.expectedStatus) { | ||||
|         prefix = this._testPrefix(index, this.screen.colors.green(statusMark)); | ||||
|         text = title; | ||||
|       } else { | ||||
|         prefix = this._testPrefix(index, this.screen.colors.red(statusMark)); | ||||
|         text = this.screen.colors.red(title); | ||||
|       } | ||||
|       text += this._retrySuffix(result) + this.screen.colors.dim(` (${(0, import_utilsBundle.ms)(result.duration)})`); | ||||
|     } | ||||
|     this._updateOrAppendLine(this._testRows, test, text, prefix); | ||||
|   } | ||||
|   _updateOrAppendLine(entityRowNumbers, entity, text, prefix) { | ||||
|     const row = entityRowNumbers.get(entity); | ||||
|     if (row !== void 0 && this.screen.isTTY && this._lastRow - row < this.screen.ttyHeight) { | ||||
|       this._updateLine(row, text, prefix); | ||||
|     } else { | ||||
|       this._maybeWriteNewLine(); | ||||
|       entityRowNumbers.set(entity, this._lastRow); | ||||
|       this._appendLine(text, prefix); | ||||
|     } | ||||
|   } | ||||
|   _appendLine(text, prefix) { | ||||
|     const line = prefix + this.fitToScreen(text, prefix); | ||||
|     if (process.env.PW_TEST_DEBUG_REPORTERS) { | ||||
|       this.screen.stdout.write("#" + this._lastRow + " : " + line + "\n"); | ||||
|     } else { | ||||
|       this.screen.stdout.write(line); | ||||
|       this.screen.stdout.write("\n"); | ||||
|     } | ||||
|     ++this._lastRow; | ||||
|     this._lastColumn = 0; | ||||
|   } | ||||
|   _updateLine(row, text, prefix) { | ||||
|     const line = prefix + this.fitToScreen(text, prefix); | ||||
|     if (process.env.PW_TEST_DEBUG_REPORTERS) | ||||
|       this.screen.stdout.write("#" + row + " : " + line + "\n"); | ||||
|     else | ||||
|       this._updateLineForTTY(row, line); | ||||
|   } | ||||
|   _updateLineForTTY(row, line) { | ||||
|     if (row !== this._lastRow) | ||||
|       this.screen.stdout.write(`\x1B[${this._lastRow - row}A`); | ||||
|     this.screen.stdout.write("\x1B[2K\x1B[0G"); | ||||
|     this.screen.stdout.write(line); | ||||
|     if (row !== this._lastRow) | ||||
|       this.screen.stdout.write(`\x1B[${this._lastRow - row}E`); | ||||
|   } | ||||
|   _testPrefix(index, statusMark) { | ||||
|     const statusMarkLength = (0, import_util.stripAnsiEscapes)(statusMark).length; | ||||
|     const indexLength = Math.ceil(Math.log10(this.totalTestCount + 1)); | ||||
|     return "  " + statusMark + " ".repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + " "); | ||||
|   } | ||||
|   _retrySuffix(result) { | ||||
|     return result.retry ? this.screen.colors.yellow(` (retry #${result.retry})`) : ""; | ||||
|   } | ||||
|   onError(error) { | ||||
|     super.onError(error); | ||||
|     this._maybeWriteNewLine(); | ||||
|     const message = this.formatError(error).message + "\n"; | ||||
|     this._updateLineCountAndNewLineFlagForOutput(message); | ||||
|     this.screen.stdout.write(message); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     await super.onEnd(result); | ||||
|     this.screen.stdout.write("\n"); | ||||
|     this.epilogue(true); | ||||
|   } | ||||
| } | ||||
| const lastStepOrdinalSymbol = Symbol("lastStepOrdinal"); | ||||
| var list_default = ListReporter; | ||||
							
								
								
									
										66
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/listModeReporter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/listModeReporter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var listModeReporter_exports = {}; | ||||
| __export(listModeReporter_exports, { | ||||
|   default: () => listModeReporter_default | ||||
| }); | ||||
| module.exports = __toCommonJS(listModeReporter_exports); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_base = require("./base"); | ||||
| class ListModeReporter { | ||||
|   constructor(options) { | ||||
|     this.screen = options?.screen ?? import_base.terminalScreen; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this.config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this._writeLine(`Listing tests:`); | ||||
|     const tests = suite.allTests(); | ||||
|     const files = /* @__PURE__ */ new Set(); | ||||
|     for (const test of tests) { | ||||
|       const [, projectName, , ...titles] = test.titlePath(); | ||||
|       const location = `${import_path.default.relative(this.config.rootDir, test.location.file)}:${test.location.line}:${test.location.column}`; | ||||
|       const projectTitle = projectName ? `[${projectName}] \u203A ` : ""; | ||||
|       this._writeLine(`  ${projectTitle}${location} \u203A ${titles.join(" \u203A ")}`); | ||||
|       files.add(test.location.file); | ||||
|     } | ||||
|     this._writeLine(`Total: ${tests.length} ${tests.length === 1 ? "test" : "tests"} in ${files.size} ${files.size === 1 ? "file" : "files"}`); | ||||
|   } | ||||
|   onError(error) { | ||||
|     this.screen.stderr.write("\n" + (0, import_base.formatError)(import_base.terminalScreen, error).message + "\n"); | ||||
|   } | ||||
|   _writeLine(line) { | ||||
|     this.screen.stdout.write(line + "\n"); | ||||
|   } | ||||
| } | ||||
| var listModeReporter_default = ListModeReporter; | ||||
							
								
								
									
										144
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/markdown.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/markdown.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var markdown_exports = {}; | ||||
| __export(markdown_exports, { | ||||
|   default: () => markdown_default | ||||
| }); | ||||
| module.exports = __toCommonJS(markdown_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| class MarkdownReporter { | ||||
|   constructor(options) { | ||||
|     this._fatalErrors = []; | ||||
|     this._options = options; | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return false; | ||||
|   } | ||||
|   onBegin(config, suite) { | ||||
|     this._config = config; | ||||
|     this._suite = suite; | ||||
|   } | ||||
|   onError(error) { | ||||
|     this._fatalErrors.push(error); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     const summary = this._generateSummary(); | ||||
|     const lines = []; | ||||
|     if (this._fatalErrors.length) | ||||
|       lines.push(`**${this._fatalErrors.length} fatal errors, not part of any test**`); | ||||
|     if (summary.unexpected.length) { | ||||
|       lines.push(`**${summary.unexpected.length} failed**`); | ||||
|       this._printTestList(":x:", summary.unexpected, lines); | ||||
|     } | ||||
|     if (summary.flaky.length) { | ||||
|       lines.push(`<details>`); | ||||
|       lines.push(`<summary><b>${summary.flaky.length} flaky</b></summary>`); | ||||
|       this._printTestList(":warning:", summary.flaky, lines, " <br/>"); | ||||
|       lines.push(`</details>`); | ||||
|       lines.push(``); | ||||
|     } | ||||
|     if (summary.interrupted.length) { | ||||
|       lines.push(`<details>`); | ||||
|       lines.push(`<summary><b>${summary.interrupted.length} interrupted</b></summary>`); | ||||
|       this._printTestList(":warning:", summary.interrupted, lines, " <br/>"); | ||||
|       lines.push(`</details>`); | ||||
|       lines.push(``); | ||||
|     } | ||||
|     const skipped = summary.skipped ? `, ${summary.skipped} skipped` : ""; | ||||
|     const didNotRun = summary.didNotRun ? `, ${summary.didNotRun} did not run` : ""; | ||||
|     lines.push(`**${summary.expected} passed${skipped}${didNotRun}**`); | ||||
|     lines.push(``); | ||||
|     await this.publishReport(lines.join("\n")); | ||||
|   } | ||||
|   async publishReport(report) { | ||||
|     const maybeRelativeFile = this._options.outputFile || "report.md"; | ||||
|     const reportFile = import_path.default.resolve(this._options.configDir, maybeRelativeFile); | ||||
|     await import_fs.default.promises.mkdir(import_path.default.dirname(reportFile), { recursive: true }); | ||||
|     await import_fs.default.promises.writeFile(reportFile, report); | ||||
|   } | ||||
|   _generateSummary() { | ||||
|     let didNotRun = 0; | ||||
|     let skipped = 0; | ||||
|     let expected = 0; | ||||
|     const interrupted = []; | ||||
|     const interruptedToPrint = []; | ||||
|     const unexpected = []; | ||||
|     const flaky = []; | ||||
|     this._suite.allTests().forEach((test) => { | ||||
|       switch (test.outcome()) { | ||||
|         case "skipped": { | ||||
|           if (test.results.some((result) => result.status === "interrupted")) { | ||||
|             if (test.results.some((result) => !!result.error)) | ||||
|               interruptedToPrint.push(test); | ||||
|             interrupted.push(test); | ||||
|           } else if (!test.results.length || test.expectedStatus !== "skipped") { | ||||
|             ++didNotRun; | ||||
|           } else { | ||||
|             ++skipped; | ||||
|           } | ||||
|           break; | ||||
|         } | ||||
|         case "expected": | ||||
|           ++expected; | ||||
|           break; | ||||
|         case "unexpected": | ||||
|           unexpected.push(test); | ||||
|           break; | ||||
|         case "flaky": | ||||
|           flaky.push(test); | ||||
|           break; | ||||
|       } | ||||
|     }); | ||||
|     return { | ||||
|       didNotRun, | ||||
|       skipped, | ||||
|       expected, | ||||
|       interrupted, | ||||
|       unexpected, | ||||
|       flaky | ||||
|     }; | ||||
|   } | ||||
|   _printTestList(prefix, tests, lines, suffix) { | ||||
|     for (const test of tests) | ||||
|       lines.push(`${prefix} ${formatTestTitle(this._config.rootDir, test)}${suffix || ""}`); | ||||
|     lines.push(``); | ||||
|   } | ||||
| } | ||||
| function formatTestTitle(rootDir, test) { | ||||
|   const [, projectName, , ...titles] = test.titlePath(); | ||||
|   const relativeTestPath = import_path.default.relative(rootDir, test.location.file); | ||||
|   const location = `${relativeTestPath}:${test.location.line}`; | ||||
|   const projectTitle = projectName ? `[${projectName}] \u203A ` : ""; | ||||
|   const testTitle = `${projectTitle}${location} \u203A ${titles.join(" \u203A ")}`; | ||||
|   const extraTags = test.tags.filter((t) => !testTitle.includes(t)); | ||||
|   const formattedTags = extraTags.map((t) => `\`${t}\``).join(" "); | ||||
|   return `${testTitle}${extraTags.length ? " " + formattedTags : ""}`; | ||||
| } | ||||
| var markdown_default = MarkdownReporter; | ||||
							
								
								
									
										533
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/merge.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										533
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/merge.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,533 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var merge_exports = {}; | ||||
| __export(merge_exports, { | ||||
|   createMergedReport: () => createMergedReport | ||||
| }); | ||||
| module.exports = __toCommonJS(merge_exports); | ||||
| var import_fs = __toESM(require("fs")); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_blob = require("./blob"); | ||||
| var import_multiplexer = require("./multiplexer"); | ||||
| var import_stringInternPool = require("../isomorphic/stringInternPool"); | ||||
| var import_teleReceiver = require("../isomorphic/teleReceiver"); | ||||
| var import_reporters = require("../runner/reporters"); | ||||
| var import_util = require("../util"); | ||||
| async function createMergedReport(config, dir, reporterDescriptions, rootDirOverride) { | ||||
|   const reporters = await (0, import_reporters.createReporters)(config, "merge", false, reporterDescriptions); | ||||
|   const multiplexer = new import_multiplexer.Multiplexer(reporters); | ||||
|   const stringPool = new import_stringInternPool.StringInternPool(); | ||||
|   let printStatus = () => { | ||||
|   }; | ||||
|   if (!multiplexer.printsToStdio()) { | ||||
|     printStatus = printStatusToStdout; | ||||
|     printStatus(`merging reports from ${dir}`); | ||||
|   } | ||||
|   const shardFiles = await sortedShardFiles(dir); | ||||
|   if (shardFiles.length === 0) | ||||
|     throw new Error(`No report files found in ${dir}`); | ||||
|   const eventData = await mergeEvents(dir, shardFiles, stringPool, printStatus, rootDirOverride); | ||||
|   const pathSeparator = rootDirOverride ? import_path.default.sep : eventData.pathSeparatorFromMetadata ?? import_path.default.sep; | ||||
|   const receiver = new import_teleReceiver.TeleReporterReceiver(multiplexer, { | ||||
|     mergeProjects: false, | ||||
|     mergeTestCases: false, | ||||
|     resolvePath: (rootDir, relativePath) => stringPool.internString(rootDir + pathSeparator + relativePath), | ||||
|     configOverrides: config.config | ||||
|   }); | ||||
|   printStatus(`processing test events`); | ||||
|   const dispatchEvents = async (events) => { | ||||
|     for (const event of events) { | ||||
|       if (event.method === "onEnd") | ||||
|         printStatus(`building final report`); | ||||
|       await receiver.dispatch(event); | ||||
|       if (event.method === "onEnd") | ||||
|         printStatus(`finished building report`); | ||||
|     } | ||||
|   }; | ||||
|   await dispatchEvents(eventData.prologue); | ||||
|   for (const { reportFile, eventPatchers, metadata } of eventData.reports) { | ||||
|     const reportJsonl = await import_fs.default.promises.readFile(reportFile); | ||||
|     const events = parseTestEvents(reportJsonl); | ||||
|     new import_stringInternPool.JsonStringInternalizer(stringPool).traverse(events); | ||||
|     eventPatchers.patchers.push(new AttachmentPathPatcher(dir)); | ||||
|     if (metadata.name) | ||||
|       eventPatchers.patchers.push(new GlobalErrorPatcher(metadata.name)); | ||||
|     eventPatchers.patchEvents(events); | ||||
|     await dispatchEvents(events); | ||||
|   } | ||||
|   await dispatchEvents(eventData.epilogue); | ||||
| } | ||||
| const commonEventNames = ["onBlobReportMetadata", "onConfigure", "onProject", "onBegin", "onEnd"]; | ||||
| const commonEvents = new Set(commonEventNames); | ||||
| const commonEventRegex = new RegExp(`${commonEventNames.join("|")}`); | ||||
| function parseCommonEvents(reportJsonl) { | ||||
|   return splitBufferLines(reportJsonl).map((line) => line.toString("utf8")).filter((line) => commonEventRegex.test(line)).map((line) => JSON.parse(line)).filter((event) => commonEvents.has(event.method)); | ||||
| } | ||||
| function parseTestEvents(reportJsonl) { | ||||
|   return splitBufferLines(reportJsonl).map((line) => line.toString("utf8")).filter((line) => line.length).map((line) => JSON.parse(line)).filter((event) => !commonEvents.has(event.method)); | ||||
| } | ||||
| function splitBufferLines(buffer) { | ||||
|   const lines = []; | ||||
|   let start = 0; | ||||
|   while (start < buffer.length) { | ||||
|     const end = buffer.indexOf(10, start); | ||||
|     if (end === -1) { | ||||
|       lines.push(buffer.slice(start)); | ||||
|       break; | ||||
|     } | ||||
|     lines.push(buffer.slice(start, end)); | ||||
|     start = end + 1; | ||||
|   } | ||||
|   return lines; | ||||
| } | ||||
| async function extractAndParseReports(dir, shardFiles, internalizer, printStatus) { | ||||
|   const shardEvents = []; | ||||
|   await import_fs.default.promises.mkdir(import_path.default.join(dir, "resources"), { recursive: true }); | ||||
|   const reportNames = new UniqueFileNameGenerator(); | ||||
|   for (const file of shardFiles) { | ||||
|     const absolutePath = import_path.default.join(dir, file); | ||||
|     printStatus(`extracting: ${(0, import_util.relativeFilePath)(absolutePath)}`); | ||||
|     const zipFile = new import_utils.ZipFile(absolutePath); | ||||
|     const entryNames = await zipFile.entries(); | ||||
|     for (const entryName of entryNames.sort()) { | ||||
|       let fileName = import_path.default.join(dir, entryName); | ||||
|       const content = await zipFile.read(entryName); | ||||
|       if (entryName.endsWith(".jsonl")) { | ||||
|         fileName = reportNames.makeUnique(fileName); | ||||
|         let parsedEvents = parseCommonEvents(content); | ||||
|         internalizer.traverse(parsedEvents); | ||||
|         const metadata = findMetadata(parsedEvents, file); | ||||
|         parsedEvents = modernizer.modernize(metadata.version, parsedEvents); | ||||
|         shardEvents.push({ | ||||
|           file, | ||||
|           localPath: fileName, | ||||
|           metadata, | ||||
|           parsedEvents | ||||
|         }); | ||||
|       } | ||||
|       await import_fs.default.promises.writeFile(fileName, content); | ||||
|     } | ||||
|     zipFile.close(); | ||||
|   } | ||||
|   return shardEvents; | ||||
| } | ||||
| function findMetadata(events, file) { | ||||
|   if (events[0]?.method !== "onBlobReportMetadata") | ||||
|     throw new Error(`No metadata event found in ${file}`); | ||||
|   const metadata = events[0].params; | ||||
|   if (metadata.version > import_blob.currentBlobReportVersion) | ||||
|     throw new Error(`Blob report ${file} was created with a newer version of Playwright.`); | ||||
|   return metadata; | ||||
| } | ||||
| async function mergeEvents(dir, shardReportFiles, stringPool, printStatus, rootDirOverride) { | ||||
|   const internalizer = new import_stringInternPool.JsonStringInternalizer(stringPool); | ||||
|   const configureEvents = []; | ||||
|   const projectEvents = []; | ||||
|   const endEvents = []; | ||||
|   const blobs = await extractAndParseReports(dir, shardReportFiles, internalizer, printStatus); | ||||
|   blobs.sort((a, b) => { | ||||
|     const nameA = a.metadata.name ?? ""; | ||||
|     const nameB = b.metadata.name ?? ""; | ||||
|     if (nameA !== nameB) | ||||
|       return nameA.localeCompare(nameB); | ||||
|     const shardA = a.metadata.shard?.current ?? 0; | ||||
|     const shardB = b.metadata.shard?.current ?? 0; | ||||
|     if (shardA !== shardB) | ||||
|       return shardA - shardB; | ||||
|     return a.file.localeCompare(b.file); | ||||
|   }); | ||||
|   printStatus(`merging events`); | ||||
|   const reports = []; | ||||
|   const globalTestIdSet = /* @__PURE__ */ new Set(); | ||||
|   for (let i = 0; i < blobs.length; ++i) { | ||||
|     const { parsedEvents, metadata, localPath } = blobs[i]; | ||||
|     const eventPatchers = new JsonEventPatchers(); | ||||
|     eventPatchers.patchers.push(new IdsPatcher( | ||||
|       stringPool, | ||||
|       metadata.name, | ||||
|       String(i), | ||||
|       globalTestIdSet | ||||
|     )); | ||||
|     if (rootDirOverride) | ||||
|       eventPatchers.patchers.push(new PathSeparatorPatcher(metadata.pathSeparator)); | ||||
|     eventPatchers.patchEvents(parsedEvents); | ||||
|     for (const event of parsedEvents) { | ||||
|       if (event.method === "onConfigure") | ||||
|         configureEvents.push(event); | ||||
|       else if (event.method === "onProject") | ||||
|         projectEvents.push(event); | ||||
|       else if (event.method === "onEnd") | ||||
|         endEvents.push(event); | ||||
|     } | ||||
|     reports.push({ | ||||
|       eventPatchers, | ||||
|       reportFile: localPath, | ||||
|       metadata | ||||
|     }); | ||||
|   } | ||||
|   return { | ||||
|     prologue: [ | ||||
|       mergeConfigureEvents(configureEvents, rootDirOverride), | ||||
|       ...projectEvents, | ||||
|       { method: "onBegin", params: void 0 } | ||||
|     ], | ||||
|     reports, | ||||
|     epilogue: [ | ||||
|       mergeEndEvents(endEvents), | ||||
|       { method: "onExit", params: void 0 } | ||||
|     ], | ||||
|     pathSeparatorFromMetadata: blobs[0]?.metadata.pathSeparator | ||||
|   }; | ||||
| } | ||||
| function mergeConfigureEvents(configureEvents, rootDirOverride) { | ||||
|   if (!configureEvents.length) | ||||
|     throw new Error("No configure events found"); | ||||
|   let config = { | ||||
|     configFile: void 0, | ||||
|     globalTimeout: 0, | ||||
|     maxFailures: 0, | ||||
|     metadata: {}, | ||||
|     rootDir: "", | ||||
|     version: "", | ||||
|     workers: 0 | ||||
|   }; | ||||
|   for (const event of configureEvents) | ||||
|     config = mergeConfigs(config, event.params.config); | ||||
|   if (rootDirOverride) { | ||||
|     config.rootDir = rootDirOverride; | ||||
|   } else { | ||||
|     const rootDirs = new Set(configureEvents.map((e) => e.params.config.rootDir)); | ||||
|     if (rootDirs.size > 1) { | ||||
|       throw new Error([ | ||||
|         `Blob reports being merged were recorded with different test directories, and`, | ||||
|         `merging cannot proceed. This may happen if you are merging reports from`, | ||||
|         `machines with different environments, like different operating systems or`, | ||||
|         `if the tests ran with different playwright configs.`, | ||||
|         ``, | ||||
|         `You can force merge by specifying a merge config file with "-c" option. If`, | ||||
|         `you'd like all test paths to be correct, make sure 'testDir' in the merge config`, | ||||
|         `file points to the actual tests location.`, | ||||
|         ``, | ||||
|         `Found directories:`, | ||||
|         ...rootDirs | ||||
|       ].join("\n")); | ||||
|     } | ||||
|   } | ||||
|   return { | ||||
|     method: "onConfigure", | ||||
|     params: { | ||||
|       config | ||||
|     } | ||||
|   }; | ||||
| } | ||||
| function mergeConfigs(to, from) { | ||||
|   return { | ||||
|     ...to, | ||||
|     ...from, | ||||
|     metadata: { | ||||
|       ...to.metadata, | ||||
|       ...from.metadata, | ||||
|       actualWorkers: (to.metadata.actualWorkers || 0) + (from.metadata.actualWorkers || 0) | ||||
|     }, | ||||
|     workers: to.workers + from.workers | ||||
|   }; | ||||
| } | ||||
| function mergeEndEvents(endEvents) { | ||||
|   let startTime = endEvents.length ? 1e13 : Date.now(); | ||||
|   let status = "passed"; | ||||
|   let duration = 0; | ||||
|   for (const event of endEvents) { | ||||
|     const shardResult = event.params.result; | ||||
|     if (shardResult.status === "failed") | ||||
|       status = "failed"; | ||||
|     else if (shardResult.status === "timedout" && status !== "failed") | ||||
|       status = "timedout"; | ||||
|     else if (shardResult.status === "interrupted" && status !== "failed" && status !== "timedout") | ||||
|       status = "interrupted"; | ||||
|     startTime = Math.min(startTime, shardResult.startTime); | ||||
|     duration = Math.max(duration, shardResult.duration); | ||||
|   } | ||||
|   const result = { | ||||
|     status, | ||||
|     startTime, | ||||
|     duration | ||||
|   }; | ||||
|   return { | ||||
|     method: "onEnd", | ||||
|     params: { | ||||
|       result | ||||
|     } | ||||
|   }; | ||||
| } | ||||
| async function sortedShardFiles(dir) { | ||||
|   const files = await import_fs.default.promises.readdir(dir); | ||||
|   return files.filter((file) => file.endsWith(".zip")).sort(); | ||||
| } | ||||
| function printStatusToStdout(message) { | ||||
|   process.stdout.write(`${message} | ||||
| `); | ||||
| } | ||||
| class UniqueFileNameGenerator { | ||||
|   constructor() { | ||||
|     this._usedNames = /* @__PURE__ */ new Set(); | ||||
|   } | ||||
|   makeUnique(name) { | ||||
|     if (!this._usedNames.has(name)) { | ||||
|       this._usedNames.add(name); | ||||
|       return name; | ||||
|     } | ||||
|     const extension = import_path.default.extname(name); | ||||
|     name = name.substring(0, name.length - extension.length); | ||||
|     let index = 0; | ||||
|     while (true) { | ||||
|       const candidate = `${name}-${++index}${extension}`; | ||||
|       if (!this._usedNames.has(candidate)) { | ||||
|         this._usedNames.add(candidate); | ||||
|         return candidate; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| class IdsPatcher { | ||||
|   constructor(stringPool, botName, salt, globalTestIdSet) { | ||||
|     this._stringPool = stringPool; | ||||
|     this._botName = botName; | ||||
|     this._salt = salt; | ||||
|     this._testIdsMap = /* @__PURE__ */ new Map(); | ||||
|     this._globalTestIdSet = globalTestIdSet; | ||||
|   } | ||||
|   patchEvent(event) { | ||||
|     const { method, params } = event; | ||||
|     switch (method) { | ||||
|       case "onProject": | ||||
|         this._onProject(params.project); | ||||
|         return; | ||||
|       case "onAttach": | ||||
|       case "onTestBegin": | ||||
|       case "onStepBegin": | ||||
|       case "onStepEnd": | ||||
|       case "onStdIO": | ||||
|         params.testId = params.testId ? this._mapTestId(params.testId) : void 0; | ||||
|         return; | ||||
|       case "onTestEnd": | ||||
|         params.test.testId = this._mapTestId(params.test.testId); | ||||
|         return; | ||||
|     } | ||||
|   } | ||||
|   _onProject(project) { | ||||
|     project.metadata ??= {}; | ||||
|     project.suites.forEach((suite) => this._updateTestIds(suite)); | ||||
|   } | ||||
|   _updateTestIds(suite) { | ||||
|     suite.entries.forEach((entry) => { | ||||
|       if ("testId" in entry) | ||||
|         this._updateTestId(entry); | ||||
|       else | ||||
|         this._updateTestIds(entry); | ||||
|     }); | ||||
|   } | ||||
|   _updateTestId(test) { | ||||
|     test.testId = this._mapTestId(test.testId); | ||||
|     if (this._botName) { | ||||
|       test.tags = test.tags || []; | ||||
|       test.tags.unshift("@" + this._botName); | ||||
|     } | ||||
|   } | ||||
|   _mapTestId(testId) { | ||||
|     const t1 = this._stringPool.internString(testId); | ||||
|     if (this._testIdsMap.has(t1)) | ||||
|       return this._testIdsMap.get(t1); | ||||
|     if (this._globalTestIdSet.has(t1)) { | ||||
|       const t2 = this._stringPool.internString(testId + this._salt); | ||||
|       this._globalTestIdSet.add(t2); | ||||
|       this._testIdsMap.set(t1, t2); | ||||
|       return t2; | ||||
|     } | ||||
|     this._globalTestIdSet.add(t1); | ||||
|     this._testIdsMap.set(t1, t1); | ||||
|     return t1; | ||||
|   } | ||||
| } | ||||
| class AttachmentPathPatcher { | ||||
|   constructor(_resourceDir) { | ||||
|     this._resourceDir = _resourceDir; | ||||
|   } | ||||
|   patchEvent(event) { | ||||
|     if (event.method === "onAttach") | ||||
|       this._patchAttachments(event.params.attachments); | ||||
|     else if (event.method === "onTestEnd") | ||||
|       this._patchAttachments(event.params.result.attachments ?? []); | ||||
|   } | ||||
|   _patchAttachments(attachments) { | ||||
|     for (const attachment of attachments) { | ||||
|       if (!attachment.path) | ||||
|         continue; | ||||
|       attachment.path = import_path.default.join(this._resourceDir, attachment.path); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| class PathSeparatorPatcher { | ||||
|   constructor(from) { | ||||
|     this._from = from ?? (import_path.default.sep === "/" ? "\\" : "/"); | ||||
|     this._to = import_path.default.sep; | ||||
|   } | ||||
|   patchEvent(jsonEvent) { | ||||
|     if (this._from === this._to) | ||||
|       return; | ||||
|     if (jsonEvent.method === "onProject") { | ||||
|       this._updateProject(jsonEvent.params.project); | ||||
|       return; | ||||
|     } | ||||
|     if (jsonEvent.method === "onTestEnd") { | ||||
|       const test = jsonEvent.params.test; | ||||
|       test.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation)); | ||||
|       const testResult = jsonEvent.params.result; | ||||
|       testResult.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation)); | ||||
|       testResult.errors.forEach((error) => this._updateErrorLocations(error)); | ||||
|       (testResult.attachments ?? []).forEach((attachment) => { | ||||
|         if (attachment.path) | ||||
|           attachment.path = this._updatePath(attachment.path); | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|     if (jsonEvent.method === "onStepBegin") { | ||||
|       const step = jsonEvent.params.step; | ||||
|       this._updateLocation(step.location); | ||||
|       return; | ||||
|     } | ||||
|     if (jsonEvent.method === "onStepEnd") { | ||||
|       const step = jsonEvent.params.step; | ||||
|       this._updateErrorLocations(step.error); | ||||
|       step.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation)); | ||||
|       return; | ||||
|     } | ||||
|     if (jsonEvent.method === "onAttach") { | ||||
|       const attach = jsonEvent.params; | ||||
|       attach.attachments.forEach((attachment) => { | ||||
|         if (attachment.path) | ||||
|           attachment.path = this._updatePath(attachment.path); | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
|   _updateProject(project) { | ||||
|     project.outputDir = this._updatePath(project.outputDir); | ||||
|     project.testDir = this._updatePath(project.testDir); | ||||
|     project.snapshotDir = this._updatePath(project.snapshotDir); | ||||
|     project.suites.forEach((suite) => this._updateSuite(suite, true)); | ||||
|   } | ||||
|   _updateSuite(suite, isFileSuite = false) { | ||||
|     this._updateLocation(suite.location); | ||||
|     if (isFileSuite) | ||||
|       suite.title = this._updatePath(suite.title); | ||||
|     for (const entry of suite.entries) { | ||||
|       if ("testId" in entry) { | ||||
|         this._updateLocation(entry.location); | ||||
|         entry.annotations?.forEach((annotation) => this._updateAnnotationLocation(annotation)); | ||||
|       } else { | ||||
|         this._updateSuite(entry); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   _updateErrorLocations(error) { | ||||
|     while (error) { | ||||
|       this._updateLocation(error.location); | ||||
|       error = error.cause; | ||||
|     } | ||||
|   } | ||||
|   _updateAnnotationLocation(annotation) { | ||||
|     this._updateLocation(annotation.location); | ||||
|   } | ||||
|   _updateLocation(location) { | ||||
|     if (location) | ||||
|       location.file = this._updatePath(location.file); | ||||
|   } | ||||
|   _updatePath(text) { | ||||
|     return text.split(this._from).join(this._to); | ||||
|   } | ||||
| } | ||||
| class GlobalErrorPatcher { | ||||
|   constructor(botName) { | ||||
|     this._prefix = `(${botName}) `; | ||||
|   } | ||||
|   patchEvent(event) { | ||||
|     if (event.method !== "onError") | ||||
|       return; | ||||
|     const error = event.params.error; | ||||
|     if (error.message !== void 0) | ||||
|       error.message = this._prefix + error.message; | ||||
|     if (error.stack !== void 0) | ||||
|       error.stack = this._prefix + error.stack; | ||||
|   } | ||||
| } | ||||
| class JsonEventPatchers { | ||||
|   constructor() { | ||||
|     this.patchers = []; | ||||
|   } | ||||
|   patchEvents(events) { | ||||
|     for (const event of events) { | ||||
|       for (const patcher of this.patchers) | ||||
|         patcher.patchEvent(event); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| class BlobModernizer { | ||||
|   modernize(fromVersion, events) { | ||||
|     const result = []; | ||||
|     for (const event of events) | ||||
|       result.push(...this._modernize(fromVersion, event)); | ||||
|     return result; | ||||
|   } | ||||
|   _modernize(fromVersion, event) { | ||||
|     let events = [event]; | ||||
|     for (let version = fromVersion; version < import_blob.currentBlobReportVersion; ++version) | ||||
|       events = this[`_modernize_${version}_to_${version + 1}`].call(this, events); | ||||
|     return events; | ||||
|   } | ||||
|   _modernize_1_to_2(events) { | ||||
|     return events.map((event) => { | ||||
|       if (event.method === "onProject") { | ||||
|         const modernizeSuite = (suite) => { | ||||
|           const newSuites = suite.suites.map(modernizeSuite); | ||||
|           const { suites, tests, ...remainder } = suite; | ||||
|           return { entries: [...newSuites, ...tests], ...remainder }; | ||||
|         }; | ||||
|         const project = event.params.project; | ||||
|         project.suites = project.suites.map(modernizeSuite); | ||||
|       } | ||||
|       return event; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| const modernizer = new BlobModernizer(); | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   createMergedReport | ||||
| }); | ||||
							
								
								
									
										104
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/multiplexer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/multiplexer.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var multiplexer_exports = {}; | ||||
| __export(multiplexer_exports, { | ||||
|   Multiplexer: () => Multiplexer | ||||
| }); | ||||
| module.exports = __toCommonJS(multiplexer_exports); | ||||
| class Multiplexer { | ||||
|   constructor(reporters) { | ||||
|     this._reporters = reporters; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onConfigure?.(config)); | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onBegin?.(suite)); | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onTestBegin?.(test, result)); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onStdOut?.(chunk, test, result)); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onStdErr?.(chunk, test, result)); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onTestEnd?.(test, result)); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     for (const reporter of this._reporters) { | ||||
|       const outResult = await wrapAsync(() => reporter.onEnd?.(result)); | ||||
|       if (outResult?.status) | ||||
|         result.status = outResult.status; | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|   async onExit() { | ||||
|     for (const reporter of this._reporters) | ||||
|       await wrapAsync(() => reporter.onExit?.()); | ||||
|   } | ||||
|   onError(error) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onError?.(error)); | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onStepBegin?.(test, result, step)); | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     for (const reporter of this._reporters) | ||||
|       wrap(() => reporter.onStepEnd?.(test, result, step)); | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return this._reporters.some((r) => { | ||||
|       let prints = false; | ||||
|       wrap(() => prints = r.printsToStdio ? r.printsToStdio() : true); | ||||
|       return prints; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| async function wrapAsync(callback) { | ||||
|   try { | ||||
|     return await callback(); | ||||
|   } catch (e) { | ||||
|     console.error("Error in reporter", e); | ||||
|   } | ||||
| } | ||||
| function wrap(callback) { | ||||
|   try { | ||||
|     callback(); | ||||
|   } catch (e) { | ||||
|     console.error("Error in reporter", e); | ||||
|   } | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   Multiplexer | ||||
| }); | ||||
							
								
								
									
										102
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/reporterV2.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/reporterV2.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var reporterV2_exports = {}; | ||||
| __export(reporterV2_exports, { | ||||
|   wrapReporterAsV2: () => wrapReporterAsV2 | ||||
| }); | ||||
| module.exports = __toCommonJS(reporterV2_exports); | ||||
| function wrapReporterAsV2(reporter) { | ||||
|   try { | ||||
|     if ("version" in reporter && reporter.version() === "v2") | ||||
|       return reporter; | ||||
|   } catch (e) { | ||||
|   } | ||||
|   return new ReporterV2Wrapper(reporter); | ||||
| } | ||||
| class ReporterV2Wrapper { | ||||
|   constructor(reporter) { | ||||
|     this._deferred = []; | ||||
|     this._reporter = reporter; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this._config = config; | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     this._reporter.onBegin?.(this._config, suite); | ||||
|     const deferred = this._deferred; | ||||
|     this._deferred = null; | ||||
|     for (const item of deferred) { | ||||
|       if (item.error) | ||||
|         this.onError(item.error); | ||||
|       if (item.stdout) | ||||
|         this.onStdOut(item.stdout.chunk, item.stdout.test, item.stdout.result); | ||||
|       if (item.stderr) | ||||
|         this.onStdErr(item.stderr.chunk, item.stderr.test, item.stderr.result); | ||||
|     } | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     this._reporter.onTestBegin?.(test, result); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     if (this._deferred) { | ||||
|       this._deferred.push({ stdout: { chunk, test, result } }); | ||||
|       return; | ||||
|     } | ||||
|     this._reporter.onStdOut?.(chunk, test, result); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     if (this._deferred) { | ||||
|       this._deferred.push({ stderr: { chunk, test, result } }); | ||||
|       return; | ||||
|     } | ||||
|     this._reporter.onStdErr?.(chunk, test, result); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     this._reporter.onTestEnd?.(test, result); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     return await this._reporter.onEnd?.(result); | ||||
|   } | ||||
|   async onExit() { | ||||
|     await this._reporter.onExit?.(); | ||||
|   } | ||||
|   onError(error) { | ||||
|     if (this._deferred) { | ||||
|       this._deferred.push({ error }); | ||||
|       return; | ||||
|     } | ||||
|     this._reporter.onError?.(error); | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     this._reporter.onStepBegin?.(test, result, step); | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     this._reporter.onStepEnd?.(test, result, step); | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return this._reporter.printsToStdio ? this._reporter.printsToStdio() : true; | ||||
|   } | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   wrapReporterAsV2 | ||||
| }); | ||||
							
								
								
									
										295
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/teleEmitter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/teleEmitter.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,295 @@ | ||||
| "use strict"; | ||||
| var __create = Object.create; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __getProtoOf = Object.getPrototypeOf; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __export = (target, all) => { | ||||
|   for (var name in all) | ||||
|     __defProp(target, name, { get: all[name], enumerable: true }); | ||||
| }; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||
|   // If the importer is in node compatibility mode or this is not an ESM | ||||
|   // file that has been converted to a CommonJS file using a Babel- | ||||
|   // compatible transform (i.e. "__esModule" has not been set), then set | ||||
|   // "default" to the CommonJS "module.exports" for node compatibility. | ||||
|   isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||
|   mod | ||||
| )); | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var teleEmitter_exports = {}; | ||||
| __export(teleEmitter_exports, { | ||||
|   TeleReporterEmitter: () => TeleReporterEmitter | ||||
| }); | ||||
| module.exports = __toCommonJS(teleEmitter_exports); | ||||
| var import_path = __toESM(require("path")); | ||||
| var import_utils = require("playwright-core/lib/utils"); | ||||
| var import_teleReceiver = require("../isomorphic/teleReceiver"); | ||||
| class TeleReporterEmitter { | ||||
|   constructor(messageSink, options = {}) { | ||||
|     this._resultKnownAttachmentCounts = /* @__PURE__ */ new Map(); | ||||
|     // In case there is blob reporter and UI mode, make sure one does override | ||||
|     // the id assigned by the other. | ||||
|     this._idSymbol = Symbol("id"); | ||||
|     this._messageSink = messageSink; | ||||
|     this._emitterOptions = options; | ||||
|   } | ||||
|   version() { | ||||
|     return "v2"; | ||||
|   } | ||||
|   onConfigure(config) { | ||||
|     this._rootDir = config.rootDir; | ||||
|     this._messageSink({ method: "onConfigure", params: { config: this._serializeConfig(config) } }); | ||||
|   } | ||||
|   onBegin(suite) { | ||||
|     const projects = suite.suites.map((projectSuite) => this._serializeProject(projectSuite)); | ||||
|     for (const project of projects) | ||||
|       this._messageSink({ method: "onProject", params: { project } }); | ||||
|     this._messageSink({ method: "onBegin", params: void 0 }); | ||||
|   } | ||||
|   onTestBegin(test, result) { | ||||
|     result[this._idSymbol] = (0, import_utils.createGuid)(); | ||||
|     this._messageSink({ | ||||
|       method: "onTestBegin", | ||||
|       params: { | ||||
|         testId: test.id, | ||||
|         result: this._serializeResultStart(result) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   onTestEnd(test, result) { | ||||
|     const testEnd = { | ||||
|       testId: test.id, | ||||
|       expectedStatus: test.expectedStatus, | ||||
|       timeout: test.timeout, | ||||
|       annotations: [] | ||||
|     }; | ||||
|     this._sendNewAttachments(result, test.id); | ||||
|     this._messageSink({ | ||||
|       method: "onTestEnd", | ||||
|       params: { | ||||
|         test: testEnd, | ||||
|         result: this._serializeResultEnd(result) | ||||
|       } | ||||
|     }); | ||||
|     this._resultKnownAttachmentCounts.delete(result[this._idSymbol]); | ||||
|   } | ||||
|   onStepBegin(test, result, step) { | ||||
|     step[this._idSymbol] = (0, import_utils.createGuid)(); | ||||
|     this._messageSink({ | ||||
|       method: "onStepBegin", | ||||
|       params: { | ||||
|         testId: test.id, | ||||
|         resultId: result[this._idSymbol], | ||||
|         step: this._serializeStepStart(step) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   onStepEnd(test, result, step) { | ||||
|     const resultId = result[this._idSymbol]; | ||||
|     this._sendNewAttachments(result, test.id); | ||||
|     this._messageSink({ | ||||
|       method: "onStepEnd", | ||||
|       params: { | ||||
|         testId: test.id, | ||||
|         resultId, | ||||
|         step: this._serializeStepEnd(step, result) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   onError(error) { | ||||
|     this._messageSink({ | ||||
|       method: "onError", | ||||
|       params: { error } | ||||
|     }); | ||||
|   } | ||||
|   onStdOut(chunk, test, result) { | ||||
|     this._onStdIO("stdout", chunk, test, result); | ||||
|   } | ||||
|   onStdErr(chunk, test, result) { | ||||
|     this._onStdIO("stderr", chunk, test, result); | ||||
|   } | ||||
|   _onStdIO(type, chunk, test, result) { | ||||
|     if (this._emitterOptions.omitOutput) | ||||
|       return; | ||||
|     const isBase64 = typeof chunk !== "string"; | ||||
|     const data = isBase64 ? chunk.toString("base64") : chunk; | ||||
|     this._messageSink({ | ||||
|       method: "onStdIO", | ||||
|       params: { testId: test?.id, resultId: result ? result[this._idSymbol] : void 0, type, data, isBase64 } | ||||
|     }); | ||||
|   } | ||||
|   async onEnd(result) { | ||||
|     const resultPayload = { | ||||
|       status: result.status, | ||||
|       startTime: result.startTime.getTime(), | ||||
|       duration: result.duration | ||||
|     }; | ||||
|     this._messageSink({ | ||||
|       method: "onEnd", | ||||
|       params: { | ||||
|         result: resultPayload | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   printsToStdio() { | ||||
|     return false; | ||||
|   } | ||||
|   _serializeConfig(config) { | ||||
|     return { | ||||
|       configFile: this._relativePath(config.configFile), | ||||
|       globalTimeout: config.globalTimeout, | ||||
|       maxFailures: config.maxFailures, | ||||
|       metadata: config.metadata, | ||||
|       rootDir: config.rootDir, | ||||
|       version: config.version, | ||||
|       workers: config.workers | ||||
|     }; | ||||
|   } | ||||
|   _serializeProject(suite) { | ||||
|     const project = suite.project(); | ||||
|     const report = { | ||||
|       metadata: project.metadata, | ||||
|       name: project.name, | ||||
|       outputDir: this._relativePath(project.outputDir), | ||||
|       repeatEach: project.repeatEach, | ||||
|       retries: project.retries, | ||||
|       testDir: this._relativePath(project.testDir), | ||||
|       testIgnore: (0, import_teleReceiver.serializeRegexPatterns)(project.testIgnore), | ||||
|       testMatch: (0, import_teleReceiver.serializeRegexPatterns)(project.testMatch), | ||||
|       timeout: project.timeout, | ||||
|       suites: suite.suites.map((fileSuite) => { | ||||
|         return this._serializeSuite(fileSuite); | ||||
|       }), | ||||
|       grep: (0, import_teleReceiver.serializeRegexPatterns)(project.grep), | ||||
|       grepInvert: (0, import_teleReceiver.serializeRegexPatterns)(project.grepInvert || []), | ||||
|       dependencies: project.dependencies, | ||||
|       snapshotDir: this._relativePath(project.snapshotDir), | ||||
|       teardown: project.teardown, | ||||
|       use: this._serializeProjectUseOptions(project.use) | ||||
|     }; | ||||
|     return report; | ||||
|   } | ||||
|   _serializeProjectUseOptions(use) { | ||||
|     return { | ||||
|       testIdAttribute: use.testIdAttribute | ||||
|     }; | ||||
|   } | ||||
|   _serializeSuite(suite) { | ||||
|     const result = { | ||||
|       title: suite.title, | ||||
|       location: this._relativeLocation(suite.location), | ||||
|       entries: suite.entries().map((e) => { | ||||
|         if (e.type === "test") | ||||
|           return this._serializeTest(e); | ||||
|         return this._serializeSuite(e); | ||||
|       }) | ||||
|     }; | ||||
|     return result; | ||||
|   } | ||||
|   _serializeTest(test) { | ||||
|     return { | ||||
|       testId: test.id, | ||||
|       title: test.title, | ||||
|       location: this._relativeLocation(test.location), | ||||
|       retries: test.retries, | ||||
|       tags: test.tags, | ||||
|       repeatEachIndex: test.repeatEachIndex, | ||||
|       annotations: this._relativeAnnotationLocations(test.annotations) | ||||
|     }; | ||||
|   } | ||||
|   _serializeResultStart(result) { | ||||
|     return { | ||||
|       id: result[this._idSymbol], | ||||
|       retry: result.retry, | ||||
|       workerIndex: result.workerIndex, | ||||
|       parallelIndex: result.parallelIndex, | ||||
|       startTime: +result.startTime | ||||
|     }; | ||||
|   } | ||||
|   _serializeResultEnd(result) { | ||||
|     return { | ||||
|       id: result[this._idSymbol], | ||||
|       duration: result.duration, | ||||
|       status: result.status, | ||||
|       errors: result.errors, | ||||
|       annotations: result.annotations?.length ? this._relativeAnnotationLocations(result.annotations) : void 0 | ||||
|     }; | ||||
|   } | ||||
|   _sendNewAttachments(result, testId) { | ||||
|     const resultId = result[this._idSymbol]; | ||||
|     const knownAttachmentCount = this._resultKnownAttachmentCounts.get(resultId) ?? 0; | ||||
|     if (result.attachments.length > knownAttachmentCount) { | ||||
|       this._messageSink({ | ||||
|         method: "onAttach", | ||||
|         params: { | ||||
|           testId, | ||||
|           resultId, | ||||
|           attachments: this._serializeAttachments(result.attachments.slice(knownAttachmentCount)) | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|     this._resultKnownAttachmentCounts.set(resultId, result.attachments.length); | ||||
|   } | ||||
|   _serializeAttachments(attachments) { | ||||
|     return attachments.map((a) => { | ||||
|       const { body, ...rest } = a; | ||||
|       return { | ||||
|         ...rest, | ||||
|         // There is no Buffer in the browser, so there is no point in sending the data there. | ||||
|         base64: body && !this._emitterOptions.omitBuffers ? body.toString("base64") : void 0 | ||||
|       }; | ||||
|     }); | ||||
|   } | ||||
|   _serializeStepStart(step) { | ||||
|     return { | ||||
|       id: step[this._idSymbol], | ||||
|       parentStepId: step.parent?.[this._idSymbol], | ||||
|       title: step.title, | ||||
|       category: step.category, | ||||
|       startTime: +step.startTime, | ||||
|       location: this._relativeLocation(step.location) | ||||
|     }; | ||||
|   } | ||||
|   _serializeStepEnd(step, result) { | ||||
|     return { | ||||
|       id: step[this._idSymbol], | ||||
|       duration: step.duration, | ||||
|       error: step.error, | ||||
|       attachments: step.attachments.length ? step.attachments.map((a) => result.attachments.indexOf(a)) : void 0, | ||||
|       annotations: step.annotations.length ? this._relativeAnnotationLocations(step.annotations) : void 0 | ||||
|     }; | ||||
|   } | ||||
|   _relativeAnnotationLocations(annotations) { | ||||
|     return annotations.map((annotation) => ({ | ||||
|       ...annotation, | ||||
|       location: annotation.location ? this._relativeLocation(annotation.location) : void 0 | ||||
|     })); | ||||
|   } | ||||
|   _relativeLocation(location) { | ||||
|     if (!location) | ||||
|       return location; | ||||
|     return { | ||||
|       ...location, | ||||
|       file: this._relativePath(location.file) | ||||
|     }; | ||||
|   } | ||||
|   _relativePath(absolutePath) { | ||||
|     if (!absolutePath) | ||||
|       return absolutePath; | ||||
|     return import_path.default.relative(this._rootDir, absolutePath); | ||||
|   } | ||||
| } | ||||
| // Annotate the CommonJS export names for ESM import in node: | ||||
| 0 && (module.exports = { | ||||
|   TeleReporterEmitter | ||||
| }); | ||||
							
								
								
									
										16
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/versions/blobV1.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								frontend/e2e/node_modules/playwright/lib/reporters/versions/blobV1.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| "use strict"; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||
| var __copyProps = (to, from, except, desc) => { | ||||
|   if (from && typeof from === "object" || typeof from === "function") { | ||||
|     for (let key of __getOwnPropNames(from)) | ||||
|       if (!__hasOwnProp.call(to, key) && key !== except) | ||||
|         __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||
|   } | ||||
|   return to; | ||||
| }; | ||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||
| var blobV1_exports = {}; | ||||
| module.exports = __toCommonJS(blobV1_exports); | ||||
		Reference in New Issue
	
	Block a user
	 Connor Johnstone
					Connor Johnstone