teleReceiver.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  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 teleReceiver_exports = {};
  20. __export(teleReceiver_exports, {
  21. TeleReporterReceiver: () => TeleReporterReceiver,
  22. TeleSuite: () => TeleSuite,
  23. TeleTestCase: () => TeleTestCase,
  24. TeleTestResult: () => TeleTestResult,
  25. baseFullConfig: () => baseFullConfig,
  26. computeTestCaseOutcome: () => computeTestCaseOutcome,
  27. parseRegexPatterns: () => parseRegexPatterns,
  28. serializeRegexPatterns: () => serializeRegexPatterns
  29. });
  30. module.exports = __toCommonJS(teleReceiver_exports);
  31. class TeleReporterReceiver {
  32. constructor(reporter, options = {}) {
  33. this.isListing = false;
  34. this._tests = /* @__PURE__ */ new Map();
  35. this._rootSuite = new TeleSuite("", "root");
  36. this._options = options;
  37. this._reporter = reporter;
  38. }
  39. reset() {
  40. this._rootSuite._entries = [];
  41. this._tests.clear();
  42. }
  43. dispatch(message) {
  44. const { method, params } = message;
  45. if (method === "onConfigure") {
  46. this._onConfigure(params.config);
  47. return;
  48. }
  49. if (method === "onProject") {
  50. this._onProject(params.project);
  51. return;
  52. }
  53. if (method === "onBegin") {
  54. this._onBegin();
  55. return;
  56. }
  57. if (method === "onTestBegin") {
  58. this._onTestBegin(params.testId, params.result);
  59. return;
  60. }
  61. if (method === "onTestEnd") {
  62. this._onTestEnd(params.test, params.result);
  63. return;
  64. }
  65. if (method === "onStepBegin") {
  66. this._onStepBegin(params.testId, params.resultId, params.step);
  67. return;
  68. }
  69. if (method === "onAttach") {
  70. this._onAttach(params.testId, params.resultId, params.attachments);
  71. return;
  72. }
  73. if (method === "onStepEnd") {
  74. this._onStepEnd(params.testId, params.resultId, params.step);
  75. return;
  76. }
  77. if (method === "onError") {
  78. this._onError(params.error);
  79. return;
  80. }
  81. if (method === "onStdIO") {
  82. this._onStdIO(params.type, params.testId, params.resultId, params.data, params.isBase64);
  83. return;
  84. }
  85. if (method === "onEnd")
  86. return this._onEnd(params.result);
  87. if (method === "onExit")
  88. return this._onExit();
  89. }
  90. _onConfigure(config) {
  91. this._rootDir = config.rootDir;
  92. this._config = this._parseConfig(config);
  93. this._reporter.onConfigure?.(this._config);
  94. }
  95. _onProject(project) {
  96. let projectSuite = this._options.mergeProjects ? this._rootSuite.suites.find((suite) => suite.project().name === project.name) : void 0;
  97. if (!projectSuite) {
  98. projectSuite = new TeleSuite(project.name, "project");
  99. this._rootSuite._addSuite(projectSuite);
  100. }
  101. projectSuite._project = this._parseProject(project);
  102. for (const suite of project.suites)
  103. this._mergeSuiteInto(suite, projectSuite);
  104. }
  105. _onBegin() {
  106. this._reporter.onBegin?.(this._rootSuite);
  107. }
  108. _onTestBegin(testId, payload) {
  109. const test = this._tests.get(testId);
  110. if (this._options.clearPreviousResultsWhenTestBegins)
  111. test.results = [];
  112. const testResult = test._createTestResult(payload.id);
  113. testResult.retry = payload.retry;
  114. testResult.workerIndex = payload.workerIndex;
  115. testResult.parallelIndex = payload.parallelIndex;
  116. testResult.setStartTimeNumber(payload.startTime);
  117. this._reporter.onTestBegin?.(test, testResult);
  118. }
  119. _onTestEnd(testEndPayload, payload) {
  120. const test = this._tests.get(testEndPayload.testId);
  121. test.timeout = testEndPayload.timeout;
  122. test.expectedStatus = testEndPayload.expectedStatus;
  123. const result = test.results.find((r) => r._id === payload.id);
  124. result.duration = payload.duration;
  125. result.status = payload.status;
  126. result.errors = payload.errors;
  127. result.error = result.errors?.[0];
  128. if (!!payload.attachments)
  129. result.attachments = this._parseAttachments(payload.attachments);
  130. if (payload.annotations) {
  131. this._absoluteAnnotationLocationsInplace(payload.annotations);
  132. result.annotations = payload.annotations;
  133. test.annotations = payload.annotations;
  134. }
  135. this._reporter.onTestEnd?.(test, result);
  136. result._stepMap = /* @__PURE__ */ new Map();
  137. }
  138. _onStepBegin(testId, resultId, payload) {
  139. const test = this._tests.get(testId);
  140. const result = test.results.find((r) => r._id === resultId);
  141. const parentStep = payload.parentStepId ? result._stepMap.get(payload.parentStepId) : void 0;
  142. const location = this._absoluteLocation(payload.location);
  143. const step = new TeleTestStep(payload, parentStep, location, result);
  144. if (parentStep)
  145. parentStep.steps.push(step);
  146. else
  147. result.steps.push(step);
  148. result._stepMap.set(payload.id, step);
  149. this._reporter.onStepBegin?.(test, result, step);
  150. }
  151. _onStepEnd(testId, resultId, payload) {
  152. const test = this._tests.get(testId);
  153. const result = test.results.find((r) => r._id === resultId);
  154. const step = result._stepMap.get(payload.id);
  155. step._endPayload = payload;
  156. step.duration = payload.duration;
  157. step.error = payload.error;
  158. this._reporter.onStepEnd?.(test, result, step);
  159. }
  160. _onAttach(testId, resultId, attachments) {
  161. const test = this._tests.get(testId);
  162. const result = test.results.find((r) => r._id === resultId);
  163. result.attachments.push(...attachments.map((a) => ({
  164. name: a.name,
  165. contentType: a.contentType,
  166. path: a.path,
  167. body: a.base64 && globalThis.Buffer ? Buffer.from(a.base64, "base64") : void 0
  168. })));
  169. }
  170. _onError(error) {
  171. this._reporter.onError?.(error);
  172. }
  173. _onStdIO(type, testId, resultId, data, isBase64) {
  174. const chunk = isBase64 ? globalThis.Buffer ? Buffer.from(data, "base64") : atob(data) : data;
  175. const test = testId ? this._tests.get(testId) : void 0;
  176. const result = test && resultId ? test.results.find((r) => r._id === resultId) : void 0;
  177. if (type === "stdout") {
  178. result?.stdout.push(chunk);
  179. this._reporter.onStdOut?.(chunk, test, result);
  180. } else {
  181. result?.stderr.push(chunk);
  182. this._reporter.onStdErr?.(chunk, test, result);
  183. }
  184. }
  185. async _onEnd(result) {
  186. await this._reporter.onEnd?.({
  187. status: result.status,
  188. startTime: new Date(result.startTime),
  189. duration: result.duration
  190. });
  191. }
  192. _onExit() {
  193. return this._reporter.onExit?.();
  194. }
  195. _parseConfig(config) {
  196. const result = { ...baseFullConfig, ...config };
  197. if (this._options.configOverrides) {
  198. result.configFile = this._options.configOverrides.configFile;
  199. result.reportSlowTests = this._options.configOverrides.reportSlowTests;
  200. result.quiet = this._options.configOverrides.quiet;
  201. result.reporter = [...this._options.configOverrides.reporter];
  202. }
  203. return result;
  204. }
  205. _parseProject(project) {
  206. return {
  207. metadata: project.metadata,
  208. name: project.name,
  209. outputDir: this._absolutePath(project.outputDir),
  210. repeatEach: project.repeatEach,
  211. retries: project.retries,
  212. testDir: this._absolutePath(project.testDir),
  213. testIgnore: parseRegexPatterns(project.testIgnore),
  214. testMatch: parseRegexPatterns(project.testMatch),
  215. timeout: project.timeout,
  216. grep: parseRegexPatterns(project.grep),
  217. grepInvert: parseRegexPatterns(project.grepInvert),
  218. dependencies: project.dependencies,
  219. teardown: project.teardown,
  220. snapshotDir: this._absolutePath(project.snapshotDir),
  221. use: project.use
  222. };
  223. }
  224. _parseAttachments(attachments) {
  225. return attachments.map((a) => {
  226. return {
  227. ...a,
  228. body: a.base64 && globalThis.Buffer ? Buffer.from(a.base64, "base64") : void 0
  229. };
  230. });
  231. }
  232. _mergeSuiteInto(jsonSuite, parent) {
  233. let targetSuite = parent.suites.find((s) => s.title === jsonSuite.title);
  234. if (!targetSuite) {
  235. targetSuite = new TeleSuite(jsonSuite.title, parent.type === "project" ? "file" : "describe");
  236. parent._addSuite(targetSuite);
  237. }
  238. targetSuite.location = this._absoluteLocation(jsonSuite.location);
  239. jsonSuite.entries.forEach((e) => {
  240. if ("testId" in e)
  241. this._mergeTestInto(e, targetSuite);
  242. else
  243. this._mergeSuiteInto(e, targetSuite);
  244. });
  245. }
  246. _mergeTestInto(jsonTest, parent) {
  247. let targetTest = this._options.mergeTestCases ? parent.tests.find((s) => s.title === jsonTest.title && s.repeatEachIndex === jsonTest.repeatEachIndex) : void 0;
  248. if (!targetTest) {
  249. targetTest = new TeleTestCase(jsonTest.testId, jsonTest.title, this._absoluteLocation(jsonTest.location), jsonTest.repeatEachIndex);
  250. parent._addTest(targetTest);
  251. this._tests.set(targetTest.id, targetTest);
  252. }
  253. this._updateTest(jsonTest, targetTest);
  254. }
  255. _updateTest(payload, test) {
  256. test.id = payload.testId;
  257. test.location = this._absoluteLocation(payload.location);
  258. test.retries = payload.retries;
  259. test.tags = payload.tags ?? [];
  260. test.annotations = payload.annotations ?? [];
  261. this._absoluteAnnotationLocationsInplace(test.annotations);
  262. return test;
  263. }
  264. _absoluteAnnotationLocationsInplace(annotations) {
  265. for (const annotation of annotations) {
  266. if (annotation.location)
  267. annotation.location = this._absoluteLocation(annotation.location);
  268. }
  269. }
  270. _absoluteLocation(location) {
  271. if (!location)
  272. return location;
  273. return {
  274. ...location,
  275. file: this._absolutePath(location.file)
  276. };
  277. }
  278. _absolutePath(relativePath) {
  279. if (relativePath === void 0)
  280. return;
  281. return this._options.resolvePath ? this._options.resolvePath(this._rootDir, relativePath) : this._rootDir + "/" + relativePath;
  282. }
  283. }
  284. class TeleSuite {
  285. constructor(title, type) {
  286. this._entries = [];
  287. this._requireFile = "";
  288. this._parallelMode = "none";
  289. this.title = title;
  290. this._type = type;
  291. }
  292. get type() {
  293. return this._type;
  294. }
  295. get suites() {
  296. return this._entries.filter((e) => e.type !== "test");
  297. }
  298. get tests() {
  299. return this._entries.filter((e) => e.type === "test");
  300. }
  301. entries() {
  302. return this._entries;
  303. }
  304. allTests() {
  305. const result = [];
  306. const visit = (suite) => {
  307. for (const entry of suite.entries()) {
  308. if (entry.type === "test")
  309. result.push(entry);
  310. else
  311. visit(entry);
  312. }
  313. };
  314. visit(this);
  315. return result;
  316. }
  317. titlePath() {
  318. const titlePath = this.parent ? this.parent.titlePath() : [];
  319. if (this.title || this._type !== "describe")
  320. titlePath.push(this.title);
  321. return titlePath;
  322. }
  323. project() {
  324. return this._project ?? this.parent?.project();
  325. }
  326. _addTest(test) {
  327. test.parent = this;
  328. this._entries.push(test);
  329. }
  330. _addSuite(suite) {
  331. suite.parent = this;
  332. this._entries.push(suite);
  333. }
  334. }
  335. class TeleTestCase {
  336. constructor(id, title, location, repeatEachIndex) {
  337. this.fn = () => {
  338. };
  339. this.results = [];
  340. this.type = "test";
  341. this.expectedStatus = "passed";
  342. this.timeout = 0;
  343. this.annotations = [];
  344. this.retries = 0;
  345. this.tags = [];
  346. this.repeatEachIndex = 0;
  347. this.id = id;
  348. this.title = title;
  349. this.location = location;
  350. this.repeatEachIndex = repeatEachIndex;
  351. }
  352. titlePath() {
  353. const titlePath = this.parent ? this.parent.titlePath() : [];
  354. titlePath.push(this.title);
  355. return titlePath;
  356. }
  357. outcome() {
  358. return computeTestCaseOutcome(this);
  359. }
  360. ok() {
  361. const status = this.outcome();
  362. return status === "expected" || status === "flaky" || status === "skipped";
  363. }
  364. _createTestResult(id) {
  365. const result = new TeleTestResult(this.results.length, id);
  366. this.results.push(result);
  367. return result;
  368. }
  369. }
  370. class TeleTestStep {
  371. constructor(payload, parentStep, location, result) {
  372. this.duration = -1;
  373. this.steps = [];
  374. this._startTime = 0;
  375. this.title = payload.title;
  376. this.category = payload.category;
  377. this.location = location;
  378. this.parent = parentStep;
  379. this._startTime = payload.startTime;
  380. this._result = result;
  381. }
  382. titlePath() {
  383. const parentPath = this.parent?.titlePath() || [];
  384. return [...parentPath, this.title];
  385. }
  386. get startTime() {
  387. return new Date(this._startTime);
  388. }
  389. set startTime(value) {
  390. this._startTime = +value;
  391. }
  392. get attachments() {
  393. return this._endPayload?.attachments?.map((index) => this._result.attachments[index]) ?? [];
  394. }
  395. get annotations() {
  396. return this._endPayload?.annotations ?? [];
  397. }
  398. }
  399. class TeleTestResult {
  400. constructor(retry, id) {
  401. this.parallelIndex = -1;
  402. this.workerIndex = -1;
  403. this.duration = -1;
  404. this.stdout = [];
  405. this.stderr = [];
  406. this.attachments = [];
  407. this.annotations = [];
  408. this.status = "skipped";
  409. this.steps = [];
  410. this.errors = [];
  411. this._stepMap = /* @__PURE__ */ new Map();
  412. this._startTime = 0;
  413. this.retry = retry;
  414. this._id = id;
  415. }
  416. setStartTimeNumber(startTime) {
  417. this._startTime = startTime;
  418. }
  419. get startTime() {
  420. return new Date(this._startTime);
  421. }
  422. set startTime(value) {
  423. this._startTime = +value;
  424. }
  425. }
  426. const baseFullConfig = {
  427. forbidOnly: false,
  428. fullyParallel: false,
  429. globalSetup: null,
  430. globalTeardown: null,
  431. globalTimeout: 0,
  432. grep: /.*/,
  433. grepInvert: null,
  434. maxFailures: 0,
  435. metadata: {},
  436. preserveOutput: "always",
  437. projects: [],
  438. reporter: [[process.env.CI ? "dot" : "list"]],
  439. reportSlowTests: {
  440. max: 5,
  441. threshold: 3e5
  442. /* 5 minutes */
  443. },
  444. configFile: "",
  445. rootDir: "",
  446. quiet: false,
  447. shard: null,
  448. updateSnapshots: "missing",
  449. updateSourceMethod: "patch",
  450. version: "",
  451. workers: 0,
  452. webServer: null
  453. };
  454. function serializeRegexPatterns(patterns) {
  455. if (!Array.isArray(patterns))
  456. patterns = [patterns];
  457. return patterns.map((s) => {
  458. if (typeof s === "string")
  459. return { s };
  460. return { r: { source: s.source, flags: s.flags } };
  461. });
  462. }
  463. function parseRegexPatterns(patterns) {
  464. return patterns.map((p) => {
  465. if (p.s !== void 0)
  466. return p.s;
  467. return new RegExp(p.r.source, p.r.flags);
  468. });
  469. }
  470. function computeTestCaseOutcome(test) {
  471. let skipped = 0;
  472. let didNotRun = 0;
  473. let expected = 0;
  474. let interrupted = 0;
  475. let unexpected = 0;
  476. for (const result of test.results) {
  477. if (result.status === "interrupted") {
  478. ++interrupted;
  479. } else if (result.status === "skipped" && test.expectedStatus === "skipped") {
  480. ++skipped;
  481. } else if (result.status === "skipped") {
  482. ++didNotRun;
  483. } else if (result.status === test.expectedStatus) {
  484. ++expected;
  485. } else {
  486. ++unexpected;
  487. }
  488. }
  489. if (expected === 0 && unexpected === 0)
  490. return "skipped";
  491. if (unexpected === 0)
  492. return "expected";
  493. if (expected === 0 && skipped === 0)
  494. return "unexpected";
  495. return "flaky";
  496. }
  497. // Annotate the CommonJS export names for ESM import in node:
  498. 0 && (module.exports = {
  499. TeleReporterReceiver,
  500. TeleSuite,
  501. TeleTestCase,
  502. TeleTestResult,
  503. baseFullConfig,
  504. computeTestCaseOutcome,
  505. parseRegexPatterns,
  506. serializeRegexPatterns
  507. });