teleEmitter.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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 teleEmitter_exports = {};
  30. __export(teleEmitter_exports, {
  31. TeleReporterEmitter: () => TeleReporterEmitter
  32. });
  33. module.exports = __toCommonJS(teleEmitter_exports);
  34. var import_path = __toESM(require("path"));
  35. var import_utils = require("playwright-core/lib/utils");
  36. var import_teleReceiver = require("../isomorphic/teleReceiver");
  37. class TeleReporterEmitter {
  38. constructor(messageSink, options = {}) {
  39. this._resultKnownAttachmentCounts = /* @__PURE__ */ new Map();
  40. // In case there is blob reporter and UI mode, make sure one does override
  41. // the id assigned by the other.
  42. this._idSymbol = Symbol("id");
  43. this._messageSink = messageSink;
  44. this._emitterOptions = options;
  45. }
  46. version() {
  47. return "v2";
  48. }
  49. onConfigure(config) {
  50. this._rootDir = config.rootDir;
  51. this._messageSink({ method: "onConfigure", params: { config: this._serializeConfig(config) } });
  52. }
  53. onBegin(suite) {
  54. const projects = suite.suites.map((projectSuite) => this._serializeProject(projectSuite));
  55. for (const project of projects)
  56. this._messageSink({ method: "onProject", params: { project } });
  57. this._messageSink({ method: "onBegin", params: void 0 });
  58. }
  59. onTestBegin(test, result) {
  60. result[this._idSymbol] = (0, import_utils.createGuid)();
  61. this._messageSink({
  62. method: "onTestBegin",
  63. params: {
  64. testId: test.id,
  65. result: this._serializeResultStart(result)
  66. }
  67. });
  68. }
  69. onTestEnd(test, result) {
  70. const testEnd = {
  71. testId: test.id,
  72. expectedStatus: test.expectedStatus,
  73. timeout: test.timeout,
  74. annotations: []
  75. };
  76. this._sendNewAttachments(result, test.id);
  77. this._messageSink({
  78. method: "onTestEnd",
  79. params: {
  80. test: testEnd,
  81. result: this._serializeResultEnd(result)
  82. }
  83. });
  84. this._resultKnownAttachmentCounts.delete(result[this._idSymbol]);
  85. }
  86. onStepBegin(test, result, step) {
  87. step[this._idSymbol] = (0, import_utils.createGuid)();
  88. this._messageSink({
  89. method: "onStepBegin",
  90. params: {
  91. testId: test.id,
  92. resultId: result[this._idSymbol],
  93. step: this._serializeStepStart(step)
  94. }
  95. });
  96. }
  97. onStepEnd(test, result, step) {
  98. const resultId = result[this._idSymbol];
  99. this._sendNewAttachments(result, test.id);
  100. this._messageSink({
  101. method: "onStepEnd",
  102. params: {
  103. testId: test.id,
  104. resultId,
  105. step: this._serializeStepEnd(step, result)
  106. }
  107. });
  108. }
  109. onError(error) {
  110. this._messageSink({
  111. method: "onError",
  112. params: { error }
  113. });
  114. }
  115. onStdOut(chunk, test, result) {
  116. this._onStdIO("stdout", chunk, test, result);
  117. }
  118. onStdErr(chunk, test, result) {
  119. this._onStdIO("stderr", chunk, test, result);
  120. }
  121. _onStdIO(type, chunk, test, result) {
  122. if (this._emitterOptions.omitOutput)
  123. return;
  124. const isBase64 = typeof chunk !== "string";
  125. const data = isBase64 ? chunk.toString("base64") : chunk;
  126. this._messageSink({
  127. method: "onStdIO",
  128. params: { testId: test?.id, resultId: result ? result[this._idSymbol] : void 0, type, data, isBase64 }
  129. });
  130. }
  131. async onEnd(result) {
  132. const resultPayload = {
  133. status: result.status,
  134. startTime: result.startTime.getTime(),
  135. duration: result.duration
  136. };
  137. this._messageSink({
  138. method: "onEnd",
  139. params: {
  140. result: resultPayload
  141. }
  142. });
  143. }
  144. printsToStdio() {
  145. return false;
  146. }
  147. _serializeConfig(config) {
  148. return {
  149. configFile: this._relativePath(config.configFile),
  150. globalTimeout: config.globalTimeout,
  151. maxFailures: config.maxFailures,
  152. metadata: config.metadata,
  153. rootDir: config.rootDir,
  154. version: config.version,
  155. workers: config.workers,
  156. globalSetup: config.globalSetup,
  157. globalTeardown: config.globalTeardown,
  158. tags: config.tags,
  159. webServer: config.webServer
  160. };
  161. }
  162. _serializeProject(suite) {
  163. const project = suite.project();
  164. const report = {
  165. metadata: project.metadata,
  166. name: project.name,
  167. outputDir: this._relativePath(project.outputDir),
  168. repeatEach: project.repeatEach,
  169. retries: project.retries,
  170. testDir: this._relativePath(project.testDir),
  171. testIgnore: (0, import_teleReceiver.serializeRegexPatterns)(project.testIgnore),
  172. testMatch: (0, import_teleReceiver.serializeRegexPatterns)(project.testMatch),
  173. timeout: project.timeout,
  174. suites: suite.suites.map((fileSuite) => {
  175. return this._serializeSuite(fileSuite);
  176. }),
  177. grep: (0, import_teleReceiver.serializeRegexPatterns)(project.grep),
  178. grepInvert: (0, import_teleReceiver.serializeRegexPatterns)(project.grepInvert || []),
  179. dependencies: project.dependencies,
  180. snapshotDir: this._relativePath(project.snapshotDir),
  181. teardown: project.teardown,
  182. use: this._serializeProjectUseOptions(project.use)
  183. };
  184. return report;
  185. }
  186. _serializeProjectUseOptions(use) {
  187. return {
  188. testIdAttribute: use.testIdAttribute
  189. };
  190. }
  191. _serializeSuite(suite) {
  192. const result = {
  193. title: suite.title,
  194. location: this._relativeLocation(suite.location),
  195. entries: suite.entries().map((e) => {
  196. if (e.type === "test")
  197. return this._serializeTest(e);
  198. return this._serializeSuite(e);
  199. })
  200. };
  201. return result;
  202. }
  203. _serializeTest(test) {
  204. return {
  205. testId: test.id,
  206. title: test.title,
  207. location: this._relativeLocation(test.location),
  208. retries: test.retries,
  209. tags: test.tags,
  210. repeatEachIndex: test.repeatEachIndex,
  211. annotations: this._relativeAnnotationLocations(test.annotations)
  212. };
  213. }
  214. _serializeResultStart(result) {
  215. return {
  216. id: result[this._idSymbol],
  217. retry: result.retry,
  218. workerIndex: result.workerIndex,
  219. parallelIndex: result.parallelIndex,
  220. startTime: +result.startTime
  221. };
  222. }
  223. _serializeResultEnd(result) {
  224. return {
  225. id: result[this._idSymbol],
  226. duration: result.duration,
  227. status: result.status,
  228. errors: result.errors,
  229. annotations: result.annotations?.length ? this._relativeAnnotationLocations(result.annotations) : void 0
  230. };
  231. }
  232. _sendNewAttachments(result, testId) {
  233. const resultId = result[this._idSymbol];
  234. const knownAttachmentCount = this._resultKnownAttachmentCounts.get(resultId) ?? 0;
  235. if (result.attachments.length > knownAttachmentCount) {
  236. this._messageSink({
  237. method: "onAttach",
  238. params: {
  239. testId,
  240. resultId,
  241. attachments: this._serializeAttachments(result.attachments.slice(knownAttachmentCount))
  242. }
  243. });
  244. }
  245. this._resultKnownAttachmentCounts.set(resultId, result.attachments.length);
  246. }
  247. _serializeAttachments(attachments) {
  248. return attachments.map((a) => {
  249. const { body, ...rest } = a;
  250. return {
  251. ...rest,
  252. // There is no Buffer in the browser, so there is no point in sending the data there.
  253. base64: body && !this._emitterOptions.omitBuffers ? body.toString("base64") : void 0
  254. };
  255. });
  256. }
  257. _serializeStepStart(step) {
  258. return {
  259. id: step[this._idSymbol],
  260. parentStepId: step.parent?.[this._idSymbol],
  261. title: step.title,
  262. category: step.category,
  263. startTime: +step.startTime,
  264. location: this._relativeLocation(step.location)
  265. };
  266. }
  267. _serializeStepEnd(step, result) {
  268. return {
  269. id: step[this._idSymbol],
  270. duration: step.duration,
  271. error: step.error,
  272. attachments: step.attachments.length ? step.attachments.map((a) => result.attachments.indexOf(a)) : void 0,
  273. annotations: step.annotations.length ? this._relativeAnnotationLocations(step.annotations) : void 0
  274. };
  275. }
  276. _relativeAnnotationLocations(annotations) {
  277. return annotations.map((annotation) => ({
  278. ...annotation,
  279. location: annotation.location ? this._relativeLocation(annotation.location) : void 0
  280. }));
  281. }
  282. _relativeLocation(location) {
  283. if (!location)
  284. return location;
  285. return {
  286. ...location,
  287. file: this._relativePath(location.file)
  288. };
  289. }
  290. _relativePath(absolutePath) {
  291. if (!absolutePath)
  292. return absolutePath;
  293. return import_path.default.relative(this._rootDir, absolutePath);
  294. }
  295. }
  296. // Annotate the CommonJS export names for ESM import in node:
  297. 0 && (module.exports = {
  298. TeleReporterEmitter
  299. });