@stablyai/internal-playwright 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +168 -0
  4. package/ThirdPartyNotices.txt +6277 -0
  5. package/cli.js +19 -0
  6. package/index.d.ts +17 -0
  7. package/index.js +17 -0
  8. package/index.mjs +18 -0
  9. package/jsx-runtime.js +42 -0
  10. package/jsx-runtime.mjs +21 -0
  11. package/lib/agents/generateAgents.js +265 -0
  12. package/lib/agents/generator.md +102 -0
  13. package/lib/agents/healer.md +78 -0
  14. package/lib/agents/planner.md +135 -0
  15. package/lib/cli.js +274 -0
  16. package/lib/common/config.js +274 -0
  17. package/lib/common/config.js.map +7 -0
  18. package/lib/common/configLoader.js +377 -0
  19. package/lib/common/configLoader.js.map +7 -0
  20. package/lib/common/esmLoaderHost.js +102 -0
  21. package/lib/common/esmLoaderHost.js.map +7 -0
  22. package/lib/common/expectBundle.js +52 -0
  23. package/lib/common/expectBundle.js.map +7 -0
  24. package/lib/common/expectBundleImpl.js +389 -0
  25. package/lib/common/expectBundleImpl.js.map +7 -0
  26. package/lib/common/fixtures.js +302 -0
  27. package/lib/common/fixtures.js.map +7 -0
  28. package/lib/common/globals.js +58 -0
  29. package/lib/common/globals.js.map +7 -0
  30. package/lib/common/ipc.js +60 -0
  31. package/lib/common/ipc.js.map +7 -0
  32. package/lib/common/poolBuilder.js +85 -0
  33. package/lib/common/poolBuilder.js.map +7 -0
  34. package/lib/common/process.js +104 -0
  35. package/lib/common/process.js.map +7 -0
  36. package/lib/common/suiteUtils.js +140 -0
  37. package/lib/common/suiteUtils.js.map +7 -0
  38. package/lib/common/test.js +321 -0
  39. package/lib/common/test.js.map +7 -0
  40. package/lib/common/testLoader.js +100 -0
  41. package/lib/common/testLoader.js.map +7 -0
  42. package/lib/common/testType.js +310 -0
  43. package/lib/common/testType.js.map +7 -0
  44. package/lib/fsWatcher.js +67 -0
  45. package/lib/fsWatcher.js.map +7 -0
  46. package/lib/index.js +696 -0
  47. package/lib/index.js.map +7 -0
  48. package/lib/internalsForTest.js +42 -0
  49. package/lib/internalsForTest.js.map +7 -0
  50. package/lib/isomorphic/events.js +77 -0
  51. package/lib/isomorphic/events.js.map +7 -0
  52. package/lib/isomorphic/folders.js +30 -0
  53. package/lib/isomorphic/folders.js.map +7 -0
  54. package/lib/isomorphic/stringInternPool.js +69 -0
  55. package/lib/isomorphic/stringInternPool.js.map +7 -0
  56. package/lib/isomorphic/teleReceiver.js +507 -0
  57. package/lib/isomorphic/teleReceiver.js.map +7 -0
  58. package/lib/isomorphic/teleSuiteUpdater.js +137 -0
  59. package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
  60. package/lib/isomorphic/testServerConnection.js +211 -0
  61. package/lib/isomorphic/testServerConnection.js.map +7 -0
  62. package/lib/isomorphic/testServerInterface.js +16 -0
  63. package/lib/isomorphic/testServerInterface.js.map +7 -0
  64. package/lib/isomorphic/testTree.js +334 -0
  65. package/lib/isomorphic/testTree.js.map +7 -0
  66. package/lib/isomorphic/types.d.js +16 -0
  67. package/lib/isomorphic/types.d.js.map +7 -0
  68. package/lib/loader/loaderMain.js +59 -0
  69. package/lib/loader/loaderMain.js.map +7 -0
  70. package/lib/matchers/expect.js +325 -0
  71. package/lib/matchers/expect.js.map +7 -0
  72. package/lib/matchers/matcherHint.js +87 -0
  73. package/lib/matchers/matcherHint.js.map +7 -0
  74. package/lib/matchers/matchers.js +366 -0
  75. package/lib/matchers/matchers.js.map +7 -0
  76. package/lib/matchers/toBeTruthy.js +73 -0
  77. package/lib/matchers/toBeTruthy.js.map +7 -0
  78. package/lib/matchers/toEqual.js +99 -0
  79. package/lib/matchers/toEqual.js.map +7 -0
  80. package/lib/matchers/toHaveURL.js +102 -0
  81. package/lib/matchers/toHaveURL.js.map +7 -0
  82. package/lib/matchers/toMatchAriaSnapshot.js +159 -0
  83. package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
  84. package/lib/matchers/toMatchSnapshot.js +359 -0
  85. package/lib/matchers/toMatchSnapshot.js.map +7 -0
  86. package/lib/matchers/toMatchText.js +99 -0
  87. package/lib/matchers/toMatchText.js.map +7 -0
  88. package/lib/mcp/browser/actions.d.js +16 -0
  89. package/lib/mcp/browser/backend.js +93 -0
  90. package/lib/mcp/browser/backend.js.map +7 -0
  91. package/lib/mcp/browser/browserContextFactory.js +296 -0
  92. package/lib/mcp/browser/browserServerBackend.js +76 -0
  93. package/lib/mcp/browser/codegen.js +66 -0
  94. package/lib/mcp/browser/config.js +385 -0
  95. package/lib/mcp/browser/context.js +287 -0
  96. package/lib/mcp/browser/response.js +228 -0
  97. package/lib/mcp/browser/sessionLog.js +160 -0
  98. package/lib/mcp/browser/tab.js +277 -0
  99. package/lib/mcp/browser/tool.js +30 -0
  100. package/lib/mcp/browser/tool.js.map +7 -0
  101. package/lib/mcp/browser/tools/common.js +63 -0
  102. package/lib/mcp/browser/tools/console.js +44 -0
  103. package/lib/mcp/browser/tools/dialogs.js +60 -0
  104. package/lib/mcp/browser/tools/evaluate.js +70 -0
  105. package/lib/mcp/browser/tools/files.js +58 -0
  106. package/lib/mcp/browser/tools/form.js +74 -0
  107. package/lib/mcp/browser/tools/install.js +69 -0
  108. package/lib/mcp/browser/tools/keyboard.js +85 -0
  109. package/lib/mcp/browser/tools/mouse.js +107 -0
  110. package/lib/mcp/browser/tools/navigate.js +62 -0
  111. package/lib/mcp/browser/tools/network.js +54 -0
  112. package/lib/mcp/browser/tools/pdf.js +59 -0
  113. package/lib/mcp/browser/tools/screenshot.js +88 -0
  114. package/lib/mcp/browser/tools/snapshot.js +182 -0
  115. package/lib/mcp/browser/tools/tabs.js +67 -0
  116. package/lib/mcp/browser/tools/tool.js +49 -0
  117. package/lib/mcp/browser/tools/tracing.js +74 -0
  118. package/lib/mcp/browser/tools/utils.js +100 -0
  119. package/lib/mcp/browser/tools/verify.js +154 -0
  120. package/lib/mcp/browser/tools/wait.js +63 -0
  121. package/lib/mcp/browser/tools.js +80 -0
  122. package/lib/mcp/browser/tools.js.map +7 -0
  123. package/lib/mcp/browser/watchdog.js +44 -0
  124. package/lib/mcp/config.d.js +16 -0
  125. package/lib/mcp/extension/cdpRelay.js +351 -0
  126. package/lib/mcp/extension/extensionContextFactory.js +75 -0
  127. package/lib/mcp/extension/protocol.js +28 -0
  128. package/lib/mcp/index.js +61 -0
  129. package/lib/mcp/log.js +35 -0
  130. package/lib/mcp/program.js +96 -0
  131. package/lib/mcp/sdk/bundle.js +81 -0
  132. package/lib/mcp/sdk/bundle.js.map +7 -0
  133. package/lib/mcp/sdk/call.js +49 -0
  134. package/lib/mcp/sdk/call.js.map +7 -0
  135. package/lib/mcp/sdk/exports.js +32 -0
  136. package/lib/mcp/sdk/exports.js.map +7 -0
  137. package/lib/mcp/sdk/http.js +187 -0
  138. package/lib/mcp/sdk/http.js.map +7 -0
  139. package/lib/mcp/sdk/inProcessTransport.js +71 -0
  140. package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
  141. package/lib/mcp/sdk/mdb.js +206 -0
  142. package/lib/mcp/sdk/mdb.js.map +7 -0
  143. package/lib/mcp/sdk/proxyBackend.js +128 -0
  144. package/lib/mcp/sdk/proxyBackend.js.map +7 -0
  145. package/lib/mcp/sdk/server.js +189 -0
  146. package/lib/mcp/sdk/server.js.map +7 -0
  147. package/lib/mcp/sdk/tool.js +51 -0
  148. package/lib/mcp/sdk/tool.js.map +7 -0
  149. package/lib/mcp/test/backend.js +67 -0
  150. package/lib/mcp/test/backend.js.map +7 -0
  151. package/lib/mcp/test/browserBackend.js +98 -0
  152. package/lib/mcp/test/context.js +48 -0
  153. package/lib/mcp/test/context.js.map +7 -0
  154. package/lib/mcp/test/generatorTools.js +122 -0
  155. package/lib/mcp/test/plannerTools.js +46 -0
  156. package/lib/mcp/test/seed.js +72 -0
  157. package/lib/mcp/test/streams.js +39 -0
  158. package/lib/mcp/test/streams.js.map +7 -0
  159. package/lib/mcp/test/testBackend.js +97 -0
  160. package/lib/mcp/test/testContext.js +176 -0
  161. package/lib/mcp/test/testTool.js +30 -0
  162. package/lib/mcp/test/testTools.js +115 -0
  163. package/lib/mcp/test/tool.js +30 -0
  164. package/lib/mcp/test/tool.js.map +7 -0
  165. package/lib/mcp/test/tools.js +150 -0
  166. package/lib/mcp/test/tools.js.map +7 -0
  167. package/lib/mcp/vscode/host.js +187 -0
  168. package/lib/mcp/vscode/main.js +77 -0
  169. package/lib/mcpBundleImpl.js +41 -0
  170. package/lib/mcpBundleImpl.js.map +7 -0
  171. package/lib/plugins/gitCommitInfoPlugin.js +198 -0
  172. package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
  173. package/lib/plugins/index.js +28 -0
  174. package/lib/plugins/index.js.map +7 -0
  175. package/lib/plugins/webServerPlugin.js +209 -0
  176. package/lib/plugins/webServerPlugin.js.map +7 -0
  177. package/lib/program.js +412 -0
  178. package/lib/program.js.map +7 -0
  179. package/lib/reporters/base.js +609 -0
  180. package/lib/reporters/base.js.map +7 -0
  181. package/lib/reporters/blob.js +135 -0
  182. package/lib/reporters/blob.js.map +7 -0
  183. package/lib/reporters/dot.js +82 -0
  184. package/lib/reporters/dot.js.map +7 -0
  185. package/lib/reporters/empty.js +32 -0
  186. package/lib/reporters/empty.js.map +7 -0
  187. package/lib/reporters/github.js +128 -0
  188. package/lib/reporters/github.js.map +7 -0
  189. package/lib/reporters/html.js +644 -0
  190. package/lib/reporters/html.js.map +7 -0
  191. package/lib/reporters/internalReporter.js +130 -0
  192. package/lib/reporters/internalReporter.js.map +7 -0
  193. package/lib/reporters/json.js +254 -0
  194. package/lib/reporters/json.js.map +7 -0
  195. package/lib/reporters/junit.js +230 -0
  196. package/lib/reporters/junit.js.map +7 -0
  197. package/lib/reporters/line.js +113 -0
  198. package/lib/reporters/line.js.map +7 -0
  199. package/lib/reporters/list.js +235 -0
  200. package/lib/reporters/list.js.map +7 -0
  201. package/lib/reporters/listModeReporter.js +69 -0
  202. package/lib/reporters/listModeReporter.js.map +7 -0
  203. package/lib/reporters/markdown.js +144 -0
  204. package/lib/reporters/markdown.js.map +7 -0
  205. package/lib/reporters/merge.js +535 -0
  206. package/lib/reporters/merge.js.map +7 -0
  207. package/lib/reporters/multiplexer.js +104 -0
  208. package/lib/reporters/multiplexer.js.map +7 -0
  209. package/lib/reporters/reporterV2.js +102 -0
  210. package/lib/reporters/reporterV2.js.map +7 -0
  211. package/lib/reporters/teleEmitter.js +297 -0
  212. package/lib/reporters/teleEmitter.js.map +7 -0
  213. package/lib/reporters/versions/blobV1.js +16 -0
  214. package/lib/reporters/versions/blobV1.js.map +7 -0
  215. package/lib/runner/dispatcher.js +491 -0
  216. package/lib/runner/dispatcher.js.map +7 -0
  217. package/lib/runner/failureTracker.js +72 -0
  218. package/lib/runner/failureTracker.js.map +7 -0
  219. package/lib/runner/lastRun.js +77 -0
  220. package/lib/runner/lastRun.js.map +7 -0
  221. package/lib/runner/loadUtils.js +333 -0
  222. package/lib/runner/loadUtils.js.map +7 -0
  223. package/lib/runner/loaderHost.js +89 -0
  224. package/lib/runner/loaderHost.js.map +7 -0
  225. package/lib/runner/processHost.js +161 -0
  226. package/lib/runner/processHost.js.map +7 -0
  227. package/lib/runner/projectUtils.js +241 -0
  228. package/lib/runner/projectUtils.js.map +7 -0
  229. package/lib/runner/rebase.js +189 -0
  230. package/lib/runner/rebase.js.map +7 -0
  231. package/lib/runner/reporters.js +137 -0
  232. package/lib/runner/reporters.js.map +7 -0
  233. package/lib/runner/runner.js +173 -0
  234. package/lib/runner/sigIntWatcher.js +96 -0
  235. package/lib/runner/sigIntWatcher.js.map +7 -0
  236. package/lib/runner/taskRunner.js +127 -0
  237. package/lib/runner/taskRunner.js.map +7 -0
  238. package/lib/runner/tasks.js +410 -0
  239. package/lib/runner/tasks.js.map +7 -0
  240. package/lib/runner/testGroups.js +117 -0
  241. package/lib/runner/testGroups.js.map +7 -0
  242. package/lib/runner/testRunner.js +390 -0
  243. package/lib/runner/testRunner.js.map +7 -0
  244. package/lib/runner/testServer.js +264 -0
  245. package/lib/runner/testServer.js.map +7 -0
  246. package/lib/runner/uiMode.js +271 -0
  247. package/lib/runner/uiModeReporter.js +30 -0
  248. package/lib/runner/uiModeReporter.js.map +7 -0
  249. package/lib/runner/vcs.js +72 -0
  250. package/lib/runner/vcs.js.map +7 -0
  251. package/lib/runner/watchMode.js +395 -0
  252. package/lib/runner/watchMode.js.map +7 -0
  253. package/lib/runner/workerHost.js +95 -0
  254. package/lib/runner/workerHost.js.map +7 -0
  255. package/lib/store.js +98 -0
  256. package/lib/third_party/pirates.js +62 -0
  257. package/lib/third_party/pirates.js.map +7 -0
  258. package/lib/third_party/tsconfig-loader.js +103 -0
  259. package/lib/third_party/tsconfig-loader.js.map +7 -0
  260. package/lib/transform/babelBundle.js +43 -0
  261. package/lib/transform/babelBundle.js.map +7 -0
  262. package/lib/transform/babelBundleImpl.js +461 -0
  263. package/lib/transform/babelBundleImpl.js.map +7 -0
  264. package/lib/transform/compilationCache.js +272 -0
  265. package/lib/transform/compilationCache.js.map +7 -0
  266. package/lib/transform/esmLoader.js +104 -0
  267. package/lib/transform/esmLoader.js.map +7 -0
  268. package/lib/transform/esmUtils.js +32 -0
  269. package/lib/transform/portTransport.js +67 -0
  270. package/lib/transform/portTransport.js.map +7 -0
  271. package/lib/transform/transform.js +293 -0
  272. package/lib/transform/transform.js.map +7 -0
  273. package/lib/util.js +403 -0
  274. package/lib/util.js.map +7 -0
  275. package/lib/utilsBundle.js +43 -0
  276. package/lib/utilsBundle.js.map +7 -0
  277. package/lib/utilsBundleImpl.js +100 -0
  278. package/lib/utilsBundleImpl.js.map +7 -0
  279. package/lib/worker/fixtureRunner.js +258 -0
  280. package/lib/worker/fixtureRunner.js.map +7 -0
  281. package/lib/worker/stepContext.js +34 -0
  282. package/lib/worker/testInfo.js +508 -0
  283. package/lib/worker/testInfo.js.map +7 -0
  284. package/lib/worker/testTracing.js +344 -0
  285. package/lib/worker/testTracing.js.map +7 -0
  286. package/lib/worker/timeoutManager.js +174 -0
  287. package/lib/worker/timeoutManager.js.map +7 -0
  288. package/lib/worker/util.js +31 -0
  289. package/lib/worker/util.js.map +7 -0
  290. package/lib/worker/workerMain.js +520 -0
  291. package/lib/worker/workerMain.js.map +7 -0
  292. package/package.json +74 -0
  293. package/test.d.ts +18 -0
  294. package/test.js +24 -0
  295. package/test.mjs +33 -0
  296. package/types/test.d.ts +10217 -0
  297. package/types/testReporter.d.ts +816 -0
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var junit_exports = {};
30
+ __export(junit_exports, {
31
+ default: () => junit_default
32
+ });
33
+ module.exports = __toCommonJS(junit_exports);
34
+ var import_fs = __toESM(require("fs"));
35
+ var import_path = __toESM(require("path"));
36
+ var import_utils = require("playwright-core/lib/utils");
37
+ var import_base = require("./base");
38
+ var import_util = require("../util");
39
+ class JUnitReporter {
40
+ constructor(options) {
41
+ this.totalTests = 0;
42
+ this.totalFailures = 0;
43
+ this.totalSkipped = 0;
44
+ this.stripANSIControlSequences = false;
45
+ this.includeProjectInTestName = false;
46
+ this.stripANSIControlSequences = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_JUNIT_STRIP_ANSI", !!options.stripANSIControlSequences);
47
+ this.includeProjectInTestName = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME", !!options.includeProjectInTestName);
48
+ this.configDir = options.configDir;
49
+ this.resolvedOutputFile = (0, import_base.resolveOutputFile)("JUNIT", options)?.outputFile;
50
+ }
51
+ version() {
52
+ return "v2";
53
+ }
54
+ printsToStdio() {
55
+ return !this.resolvedOutputFile;
56
+ }
57
+ onConfigure(config) {
58
+ this.config = config;
59
+ }
60
+ onBegin(suite) {
61
+ this.suite = suite;
62
+ this.timestamp = /* @__PURE__ */ new Date();
63
+ }
64
+ async onEnd(result) {
65
+ const children = [];
66
+ for (const projectSuite of this.suite.suites) {
67
+ for (const fileSuite of projectSuite.suites)
68
+ children.push(await this._buildTestSuite(projectSuite.title, fileSuite));
69
+ }
70
+ const tokens = [];
71
+ const self = this;
72
+ const root = {
73
+ name: "testsuites",
74
+ attributes: {
75
+ id: process.env[`PLAYWRIGHT_JUNIT_SUITE_ID`] || "",
76
+ name: process.env[`PLAYWRIGHT_JUNIT_SUITE_NAME`] || "",
77
+ tests: self.totalTests,
78
+ failures: self.totalFailures,
79
+ skipped: self.totalSkipped,
80
+ errors: 0,
81
+ time: result.duration / 1e3
82
+ },
83
+ children
84
+ };
85
+ serializeXML(root, tokens, this.stripANSIControlSequences);
86
+ const reportString = tokens.join("\n");
87
+ if (this.resolvedOutputFile) {
88
+ await import_fs.default.promises.mkdir(import_path.default.dirname(this.resolvedOutputFile), { recursive: true });
89
+ await import_fs.default.promises.writeFile(this.resolvedOutputFile, reportString);
90
+ } else {
91
+ console.log(reportString);
92
+ }
93
+ }
94
+ async _buildTestSuite(projectName, suite) {
95
+ let tests = 0;
96
+ let skipped = 0;
97
+ let failures = 0;
98
+ let duration = 0;
99
+ const children = [];
100
+ const testCaseNamePrefix = projectName && this.includeProjectInTestName ? `[${projectName}] ` : "";
101
+ for (const test of suite.allTests()) {
102
+ ++tests;
103
+ if (test.outcome() === "skipped")
104
+ ++skipped;
105
+ if (!test.ok())
106
+ ++failures;
107
+ for (const result of test.results)
108
+ duration += result.duration;
109
+ await this._addTestCase(suite.title, testCaseNamePrefix, test, children);
110
+ }
111
+ this.totalTests += tests;
112
+ this.totalSkipped += skipped;
113
+ this.totalFailures += failures;
114
+ const entry = {
115
+ name: "testsuite",
116
+ attributes: {
117
+ name: suite.title,
118
+ timestamp: this.timestamp.toISOString(),
119
+ hostname: projectName,
120
+ tests,
121
+ failures,
122
+ skipped,
123
+ time: duration / 1e3,
124
+ errors: 0
125
+ },
126
+ children
127
+ };
128
+ return entry;
129
+ }
130
+ async _addTestCase(suiteName, namePrefix, test, entries) {
131
+ const entry = {
132
+ name: "testcase",
133
+ attributes: {
134
+ // Skip root, project, file
135
+ name: namePrefix + test.titlePath().slice(3).join(" \u203A "),
136
+ // filename
137
+ classname: suiteName,
138
+ time: test.results.reduce((acc, value) => acc + value.duration, 0) / 1e3
139
+ },
140
+ children: []
141
+ };
142
+ entries.push(entry);
143
+ const properties = {
144
+ name: "properties",
145
+ children: []
146
+ };
147
+ for (const annotation of test.annotations) {
148
+ const property = {
149
+ name: "property",
150
+ attributes: {
151
+ name: annotation.type,
152
+ value: annotation?.description ? annotation.description : ""
153
+ }
154
+ };
155
+ properties.children?.push(property);
156
+ }
157
+ if (properties.children?.length)
158
+ entry.children.push(properties);
159
+ if (test.outcome() === "skipped") {
160
+ entry.children.push({ name: "skipped" });
161
+ return;
162
+ }
163
+ if (!test.ok()) {
164
+ entry.children.push({
165
+ name: "failure",
166
+ attributes: {
167
+ message: `${import_path.default.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`,
168
+ type: "FAILURE"
169
+ },
170
+ text: (0, import_util.stripAnsiEscapes)((0, import_base.formatFailure)(import_base.nonTerminalScreen, this.config, test))
171
+ });
172
+ }
173
+ const systemOut = [];
174
+ const systemErr = [];
175
+ for (const result of test.results) {
176
+ systemOut.push(...result.stdout.map((item) => item.toString()));
177
+ systemErr.push(...result.stderr.map((item) => item.toString()));
178
+ for (const attachment of result.attachments) {
179
+ if (!attachment.path)
180
+ continue;
181
+ let attachmentPath = import_path.default.relative(this.configDir, attachment.path);
182
+ try {
183
+ if (this.resolvedOutputFile)
184
+ attachmentPath = import_path.default.relative(import_path.default.dirname(this.resolvedOutputFile), attachment.path);
185
+ } catch {
186
+ systemOut.push(`
187
+ Warning: Unable to make attachment path ${attachment.path} relative to report output file ${this.resolvedOutputFile}`);
188
+ }
189
+ try {
190
+ await import_fs.default.promises.access(attachment.path);
191
+ systemOut.push(`
192
+ [[ATTACHMENT|${attachmentPath}]]
193
+ `);
194
+ } catch {
195
+ systemErr.push(`
196
+ Warning: attachment ${attachmentPath} is missing`);
197
+ }
198
+ }
199
+ }
200
+ if (systemOut.length)
201
+ entry.children.push({ name: "system-out", text: systemOut.join("") });
202
+ if (systemErr.length)
203
+ entry.children.push({ name: "system-err", text: systemErr.join("") });
204
+ }
205
+ }
206
+ function serializeXML(entry, tokens, stripANSIControlSequences) {
207
+ const attrs = [];
208
+ for (const [name, value] of Object.entries(entry.attributes || {}))
209
+ attrs.push(`${name}="${escape(String(value), stripANSIControlSequences, false)}"`);
210
+ tokens.push(`<${entry.name}${attrs.length ? " " : ""}${attrs.join(" ")}>`);
211
+ for (const child of entry.children || [])
212
+ serializeXML(child, tokens, stripANSIControlSequences);
213
+ if (entry.text)
214
+ tokens.push(escape(entry.text, stripANSIControlSequences, true));
215
+ tokens.push(`</${entry.name}>`);
216
+ }
217
+ const discouragedXMLCharacters = /[\u0000-\u0008\u000b-\u000c\u000e-\u001f\u007f-\u0084\u0086-\u009f]/g;
218
+ function escape(text, stripANSIControlSequences, isCharacterData) {
219
+ if (stripANSIControlSequences)
220
+ text = (0, import_util.stripAnsiEscapes)(text);
221
+ if (isCharacterData) {
222
+ text = "<![CDATA[" + text.replace(/]]>/g, "]]&gt;") + "]]>";
223
+ } else {
224
+ const escapeRe = /[&"'<>]/g;
225
+ text = text.replace(escapeRe, (c) => ({ "&": "&amp;", '"': "&quot;", "'": "&apos;", "<": "&lt;", ">": "&gt;" })[c]);
226
+ }
227
+ text = text.replace(discouragedXMLCharacters, "");
228
+ return text;
229
+ }
230
+ var junit_default = JUnitReporter;
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/reporters/junit.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { getAsBooleanFromENV } from 'playwright-core/lib/utils';\n\nimport { CommonReporterOptions, formatFailure, nonTerminalScreen, resolveOutputFile } from './base';\nimport { stripAnsiEscapes } from '../util';\n\nimport type { ReporterV2 } from './reporterV2';\nimport type { JUnitReporterOptions } from '../../types/test';\nimport type { FullConfig, FullResult, Suite, TestCase } from '../../types/testReporter';\n\nclass JUnitReporter implements ReporterV2 {\n private config!: FullConfig;\n private configDir: string;\n private suite!: Suite;\n private timestamp!: Date;\n private totalTests = 0;\n private totalFailures = 0;\n private totalSkipped = 0;\n private resolvedOutputFile: string | undefined;\n private stripANSIControlSequences = false;\n private includeProjectInTestName = false;\n\n constructor(options: JUnitReporterOptions & CommonReporterOptions) {\n this.stripANSIControlSequences = getAsBooleanFromENV('PLAYWRIGHT_JUNIT_STRIP_ANSI', !!options.stripANSIControlSequences);\n this.includeProjectInTestName = getAsBooleanFromENV('PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME', !!options.includeProjectInTestName);\n this.configDir = options.configDir;\n this.resolvedOutputFile = resolveOutputFile('JUNIT', options)?.outputFile;\n }\n\n version(): 'v2' {\n return 'v2';\n }\n\n printsToStdio() {\n return !this.resolvedOutputFile;\n }\n\n onConfigure(config: FullConfig) {\n this.config = config;\n }\n\n onBegin(suite: Suite) {\n this.suite = suite;\n this.timestamp = new Date();\n }\n\n async onEnd(result: FullResult) {\n const children: XMLEntry[] = [];\n for (const projectSuite of this.suite.suites) {\n for (const fileSuite of projectSuite.suites)\n children.push(await this._buildTestSuite(projectSuite.title, fileSuite));\n }\n const tokens: string[] = [];\n\n const self = this;\n const root: XMLEntry = {\n name: 'testsuites',\n attributes: {\n id: process.env[`PLAYWRIGHT_JUNIT_SUITE_ID`] || '',\n name: process.env[`PLAYWRIGHT_JUNIT_SUITE_NAME`] || '',\n tests: self.totalTests,\n failures: self.totalFailures,\n skipped: self.totalSkipped,\n errors: 0,\n time: result.duration / 1000\n },\n children\n };\n\n serializeXML(root, tokens, this.stripANSIControlSequences);\n const reportString = tokens.join('\\n');\n if (this.resolvedOutputFile) {\n await fs.promises.mkdir(path.dirname(this.resolvedOutputFile), { recursive: true });\n await fs.promises.writeFile(this.resolvedOutputFile, reportString);\n } else {\n // eslint-disable-next-line no-console\n console.log(reportString);\n }\n }\n\n private async _buildTestSuite(projectName: string, suite: Suite): Promise<XMLEntry> {\n let tests = 0;\n let skipped = 0;\n let failures = 0;\n let duration = 0;\n const children: XMLEntry[] = [];\n const testCaseNamePrefix = projectName && this.includeProjectInTestName ? `[${projectName}] ` : '';\n\n for (const test of suite.allTests()){\n ++tests;\n if (test.outcome() === 'skipped')\n ++skipped;\n if (!test.ok())\n ++failures;\n for (const result of test.results)\n duration += result.duration;\n await this._addTestCase(suite.title, testCaseNamePrefix, test, children);\n }\n\n this.totalTests += tests;\n this.totalSkipped += skipped;\n this.totalFailures += failures;\n\n const entry: XMLEntry = {\n name: 'testsuite',\n attributes: {\n name: suite.title,\n timestamp: this.timestamp.toISOString(),\n hostname: projectName,\n tests,\n failures,\n skipped,\n time: duration / 1000,\n errors: 0,\n },\n children\n };\n\n return entry;\n }\n\n private async _addTestCase(suiteName: string, namePrefix: string, test: TestCase, entries: XMLEntry[]) {\n const entry = {\n name: 'testcase',\n attributes: {\n // Skip root, project, file\n name: namePrefix + test.titlePath().slice(3).join(' \u203A '),\n // filename\n classname: suiteName,\n time: (test.results.reduce((acc, value) => acc + value.duration, 0)) / 1000\n\n },\n children: [] as XMLEntry[]\n };\n entries.push(entry);\n\n // Xray Test Management supports testcase level properties, where additional metadata may be provided\n // some annotations are encoded as value attributes, other as cdata content; this implementation supports\n // Xray JUnit extensions but it also agnostic, so other tools can also take advantage of this format\n const properties: XMLEntry = {\n name: 'properties',\n children: [] as XMLEntry[]\n };\n\n for (const annotation of test.annotations) {\n const property: XMLEntry = {\n name: 'property',\n attributes: {\n name: annotation.type,\n value: (annotation?.description ? annotation.description : '')\n }\n };\n properties.children?.push(property);\n }\n\n if (properties.children?.length)\n entry.children.push(properties);\n\n if (test.outcome() === 'skipped') {\n entry.children.push({ name: 'skipped' });\n return;\n }\n\n if (!test.ok()) {\n entry.children.push({\n name: 'failure',\n attributes: {\n message: `${path.basename(test.location.file)}:${test.location.line}:${test.location.column} ${test.title}`,\n type: 'FAILURE',\n },\n text: stripAnsiEscapes(formatFailure(nonTerminalScreen, this.config, test))\n });\n }\n\n const systemOut: string[] = [];\n const systemErr: string[] = [];\n for (const result of test.results) {\n systemOut.push(...result.stdout.map(item => item.toString()));\n systemErr.push(...result.stderr.map(item => item.toString()));\n for (const attachment of result.attachments) {\n if (!attachment.path)\n continue;\n\n let attachmentPath = path.relative(this.configDir, attachment.path);\n try {\n if (this.resolvedOutputFile)\n attachmentPath = path.relative(path.dirname(this.resolvedOutputFile), attachment.path);\n } catch {\n systemOut.push(`\\nWarning: Unable to make attachment path ${attachment.path} relative to report output file ${this.resolvedOutputFile}`);\n }\n\n try {\n await fs.promises.access(attachment.path);\n systemOut.push(`\\n[[ATTACHMENT|${attachmentPath}]]\\n`);\n } catch {\n systemErr.push(`\\nWarning: attachment ${attachmentPath} is missing`);\n }\n }\n }\n // Note: it is important to only produce a single system-out/system-err entry\n // so that parsers in the wild understand it.\n if (systemOut.length)\n entry.children.push({ name: 'system-out', text: systemOut.join('') });\n if (systemErr.length)\n entry.children.push({ name: 'system-err', text: systemErr.join('') });\n }\n}\n\ntype XMLEntry = {\n name: string;\n attributes?: { [name: string]: string | number | boolean };\n children?: XMLEntry[];\n text?: string;\n};\n\nfunction serializeXML(entry: XMLEntry, tokens: string[], stripANSIControlSequences: boolean) {\n const attrs: string[] = [];\n for (const [name, value] of Object.entries(entry.attributes || {}))\n attrs.push(`${name}=\"${escape(String(value), stripANSIControlSequences, false)}\"`);\n tokens.push(`<${entry.name}${attrs.length ? ' ' : ''}${attrs.join(' ')}>`);\n for (const child of entry.children || [])\n serializeXML(child, tokens, stripANSIControlSequences);\n if (entry.text)\n tokens.push(escape(entry.text, stripANSIControlSequences, true));\n tokens.push(`</${entry.name}>`);\n}\n\n// See https://en.wikipedia.org/wiki/Valid_characters_in_XML\nconst discouragedXMLCharacters = /[\\u0000-\\u0008\\u000b-\\u000c\\u000e-\\u001f\\u007f-\\u0084\\u0086-\\u009f]/g;\n\nfunction escape(text: string, stripANSIControlSequences: boolean, isCharacterData: boolean): string {\n if (stripANSIControlSequences)\n text = stripAnsiEscapes(text);\n\n if (isCharacterData) {\n text = '<![CDATA[' + text.replace(/]]>/g, ']]&gt;') + ']]>';\n } else {\n const escapeRe = /[&\"'<>]/g;\n text = text.replace(escapeRe, c => ({ '&': '&amp;', '\"': '&quot;', \"'\": '&apos;', '<': '&lt;', '>': '&gt;' }[c]!));\n }\n\n text = text.replace(discouragedXMLCharacters, '');\n return text;\n}\n\nexport default JUnitReporter;\n"],
5
+ "mappings": "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",
6
+ "names": ["fs", "path"]
7
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var line_exports = {};
20
+ __export(line_exports, {
21
+ default: () => line_default
22
+ });
23
+ module.exports = __toCommonJS(line_exports);
24
+ var import_base = require("./base");
25
+ class LineReporter extends import_base.TerminalReporter {
26
+ constructor() {
27
+ super(...arguments);
28
+ this._current = 0;
29
+ this._failures = 0;
30
+ this._didBegin = false;
31
+ }
32
+ onBegin(suite) {
33
+ super.onBegin(suite);
34
+ const startingMessage = this.generateStartingMessage();
35
+ if (startingMessage) {
36
+ this.writeLine(startingMessage);
37
+ this.writeLine();
38
+ }
39
+ this._didBegin = true;
40
+ }
41
+ onStdOut(chunk, test, result) {
42
+ super.onStdOut(chunk, test, result);
43
+ this._dumpToStdio(test, chunk, this.screen.stdout);
44
+ }
45
+ onStdErr(chunk, test, result) {
46
+ super.onStdErr(chunk, test, result);
47
+ this._dumpToStdio(test, chunk, this.screen.stderr);
48
+ }
49
+ _dumpToStdio(test, chunk, stream) {
50
+ if (this.config.quiet)
51
+ return;
52
+ if (!process.env.PW_TEST_DEBUG_REPORTERS)
53
+ stream.write(`\x1B[1A\x1B[2K`);
54
+ if (test && this._lastTest !== test) {
55
+ const title = this.screen.colors.dim(this.formatTestTitle(test));
56
+ stream.write(this.fitToScreen(title) + `
57
+ `);
58
+ this._lastTest = test;
59
+ }
60
+ stream.write(chunk);
61
+ if (chunk[chunk.length - 1] !== "\n")
62
+ this.writeLine();
63
+ this.writeLine();
64
+ }
65
+ onTestBegin(test, result) {
66
+ ++this._current;
67
+ this._updateLine(test, result, void 0);
68
+ }
69
+ onStepBegin(test, result, step) {
70
+ if (this.screen.isTTY && step.category === "test.step")
71
+ this._updateLine(test, result, step);
72
+ }
73
+ onStepEnd(test, result, step) {
74
+ if (this.screen.isTTY && step.category === "test.step")
75
+ this._updateLine(test, result, step.parent);
76
+ }
77
+ onTestEnd(test, result) {
78
+ super.onTestEnd(test, result);
79
+ if (!this.willRetry(test) && (test.outcome() === "flaky" || test.outcome() === "unexpected" || result.status === "interrupted")) {
80
+ if (!process.env.PW_TEST_DEBUG_REPORTERS)
81
+ this.screen.stdout.write(`\x1B[1A\x1B[2K`);
82
+ this.writeLine(this.formatFailure(test, ++this._failures));
83
+ this.writeLine();
84
+ }
85
+ }
86
+ _updateLine(test, result, step) {
87
+ const retriesPrefix = this.totalTestCount < this._current ? ` (retries)` : ``;
88
+ const prefix = `[${this._current}/${this.totalTestCount}]${retriesPrefix} `;
89
+ const currentRetrySuffix = result.retry ? this.screen.colors.yellow(` (retry #${result.retry})`) : "";
90
+ const title = this.formatTestTitle(test, step) + currentRetrySuffix;
91
+ if (process.env.PW_TEST_DEBUG_REPORTERS)
92
+ this.screen.stdout.write(`${prefix + title}
93
+ `);
94
+ else
95
+ this.screen.stdout.write(`\x1B[1A\x1B[2K${prefix + this.fitToScreen(title, prefix)}
96
+ `);
97
+ }
98
+ onError(error) {
99
+ super.onError(error);
100
+ const message = this.formatError(error).message + "\n";
101
+ if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin)
102
+ this.screen.stdout.write(`\x1B[1A\x1B[2K`);
103
+ this.screen.stdout.write(message);
104
+ this.writeLine();
105
+ }
106
+ async onEnd(result) {
107
+ if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin)
108
+ this.screen.stdout.write(`\x1B[1A\x1B[2K`);
109
+ await super.onEnd(result);
110
+ this.epilogue(false);
111
+ }
112
+ }
113
+ var line_default = LineReporter;
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/reporters/line.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { TerminalReporter } from './base';\n\nimport type { FullResult, Suite, TestCase, TestError, TestResult, TestStep } from '../../types/testReporter';\n\nclass LineReporter extends TerminalReporter {\n private _current = 0;\n private _failures = 0;\n private _lastTest: TestCase | undefined;\n private _didBegin = false;\n\n override onBegin(suite: Suite) {\n super.onBegin(suite);\n const startingMessage = this.generateStartingMessage();\n if (startingMessage) {\n this.writeLine(startingMessage);\n this.writeLine();\n }\n this._didBegin = true;\n }\n\n override onStdOut(chunk: string | Buffer, test?: TestCase, result?: TestResult) {\n super.onStdOut(chunk, test, result);\n this._dumpToStdio(test, chunk, this.screen.stdout);\n }\n\n override onStdErr(chunk: string | Buffer, test?: TestCase, result?: TestResult) {\n super.onStdErr(chunk, test, result);\n this._dumpToStdio(test, chunk, this.screen.stderr);\n }\n\n private _dumpToStdio(test: TestCase | undefined, chunk: string | Buffer, stream: NodeJS.WriteStream) {\n if (this.config.quiet)\n return;\n if (!process.env.PW_TEST_DEBUG_REPORTERS)\n stream.write(`\\u001B[1A\\u001B[2K`);\n if (test && this._lastTest !== test) {\n // Write new header for the output.\n const title = this.screen.colors.dim(this.formatTestTitle(test));\n stream.write(this.fitToScreen(title) + `\\n`);\n this._lastTest = test;\n }\n\n stream.write(chunk);\n if (chunk[chunk.length - 1] !== '\\n')\n this.writeLine();\n\n this.writeLine();\n }\n\n onTestBegin(test: TestCase, result: TestResult) {\n ++this._current;\n this._updateLine(test, result, undefined);\n }\n\n onStepBegin(test: TestCase, result: TestResult, step: TestStep) {\n if (this.screen.isTTY && step.category === 'test.step')\n this._updateLine(test, result, step);\n }\n\n onStepEnd(test: TestCase, result: TestResult, step: TestStep) {\n if (this.screen.isTTY && step.category === 'test.step')\n this._updateLine(test, result, step.parent);\n }\n\n override onTestEnd(test: TestCase, result: TestResult) {\n super.onTestEnd(test, result);\n if (!this.willRetry(test) && (test.outcome() === 'flaky' || test.outcome() === 'unexpected' || result.status === 'interrupted')) {\n if (!process.env.PW_TEST_DEBUG_REPORTERS)\n this.screen.stdout.write(`\\u001B[1A\\u001B[2K`);\n this.writeLine(this.formatFailure(test, ++this._failures));\n this.writeLine();\n }\n }\n\n private _updateLine(test: TestCase, result: TestResult, step?: TestStep) {\n const retriesPrefix = this.totalTestCount < this._current ? ` (retries)` : ``;\n const prefix = `[${this._current}/${this.totalTestCount}]${retriesPrefix} `;\n const currentRetrySuffix = result.retry ? this.screen.colors.yellow(` (retry #${result.retry})`) : '';\n const title = this.formatTestTitle(test, step) + currentRetrySuffix;\n if (process.env.PW_TEST_DEBUG_REPORTERS)\n this.screen.stdout.write(`${prefix + title}\\n`);\n else\n this.screen.stdout.write(`\\u001B[1A\\u001B[2K${prefix + this.fitToScreen(title, prefix)}\\n`);\n }\n\n override onError(error: TestError): void {\n super.onError(error);\n\n const message = this.formatError(error).message + '\\n';\n if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin)\n this.screen.stdout.write(`\\u001B[1A\\u001B[2K`);\n this.screen.stdout.write(message);\n this.writeLine();\n }\n\n override async onEnd(result: FullResult) {\n if (!process.env.PW_TEST_DEBUG_REPORTERS && this._didBegin)\n this.screen.stdout.write(`\\u001B[1A\\u001B[2K`);\n await super.onEnd(result);\n this.epilogue(false);\n }\n}\n\nexport default LineReporter;\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var list_exports = {};
20
+ __export(list_exports, {
21
+ default: () => list_default
22
+ });
23
+ module.exports = __toCommonJS(list_exports);
24
+ var import_utils = require("playwright-core/lib/utils");
25
+ var import_utilsBundle = require("playwright-core/lib/utilsBundle");
26
+ var import_base = require("./base");
27
+ var import_util = require("../util");
28
+ const DOES_NOT_SUPPORT_UTF8_IN_TERMINAL = process.platform === "win32" && process.env.TERM_PROGRAM !== "vscode" && !process.env.WT_SESSION;
29
+ const POSITIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "ok" : "\u2713";
30
+ const NEGATIVE_STATUS_MARK = DOES_NOT_SUPPORT_UTF8_IN_TERMINAL ? "x" : "\u2718";
31
+ class ListReporter extends import_base.TerminalReporter {
32
+ constructor(options) {
33
+ super(options);
34
+ this._lastRow = 0;
35
+ this._lastColumn = 0;
36
+ this._testRows = /* @__PURE__ */ new Map();
37
+ this._stepRows = /* @__PURE__ */ new Map();
38
+ this._resultIndex = /* @__PURE__ */ new Map();
39
+ this._stepIndex = /* @__PURE__ */ new Map();
40
+ this._needNewLine = false;
41
+ this._printSteps = (0, import_utils.getAsBooleanFromENV)("PLAYWRIGHT_LIST_PRINT_STEPS", options?.printSteps);
42
+ this._prefixStdio = options?.prefixStdio;
43
+ }
44
+ onBegin(suite) {
45
+ super.onBegin(suite);
46
+ const startingMessage = this.generateStartingMessage();
47
+ if (startingMessage) {
48
+ this.writeLine(startingMessage);
49
+ this.writeLine("");
50
+ }
51
+ }
52
+ onTestBegin(test, result) {
53
+ const index = String(this._resultIndex.size + 1);
54
+ this._resultIndex.set(result, index);
55
+ if (!this.screen.isTTY)
56
+ return;
57
+ this._maybeWriteNewLine();
58
+ this._testRows.set(test, this._lastRow);
59
+ const prefix = this._testPrefix(index, "");
60
+ const line = this.screen.colors.dim(this.formatTestTitle(test)) + this._retrySuffix(result);
61
+ this._appendLine(line, prefix);
62
+ }
63
+ onStdOut(chunk, test, result) {
64
+ super.onStdOut(chunk, test, result);
65
+ this._dumpToStdio(test, chunk, this.screen.stdout, "out");
66
+ }
67
+ onStdErr(chunk, test, result) {
68
+ super.onStdErr(chunk, test, result);
69
+ this._dumpToStdio(test, chunk, this.screen.stderr, "err");
70
+ }
71
+ getStepIndex(testIndex, result, step) {
72
+ if (this._stepIndex.has(step))
73
+ return this._stepIndex.get(step);
74
+ const ordinal = (result[lastStepOrdinalSymbol] || 0) + 1;
75
+ result[lastStepOrdinalSymbol] = ordinal;
76
+ const stepIndex = `${testIndex}.${ordinal}`;
77
+ this._stepIndex.set(step, stepIndex);
78
+ return stepIndex;
79
+ }
80
+ onStepBegin(test, result, step) {
81
+ if (step.category !== "test.step")
82
+ return;
83
+ const testIndex = this._resultIndex.get(result) || "";
84
+ if (!this.screen.isTTY)
85
+ return;
86
+ if (this._printSteps) {
87
+ this._maybeWriteNewLine();
88
+ this._stepRows.set(step, this._lastRow);
89
+ const prefix = this._testPrefix(this.getStepIndex(testIndex, result, step), "");
90
+ const line = test.title + this.screen.colors.dim((0, import_base.stepSuffix)(step));
91
+ this._appendLine(line, prefix);
92
+ } else {
93
+ this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step)) + this._retrySuffix(result), this._testPrefix(testIndex, ""));
94
+ }
95
+ }
96
+ onStepEnd(test, result, step) {
97
+ if (step.category !== "test.step")
98
+ return;
99
+ const testIndex = this._resultIndex.get(result) || "";
100
+ if (!this._printSteps) {
101
+ if (this.screen.isTTY)
102
+ this._updateOrAppendLine(this._testRows, test, this.screen.colors.dim(this.formatTestTitle(test, step.parent)) + this._retrySuffix(result), this._testPrefix(testIndex, ""));
103
+ return;
104
+ }
105
+ const index = this.getStepIndex(testIndex, result, step);
106
+ const title = this.screen.isTTY ? test.title + this.screen.colors.dim((0, import_base.stepSuffix)(step)) : this.formatTestTitle(test, step);
107
+ const prefix = this._testPrefix(index, "");
108
+ let text = "";
109
+ if (step.error)
110
+ text = this.screen.colors.red(title);
111
+ else
112
+ text = title;
113
+ text += this.screen.colors.dim(` (${(0, import_utilsBundle.ms)(step.duration)})`);
114
+ this._updateOrAppendLine(this._stepRows, step, text, prefix);
115
+ }
116
+ _maybeWriteNewLine() {
117
+ if (this._needNewLine) {
118
+ this._needNewLine = false;
119
+ this.screen.stdout.write("\n");
120
+ ++this._lastRow;
121
+ this._lastColumn = 0;
122
+ }
123
+ }
124
+ _updateLineCountAndNewLineFlagForOutput(text) {
125
+ this._needNewLine = text[text.length - 1] !== "\n";
126
+ if (!this.screen.ttyWidth)
127
+ return;
128
+ for (const ch of text) {
129
+ if (ch === "\n") {
130
+ this._lastColumn = 0;
131
+ ++this._lastRow;
132
+ continue;
133
+ }
134
+ ++this._lastColumn;
135
+ if (this._lastColumn > this.screen.ttyWidth) {
136
+ this._lastColumn = 0;
137
+ ++this._lastRow;
138
+ }
139
+ }
140
+ }
141
+ _dumpToStdio(test, chunk, stream, stdio) {
142
+ if (this.config.quiet)
143
+ return;
144
+ const text = chunk.toString("utf-8");
145
+ this._updateLineCountAndNewLineFlagForOutput(text);
146
+ if (this._prefixStdio)
147
+ stream.write(`[${stdio}] ${chunk}`);
148
+ else
149
+ stream.write(chunk);
150
+ }
151
+ onTestEnd(test, result) {
152
+ super.onTestEnd(test, result);
153
+ const title = this.formatTestTitle(test);
154
+ let prefix = "";
155
+ let text = "";
156
+ let index = this._resultIndex.get(result);
157
+ if (!index) {
158
+ index = String(this._resultIndex.size + 1);
159
+ this._resultIndex.set(result, index);
160
+ }
161
+ if (result.status === "skipped") {
162
+ prefix = this._testPrefix(index, this.screen.colors.green("-"));
163
+ text = this.screen.colors.cyan(title) + this._retrySuffix(result);
164
+ } else {
165
+ const statusMark = result.status === "passed" ? POSITIVE_STATUS_MARK : NEGATIVE_STATUS_MARK;
166
+ if (result.status === test.expectedStatus) {
167
+ prefix = this._testPrefix(index, this.screen.colors.green(statusMark));
168
+ text = title;
169
+ } else {
170
+ prefix = this._testPrefix(index, this.screen.colors.red(statusMark));
171
+ text = this.screen.colors.red(title);
172
+ }
173
+ text += this._retrySuffix(result) + this.screen.colors.dim(` (${(0, import_utilsBundle.ms)(result.duration)})`);
174
+ }
175
+ this._updateOrAppendLine(this._testRows, test, text, prefix);
176
+ }
177
+ _updateOrAppendLine(entityRowNumbers, entity, text, prefix) {
178
+ const row = entityRowNumbers.get(entity);
179
+ if (row !== void 0 && this.screen.isTTY && this._lastRow - row < this.screen.ttyHeight) {
180
+ this._updateLine(row, text, prefix);
181
+ } else {
182
+ this._maybeWriteNewLine();
183
+ entityRowNumbers.set(entity, this._lastRow);
184
+ this._appendLine(text, prefix);
185
+ }
186
+ }
187
+ _appendLine(text, prefix) {
188
+ const line = prefix + this.fitToScreen(text, prefix);
189
+ if (process.env.PW_TEST_DEBUG_REPORTERS) {
190
+ this.screen.stdout.write("#" + this._lastRow + " : " + line + "\n");
191
+ } else {
192
+ this.screen.stdout.write(line);
193
+ this.screen.stdout.write("\n");
194
+ }
195
+ ++this._lastRow;
196
+ this._lastColumn = 0;
197
+ }
198
+ _updateLine(row, text, prefix) {
199
+ const line = prefix + this.fitToScreen(text, prefix);
200
+ if (process.env.PW_TEST_DEBUG_REPORTERS)
201
+ this.screen.stdout.write("#" + row + " : " + line + "\n");
202
+ else
203
+ this._updateLineForTTY(row, line);
204
+ }
205
+ _updateLineForTTY(row, line) {
206
+ if (row !== this._lastRow)
207
+ this.screen.stdout.write(`\x1B[${this._lastRow - row}A`);
208
+ this.screen.stdout.write("\x1B[2K\x1B[0G");
209
+ this.screen.stdout.write(line);
210
+ if (row !== this._lastRow)
211
+ this.screen.stdout.write(`\x1B[${this._lastRow - row}E`);
212
+ }
213
+ _testPrefix(index, statusMark) {
214
+ const statusMarkLength = (0, import_util.stripAnsiEscapes)(statusMark).length;
215
+ const indexLength = Math.ceil(Math.log10(this.totalTestCount + 1));
216
+ return " " + statusMark + " ".repeat(3 - statusMarkLength) + this.screen.colors.dim(index.padStart(indexLength) + " ");
217
+ }
218
+ _retrySuffix(result) {
219
+ return result.retry ? this.screen.colors.yellow(` (retry #${result.retry})`) : "";
220
+ }
221
+ onError(error) {
222
+ super.onError(error);
223
+ this._maybeWriteNewLine();
224
+ const message = this.formatError(error).message + "\n";
225
+ this._updateLineCountAndNewLineFlagForOutput(message);
226
+ this.screen.stdout.write(message);
227
+ }
228
+ async onEnd(result) {
229
+ await super.onEnd(result);
230
+ this.screen.stdout.write("\n");
231
+ this.epilogue(true);
232
+ }
233
+ }
234
+ const lastStepOrdinalSymbol = Symbol("lastStepOrdinal");
235
+ var list_default = ListReporter;