test.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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 test_exports = {};
  20. __export(test_exports, {
  21. Suite: () => Suite,
  22. TestCase: () => TestCase
  23. });
  24. module.exports = __toCommonJS(test_exports);
  25. var import_testType = require("./testType");
  26. var import_teleReceiver = require("../isomorphic/teleReceiver");
  27. class Base {
  28. constructor(title) {
  29. this._only = false;
  30. this._requireFile = "";
  31. this.title = title;
  32. }
  33. }
  34. class Suite extends Base {
  35. constructor(title, type) {
  36. super(title);
  37. this._use = [];
  38. this._entries = [];
  39. this._hooks = [];
  40. // Annotations known statically before running the test, e.g. `test.describe.skip()` or `test.describe({ annotation }, body)`.
  41. this._staticAnnotations = [];
  42. // Explicitly declared tags that are not a part of the title.
  43. this._tags = [];
  44. this._modifiers = [];
  45. this._parallelMode = "none";
  46. this._type = type;
  47. }
  48. get type() {
  49. return this._type;
  50. }
  51. entries() {
  52. return this._entries;
  53. }
  54. get suites() {
  55. return this._entries.filter((entry) => entry instanceof Suite);
  56. }
  57. get tests() {
  58. return this._entries.filter((entry) => entry instanceof TestCase);
  59. }
  60. _addTest(test) {
  61. test.parent = this;
  62. this._entries.push(test);
  63. }
  64. _addSuite(suite) {
  65. suite.parent = this;
  66. this._entries.push(suite);
  67. }
  68. _prependSuite(suite) {
  69. suite.parent = this;
  70. this._entries.unshift(suite);
  71. }
  72. allTests() {
  73. const result = [];
  74. const visit = (suite) => {
  75. for (const entry of suite._entries) {
  76. if (entry instanceof Suite)
  77. visit(entry);
  78. else
  79. result.push(entry);
  80. }
  81. };
  82. visit(this);
  83. return result;
  84. }
  85. _hasTests() {
  86. let result = false;
  87. const visit = (suite) => {
  88. for (const entry of suite._entries) {
  89. if (result)
  90. return;
  91. if (entry instanceof Suite)
  92. visit(entry);
  93. else
  94. result = true;
  95. }
  96. };
  97. visit(this);
  98. return result;
  99. }
  100. titlePath() {
  101. const titlePath = this.parent ? this.parent.titlePath() : [];
  102. if (this.title || this._type !== "describe")
  103. titlePath.push(this.title);
  104. return titlePath;
  105. }
  106. _collectGrepTitlePath(path) {
  107. if (this.parent)
  108. this.parent._collectGrepTitlePath(path);
  109. if (this.title || this._type !== "describe")
  110. path.push(this.title);
  111. path.push(...this._tags);
  112. }
  113. _getOnlyItems() {
  114. const items = [];
  115. if (this._only)
  116. items.push(this);
  117. for (const suite of this.suites)
  118. items.push(...suite._getOnlyItems());
  119. items.push(...this.tests.filter((test) => test._only));
  120. return items;
  121. }
  122. _deepClone() {
  123. const suite = this._clone();
  124. for (const entry of this._entries) {
  125. if (entry instanceof Suite)
  126. suite._addSuite(entry._deepClone());
  127. else
  128. suite._addTest(entry._clone());
  129. }
  130. return suite;
  131. }
  132. _deepSerialize() {
  133. const suite = this._serialize();
  134. suite.entries = [];
  135. for (const entry of this._entries) {
  136. if (entry instanceof Suite)
  137. suite.entries.push(entry._deepSerialize());
  138. else
  139. suite.entries.push(entry._serialize());
  140. }
  141. return suite;
  142. }
  143. static _deepParse(data) {
  144. const suite = Suite._parse(data);
  145. for (const entry of data.entries) {
  146. if (entry.kind === "suite")
  147. suite._addSuite(Suite._deepParse(entry));
  148. else
  149. suite._addTest(TestCase._parse(entry));
  150. }
  151. return suite;
  152. }
  153. forEachTest(visitor) {
  154. for (const entry of this._entries) {
  155. if (entry instanceof Suite)
  156. entry.forEachTest(visitor);
  157. else
  158. visitor(entry, this);
  159. }
  160. }
  161. _serialize() {
  162. return {
  163. kind: "suite",
  164. title: this.title,
  165. type: this._type,
  166. location: this.location,
  167. only: this._only,
  168. requireFile: this._requireFile,
  169. timeout: this._timeout,
  170. retries: this._retries,
  171. staticAnnotations: this._staticAnnotations.slice(),
  172. tags: this._tags.slice(),
  173. modifiers: this._modifiers.slice(),
  174. parallelMode: this._parallelMode,
  175. hooks: this._hooks.map((h) => ({ type: h.type, location: h.location, title: h.title })),
  176. fileId: this._fileId
  177. };
  178. }
  179. static _parse(data) {
  180. const suite = new Suite(data.title, data.type);
  181. suite.location = data.location;
  182. suite._only = data.only;
  183. suite._requireFile = data.requireFile;
  184. suite._timeout = data.timeout;
  185. suite._retries = data.retries;
  186. suite._staticAnnotations = data.staticAnnotations;
  187. suite._tags = data.tags;
  188. suite._modifiers = data.modifiers;
  189. suite._parallelMode = data.parallelMode;
  190. suite._hooks = data.hooks.map((h) => ({ type: h.type, location: h.location, title: h.title, fn: () => {
  191. } }));
  192. suite._fileId = data.fileId;
  193. return suite;
  194. }
  195. _clone() {
  196. const data = this._serialize();
  197. const suite = Suite._parse(data);
  198. suite._use = this._use.slice();
  199. suite._hooks = this._hooks.slice();
  200. suite._fullProject = this._fullProject;
  201. return suite;
  202. }
  203. project() {
  204. return this._fullProject?.project || this.parent?.project();
  205. }
  206. }
  207. class TestCase extends Base {
  208. constructor(title, fn, testType, location) {
  209. super(title);
  210. this.results = [];
  211. this.type = "test";
  212. this.expectedStatus = "passed";
  213. this.timeout = 0;
  214. this.annotations = [];
  215. this.retries = 0;
  216. this.repeatEachIndex = 0;
  217. this.id = "";
  218. this._poolDigest = "";
  219. this._workerHash = "";
  220. this._projectId = "";
  221. // Explicitly declared tags that are not a part of the title.
  222. this._tags = [];
  223. this.fn = fn;
  224. this._testType = testType;
  225. this.location = location;
  226. }
  227. titlePath() {
  228. const titlePath = this.parent ? this.parent.titlePath() : [];
  229. titlePath.push(this.title);
  230. return titlePath;
  231. }
  232. outcome() {
  233. return (0, import_teleReceiver.computeTestCaseOutcome)(this);
  234. }
  235. ok() {
  236. const status = this.outcome();
  237. return status === "expected" || status === "flaky" || status === "skipped";
  238. }
  239. get tags() {
  240. const titleTags = this._grepBaseTitlePath().join(" ").match(/@[\S]+/g) || [];
  241. return [
  242. ...titleTags,
  243. ...this._tags
  244. ];
  245. }
  246. _serialize() {
  247. return {
  248. kind: "test",
  249. id: this.id,
  250. title: this.title,
  251. retries: this.retries,
  252. timeout: this.timeout,
  253. expectedStatus: this.expectedStatus,
  254. location: this.location,
  255. only: this._only,
  256. requireFile: this._requireFile,
  257. poolDigest: this._poolDigest,
  258. workerHash: this._workerHash,
  259. annotations: this.annotations.slice(),
  260. tags: this._tags.slice(),
  261. projectId: this._projectId
  262. };
  263. }
  264. static _parse(data) {
  265. const test = new TestCase(data.title, () => {
  266. }, import_testType.rootTestType, data.location);
  267. test.id = data.id;
  268. test.retries = data.retries;
  269. test.timeout = data.timeout;
  270. test.expectedStatus = data.expectedStatus;
  271. test._only = data.only;
  272. test._requireFile = data.requireFile;
  273. test._poolDigest = data.poolDigest;
  274. test._workerHash = data.workerHash;
  275. test.annotations = data.annotations;
  276. test._tags = data.tags;
  277. test._projectId = data.projectId;
  278. return test;
  279. }
  280. _clone() {
  281. const data = this._serialize();
  282. const test = TestCase._parse(data);
  283. test._testType = this._testType;
  284. test.fn = this.fn;
  285. return test;
  286. }
  287. _appendTestResult() {
  288. const result = {
  289. retry: this.results.length,
  290. parallelIndex: -1,
  291. workerIndex: -1,
  292. duration: 0,
  293. startTime: /* @__PURE__ */ new Date(),
  294. stdout: [],
  295. stderr: [],
  296. attachments: [],
  297. status: "skipped",
  298. steps: [],
  299. errors: [],
  300. annotations: []
  301. };
  302. this.results.push(result);
  303. return result;
  304. }
  305. _grepBaseTitlePath() {
  306. const path = [];
  307. this.parent._collectGrepTitlePath(path);
  308. path.push(this.title);
  309. return path;
  310. }
  311. _grepTitleWithTags() {
  312. const path = this._grepBaseTitlePath();
  313. path.push(...this._tags);
  314. return path.join(" ");
  315. }
  316. }
  317. // Annotate the CommonJS export names for ESM import in node:
  318. 0 && (module.exports = {
  319. Suite,
  320. TestCase
  321. });