teleEmitter.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. };
  157. }
  158. _serializeProject(suite) {
  159. const project = suite.project();
  160. const report = {
  161. metadata: project.metadata,
  162. name: project.name,
  163. outputDir: this._relativePath(project.outputDir),
  164. repeatEach: project.repeatEach,
  165. retries: project.retries,
  166. testDir: this._relativePath(project.testDir),
  167. testIgnore: (0, import_teleReceiver.serializeRegexPatterns)(project.testIgnore),
  168. testMatch: (0, import_teleReceiver.serializeRegexPatterns)(project.testMatch),
  169. timeout: project.timeout,
  170. suites: suite.suites.map((fileSuite) => {
  171. return this._serializeSuite(fileSuite);
  172. }),
  173. grep: (0, import_teleReceiver.serializeRegexPatterns)(project.grep),
  174. grepInvert: (0, import_teleReceiver.serializeRegexPatterns)(project.grepInvert || []),
  175. dependencies: project.dependencies,
  176. snapshotDir: this._relativePath(project.snapshotDir),
  177. teardown: project.teardown,
  178. use: this._serializeProjectUseOptions(project.use)
  179. };
  180. return report;
  181. }
  182. _serializeProjectUseOptions(use) {
  183. return {
  184. testIdAttribute: use.testIdAttribute
  185. };
  186. }
  187. _serializeSuite(suite) {
  188. const result = {
  189. title: suite.title,
  190. location: this._relativeLocation(suite.location),
  191. entries: suite.entries().map((e) => {
  192. if (e.type === "test")
  193. return this._serializeTest(e);
  194. return this._serializeSuite(e);
  195. })
  196. };
  197. return result;
  198. }
  199. _serializeTest(test) {
  200. return {
  201. testId: test.id,
  202. title: test.title,
  203. location: this._relativeLocation(test.location),
  204. retries: test.retries,
  205. tags: test.tags,
  206. repeatEachIndex: test.repeatEachIndex,
  207. annotations: this._relativeAnnotationLocations(test.annotations)
  208. };
  209. }
  210. _serializeResultStart(result) {
  211. return {
  212. id: result[this._idSymbol],
  213. retry: result.retry,
  214. workerIndex: result.workerIndex,
  215. parallelIndex: result.parallelIndex,
  216. startTime: +result.startTime
  217. };
  218. }
  219. _serializeResultEnd(result) {
  220. return {
  221. id: result[this._idSymbol],
  222. duration: result.duration,
  223. status: result.status,
  224. errors: result.errors,
  225. annotations: result.annotations?.length ? this._relativeAnnotationLocations(result.annotations) : void 0
  226. };
  227. }
  228. _sendNewAttachments(result, testId) {
  229. const resultId = result[this._idSymbol];
  230. const knownAttachmentCount = this._resultKnownAttachmentCounts.get(resultId) ?? 0;
  231. if (result.attachments.length > knownAttachmentCount) {
  232. this._messageSink({
  233. method: "onAttach",
  234. params: {
  235. testId,
  236. resultId,
  237. attachments: this._serializeAttachments(result.attachments.slice(knownAttachmentCount))
  238. }
  239. });
  240. }
  241. this._resultKnownAttachmentCounts.set(resultId, result.attachments.length);
  242. }
  243. _serializeAttachments(attachments) {
  244. return attachments.map((a) => {
  245. const { body, ...rest } = a;
  246. return {
  247. ...rest,
  248. // There is no Buffer in the browser, so there is no point in sending the data there.
  249. base64: body && !this._emitterOptions.omitBuffers ? body.toString("base64") : void 0
  250. };
  251. });
  252. }
  253. _serializeStepStart(step) {
  254. return {
  255. id: step[this._idSymbol],
  256. parentStepId: step.parent?.[this._idSymbol],
  257. title: step.title,
  258. category: step.category,
  259. startTime: +step.startTime,
  260. location: this._relativeLocation(step.location)
  261. };
  262. }
  263. _serializeStepEnd(step, result) {
  264. return {
  265. id: step[this._idSymbol],
  266. duration: step.duration,
  267. error: step.error,
  268. attachments: step.attachments.length ? step.attachments.map((a) => result.attachments.indexOf(a)) : void 0,
  269. annotations: step.annotations.length ? this._relativeAnnotationLocations(step.annotations) : void 0
  270. };
  271. }
  272. _relativeAnnotationLocations(annotations) {
  273. return annotations.map((annotation) => ({
  274. ...annotation,
  275. location: annotation.location ? this._relativeLocation(annotation.location) : void 0
  276. }));
  277. }
  278. _relativeLocation(location) {
  279. if (!location)
  280. return location;
  281. return {
  282. ...location,
  283. file: this._relativePath(location.file)
  284. };
  285. }
  286. _relativePath(absolutePath) {
  287. if (!absolutePath)
  288. return absolutePath;
  289. return import_path.default.relative(this._rootDir, absolutePath);
  290. }
  291. }
  292. // Annotate the CommonJS export names for ESM import in node:
  293. 0 && (module.exports = {
  294. TeleReporterEmitter
  295. });