ScuttleBot

Source Blame History 329 lines
f7eb47b… lmata 1 "use strict";
f7eb47b… lmata 2 var __defProp = Object.defineProperty;
f7eb47b… lmata 3 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
f7eb47b… lmata 4 var __getOwnPropNames = Object.getOwnPropertyNames;
f7eb47b… lmata 5 var __hasOwnProp = Object.prototype.hasOwnProperty;
f7eb47b… lmata 6 var __export = (target, all) => {
f7eb47b… lmata 7 for (var name in all)
f7eb47b… lmata 8 __defProp(target, name, { get: all[name], enumerable: true });
f7eb47b… lmata 9 };
f7eb47b… lmata 10 var __copyProps = (to, from, except, desc) => {
f7eb47b… lmata 11 if (from && typeof from === "object" || typeof from === "function") {
f7eb47b… lmata 12 for (let key of __getOwnPropNames(from))
f7eb47b… lmata 13 if (!__hasOwnProp.call(to, key) && key !== except)
f7eb47b… lmata 14 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
f7eb47b… lmata 15 }
f7eb47b… lmata 16 return to;
f7eb47b… lmata 17 };
f7eb47b… lmata 18 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
f7eb47b… lmata 19 var testTree_exports = {};
f7eb47b… lmata 20 __export(testTree_exports, {
f7eb47b… lmata 21 TestTree: () => TestTree,
f7eb47b… lmata 22 sortAndPropagateStatus: () => sortAndPropagateStatus,
f7eb47b… lmata 23 statusEx: () => statusEx
f7eb47b… lmata 24 });
f7eb47b… lmata 25 module.exports = __toCommonJS(testTree_exports);
f7eb47b… lmata 26 class TestTree {
f7eb47b… lmata 27 constructor(rootFolder, rootSuite, loadErrors, projectFilters, pathSeparator, hideFiles) {
f7eb47b… lmata 28 this._treeItemById = /* @__PURE__ */ new Map();
f7eb47b… lmata 29 this._treeItemByTestId = /* @__PURE__ */ new Map();
f7eb47b… lmata 30 const filterProjects = projectFilters && [...projectFilters.values()].some(Boolean);
f7eb47b… lmata 31 this.pathSeparator = pathSeparator;
f7eb47b… lmata 32 this.rootItem = {
f7eb47b… lmata 33 kind: "group",
f7eb47b… lmata 34 subKind: "folder",
f7eb47b… lmata 35 id: rootFolder,
f7eb47b… lmata 36 title: "",
f7eb47b… lmata 37 location: { file: "", line: 0, column: 0 },
f7eb47b… lmata 38 duration: 0,
f7eb47b… lmata 39 parent: void 0,
f7eb47b… lmata 40 children: [],
f7eb47b… lmata 41 status: "none",
f7eb47b… lmata 42 hasLoadErrors: false
f7eb47b… lmata 43 };
f7eb47b… lmata 44 this._treeItemById.set(rootFolder, this.rootItem);
f7eb47b… lmata 45 const visitSuite = (project, parentSuite, parentGroup, mode) => {
f7eb47b… lmata 46 for (const suite of mode === "tests" ? [] : parentSuite.suites) {
f7eb47b… lmata 47 if (!suite.title) {
f7eb47b… lmata 48 visitSuite(project, suite, parentGroup, "all");
f7eb47b… lmata 49 continue;
f7eb47b… lmata 50 }
f7eb47b… lmata 51 let group = parentGroup.children.find((item) => item.kind === "group" && item.title === suite.title);
f7eb47b… lmata 52 if (!group) {
f7eb47b… lmata 53 group = {
f7eb47b… lmata 54 kind: "group",
f7eb47b… lmata 55 subKind: "describe",
f7eb47b… lmata 56 id: "suite:" + parentSuite.titlePath().join("
f7eb47b… lmata 57 // account for anonymous suites
f7eb47b… lmata 58 title: suite.title,
f7eb47b… lmata 59 location: suite.location,
f7eb47b… lmata 60 duration: 0,
f7eb47b… lmata 61 parent: parentGroup,
f7eb47b… lmata 62 children: [],
f7eb47b… lmata 63 status: "none",
f7eb47b… lmata 64 hasLoadErrors: false
f7eb47b… lmata 65 };
f7eb47b… lmata 66 this._addChild(parentGroup, group);
f7eb47b… lmata 67 }
f7eb47b… lmata 68 visitSuite(project, suite, group, "all");
f7eb47b… lmata 69 }
f7eb47b… lmata 70 for (const test of mode === "suites" ? [] : parentSuite.tests) {
f7eb47b… lmata 71 const title = test.title;
f7eb47b… lmata 72 let testCaseItem = parentGroup.children.find((t) => t.kind !== "group" && t.title === title);
f7eb47b… lmata 73 if (!testCaseItem) {
f7eb47b… lmata 74 testCaseItem = {
f7eb47b… lmata 75 kind: "case",
f7eb47b… lmata 76 id: "test:" + test.titlePath().join("
f7eb47b… lmata 77 title,
f7eb47b… lmata 78 parent: parentGroup,
f7eb47b… lmata 79 children: [],
f7eb47b… lmata 80 tests: [],
f7eb47b… lmata 81 location: test.location,
f7eb47b… lmata 82 duration: 0,
f7eb47b… lmata 83 status: "none",
f7eb47b… lmata 84 project: void 0,
f7eb47b… lmata 85 test: void 0,
f7eb47b… lmata 86 tags: test.tags
f7eb47b… lmata 87 };
f7eb47b… lmata 88 this._addChild(parentGroup, testCaseItem);
f7eb47b… lmata 89 }
f7eb47b… lmata 90 const result = test.results[0];
f7eb47b… lmata 91 let status = "none";
f7eb47b… lmata 92 if (result?.[statusEx] === "scheduled")
f7eb47b… lmata 93 status = "scheduled";
f7eb47b… lmata 94 else if (result?.[statusEx] === "running")
f7eb47b… lmata 95 status = "running";
f7eb47b… lmata 96 else if (result?.status === "skipped")
f7eb47b… lmata 97 status = "skipped";
f7eb47b… lmata 98 else if (result?.status === "interrupted")
f7eb47b… lmata 99 status = "none";
f7eb47b… lmata 100 else if (result && test.outcome() !== "expected")
f7eb47b… lmata 101 status = "failed";
f7eb47b… lmata 102 else if (result && test.outcome() === "expected")
f7eb47b… lmata 103 status = "passed";
f7eb47b… lmata 104 testCaseItem.tests.push(test);
f7eb47b… lmata 105 const testItem = {
f7eb47b… lmata 106 kind: "test",
f7eb47b… lmata 107 id: test.id,
f7eb47b… lmata 108 title: project.name,
f7eb47b… lmata 109 location: test.location,
f7eb47b… lmata 110 test,
f7eb47b… lmata 111 parent: testCaseItem,
f7eb47b… lmata 112 children: [],
f7eb47b… lmata 113 status,
f7eb47b… lmata 114 duration: test.results.length ? Math.max(0, test.results[0].duration) : 0,
f7eb47b… lmata 115 project
f7eb47b… lmata 116 };
f7eb47b… lmata 117 this._addChild(testCaseItem, testItem);
f7eb47b… lmata 118 this._treeItemByTestId.set(test.id, testItem);
f7eb47b… lmata 119 testCaseItem.duration = testCaseItem.children.reduce((a, b) => a + b.duration, 0);
f7eb47b… lmata 120 }
f7eb47b… lmata 121 };
f7eb47b… lmata 122 for (const projectSuite of rootSuite?.suites || []) {
f7eb47b… lmata 123 if (filterProjects && !projectFilters.get(projectSuite.title))
f7eb47b… lmata 124 continue;
f7eb47b… lmata 125 for (const fileSuite of projectSuite.suites) {
f7eb47b… lmata 126 if (hideFiles) {
f7eb47b… lmata 127 visitSuite(projectSuite.project(), fileSuite, this.rootItem, "suites");
f7eb47b… lmata 128 if (fileSuite.tests.length) {
f7eb47b… lmata 129 const defaultDescribeItem = this._defaultDescribeItem();
f7eb47b… lmata 130 visitSuite(projectSuite.project(), fileSuite, defaultDescribeItem, "tests");
f7eb47b… lmata 131 }
f7eb47b… lmata 132 } else {
f7eb47b… lmata 133 const fileItem = this._fileItem(fileSuite.location.file.split(pathSeparator), true);
f7eb47b… lmata 134 visitSuite(projectSuite.project(), fileSuite, fileItem, "all");
f7eb47b… lmata 135 }
f7eb47b… lmata 136 }
f7eb47b… lmata 137 }
f7eb47b… lmata 138 for (const loadError of loadErrors) {
f7eb47b… lmata 139 if (!loadError.location)
f7eb47b… lmata 140 continue;
f7eb47b… lmata 141 const fileItem = this._fileItem(loadError.location.file.split(pathSeparator), true);
f7eb47b… lmata 142 fileItem.hasLoadErrors = true;
f7eb47b… lmata 143 }
f7eb47b… lmata 144 }
f7eb47b… lmata 145 _addChild(parent, child) {
f7eb47b… lmata 146 parent.children.push(child);
f7eb47b… lmata 147 child.parent = parent;
f7eb47b… lmata 148 this._treeItemById.set(child.id, child);
f7eb47b… lmata 149 }
f7eb47b… lmata 150 filterTree(filterText, statusFilters, runningTestIds) {
f7eb47b… lmata 151 const tokens = filterText.trim().toLowerCase().split(" ");
f7eb47b… lmata 152 const filtersStatuses = [...statusFilters.values()].some(Boolean);
f7eb47b… lmata 153 const filter = (testCase) => {
f7eb47b… lmata 154 const titleWithTags = [...testCase.tests[0].titlePath(), ...testCase.tests[0].tags].join(" ").toLowerCase();
f7eb47b… lmata 155 if (!tokens.every((token) => titleWithTags.includes(token)) && !testCase.tests.some((t) => runningTestIds?.has(t.id)))
f7eb47b… lmata 156 return false;
f7eb47b… lmata 157 testCase.children = testCase.children.filter((test) => {
f7eb47b… lmata 158 return !filtersStatuses || runningTestIds?.has(test.test.id) || statusFilters.get(test.status);
f7eb47b… lmata 159 });
f7eb47b… lmata 160 testCase.tests = testCase.children.map((c) => c.test);
f7eb47b… lmata 161 return !!testCase.children.length;
f7eb47b… lmata 162 };
f7eb47b… lmata 163 const visit = (treeItem) => {
f7eb47b… lmata 164 const newChildren = [];
f7eb47b… lmata 165 for (const child of treeItem.children) {
f7eb47b… lmata 166 if (child.kind === "case") {
f7eb47b… lmata 167 if (filter(child))
f7eb47b… lmata 168 newChildren.push(child);
f7eb47b… lmata 169 } else {
f7eb47b… lmata 170 visit(child);
f7eb47b… lmata 171 if (child.children.length || child.hasLoadErrors)
f7eb47b… lmata 172 newChildren.push(child);
f7eb47b… lmata 173 }
f7eb47b… lmata 174 }
f7eb47b… lmata 175 treeItem.children = newChildren;
f7eb47b… lmata 176 };
f7eb47b… lmata 177 visit(this.rootItem);
f7eb47b… lmata 178 }
f7eb47b… lmata 179 _fileItem(filePath, isFile) {
f7eb47b… lmata 180 if (filePath.length === 0)
f7eb47b… lmata 181 return this.rootItem;
f7eb47b… lmata 182 const fileName = filePath.join(this.pathSeparator);
f7eb47b… lmata 183 const existingFileItem = this._treeItemById.get(fileName);
f7eb47b… lmata 184 if (existingFileItem)
f7eb47b… lmata 185 return existingFileItem;
f7eb47b… lmata 186 const parentFileItem = this._fileItem(filePath.slice(0, filePath.length - 1), false);
f7eb47b… lmata 187 const fileItem = {
f7eb47b… lmata 188 kind: "group",
f7eb47b… lmata 189 subKind: isFile ? "file" : "folder",
f7eb47b… lmata 190 id: fileName,
f7eb47b… lmata 191 title: filePath[filePath.length - 1],
f7eb47b… lmata 192 location: { file: fileName, line: 0, column: 0 },
f7eb47b… lmata 193 duration: 0,
f7eb47b… lmata 194 parent: parentFileItem,
f7eb47b… lmata 195 children: [],
f7eb47b… lmata 196 status: "none",
f7eb47b… lmata 197 hasLoadErrors: false
f7eb47b… lmata 198 };
f7eb47b… lmata 199 this._addChild(parentFileItem, fileItem);
f7eb47b… lmata 200 return fileItem;
f7eb47b… lmata 201 }
f7eb47b… lmata 202 _defaultDescribeItem() {
f7eb47b… lmata 203 let defaultDescribeItem = this._treeItemById.get("<anonymous>");
f7eb47b… lmata 204 if (!defaultDescribeItem) {
f7eb47b… lmata 205 defaultDescribeItem = {
f7eb47b… lmata 206 kind: "group",
f7eb47b… lmata 207 subKind: "describe",
f7eb47b… lmata 208 id: "<anonymous>",
f7eb47b… lmata 209 title: "<anonymous>",
f7eb47b… lmata 210 location: { file: "", line: 0, column: 0 },
f7eb47b… lmata 211 duration: 0,
f7eb47b… lmata 212 parent: this.rootItem,
f7eb47b… lmata 213 children: [],
f7eb47b… lmata 214 status: "none",
f7eb47b… lmata 215 hasLoadErrors: false
f7eb47b… lmata 216 };
f7eb47b… lmata 217 this._addChild(this.rootItem, defaultDescribeItem);
f7eb47b… lmata 218 }
f7eb47b… lmata 219 return defaultDescribeItem;
f7eb47b… lmata 220 }
f7eb47b… lmata 221 sortAndPropagateStatus() {
f7eb47b… lmata 222 sortAndPropagateStatus(this.rootItem);
f7eb47b… lmata 223 }
f7eb47b… lmata 224 flattenForSingleProject() {
f7eb47b… lmata 225 const visit = (treeItem) => {
f7eb47b… lmata 226 if (treeItem.kind === "case" && treeItem.children.length === 1) {
f7eb47b… lmata 227 treeItem.project = treeItem.children[0].project;
f7eb47b… lmata 228 treeItem.test = treeItem.children[0].test;
f7eb47b… lmata 229 treeItem.children = [];
f7eb47b… lmata 230 this._treeItemByTestId.set(treeItem.test.id, treeItem);
f7eb47b… lmata 231 } else {
f7eb47b… lmata 232 treeItem.children.forEach(visit);
f7eb47b… lmata 233 }
f7eb47b… lmata 234 };
f7eb47b… lmata 235 visit(this.rootItem);
f7eb47b… lmata 236 }
f7eb47b… lmata 237 shortenRoot() {
f7eb47b… lmata 238 let shortRoot = this.rootItem;
f7eb47b… lmata 239 while (shortRoot.children.length === 1 && shortRoot.children[0].kind === "group" && shortRoot.children[0].subKind === "folder")
f7eb47b… lmata 240 shortRoot = shortRoot.children[0];
f7eb47b… lmata 241 shortRoot.location = this.rootItem.location;
f7eb47b… lmata 242 this.rootItem = shortRoot;
f7eb47b… lmata 243 }
f7eb47b… lmata 244 fileNames() {
f7eb47b… lmata 245 const result = /* @__PURE__ */ new Set();
f7eb47b… lmata 246 const visit = (treeItem) => {
f7eb47b… lmata 247 if (treeItem.kind === "group" && treeItem.subKind === "file")
f7eb47b… lmata 248 result.add(treeItem.id);
f7eb47b… lmata 249 else
f7eb47b… lmata 250 treeItem.children.forEach(visit);
f7eb47b… lmata 251 };
f7eb47b… lmata 252 visit(this.rootItem);
f7eb47b… lmata 253 return [...result];
f7eb47b… lmata 254 }
f7eb47b… lmata 255 flatTreeItems() {
f7eb47b… lmata 256 const result = [];
f7eb47b… lmata 257 const visit = (treeItem) => {
f7eb47b… lmata 258 result.push(treeItem);
f7eb47b… lmata 259 treeItem.children.forEach(visit);
f7eb47b… lmata 260 };
f7eb47b… lmata 261 visit(this.rootItem);
f7eb47b… lmata 262 return result;
f7eb47b… lmata 263 }
f7eb47b… lmata 264 treeItemById(id) {
f7eb47b… lmata 265 return this._treeItemById.get(id);
f7eb47b… lmata 266 }
f7eb47b… lmata 267 collectTestIds(treeItem) {
f7eb47b… lmata 268 return collectTestIds(treeItem);
f7eb47b… lmata 269 }
f7eb47b… lmata 270 }
f7eb47b… lmata 271 function sortAndPropagateStatus(treeItem) {
f7eb47b… lmata 272 for (const child of treeItem.children)
f7eb47b… lmata 273 sortAndPropagateStatus(child);
f7eb47b… lmata 274 if (treeItem.kind === "group") {
f7eb47b… lmata 275 treeItem.children.sort((a, b) => {
f7eb47b… lmata 276 const fc = a.location.file.localeCompare(b.location.file);
f7eb47b… lmata 277 return fc || a.location.line - b.location.line;
f7eb47b… lmata 278 });
f7eb47b… lmata 279 }
f7eb47b… lmata 280 let allPassed = treeItem.children.length > 0;
f7eb47b… lmata 281 let allSkipped = treeItem.children.length > 0;
f7eb47b… lmata 282 let hasFailed = false;
f7eb47b… lmata 283 let hasRunning = false;
f7eb47b… lmata 284 let hasScheduled = false;
f7eb47b… lmata 285 for (const child of treeItem.children) {
f7eb47b… lmata 286 allSkipped = allSkipped && child.status === "skipped";
f7eb47b… lmata 287 allPassed = allPassed && (child.status === "passed" || child.status === "skipped");
f7eb47b… lmata 288 hasFailed = hasFailed || child.status === "failed";
f7eb47b… lmata 289 hasRunning = hasRunning || child.status === "running";
f7eb47b… lmata 290 hasScheduled = hasScheduled || child.status === "scheduled";
f7eb47b… lmata 291 }
f7eb47b… lmata 292 if (hasRunning)
f7eb47b… lmata 293 treeItem.status = "running";
f7eb47b… lmata 294 else if (hasScheduled)
f7eb47b… lmata 295 treeItem.status = "scheduled";
f7eb47b… lmata 296 else if (hasFailed)
f7eb47b… lmata 297 treeItem.status = "failed";
f7eb47b… lmata 298 else if (allSkipped)
f7eb47b… lmata 299 treeItem.status = "skipped";
f7eb47b… lmata 300 else if (allPassed)
f7eb47b… lmata 301 treeItem.status = "passed";
f7eb47b… lmata 302 }
f7eb47b… lmata 303 function collectTestIds(treeItem) {
f7eb47b… lmata 304 const testIds = /* @__PURE__ */ new Set();
f7eb47b… lmata 305 const locations = /* @__PURE__ */ new Set();
f7eb47b… lmata 306 const visit = (treeItem2) => {
f7eb47b… lmata 307 if (treeItem2.kind !== "test" && treeItem2.kind !== "case") {
f7eb47b… lmata 308 treeItem2.children.forEach(visit);
f7eb47b… lmata 309 return;
f7eb47b… lmata 310 }
f7eb47b… lmata 311 let fileItem = treeItem2;
f7eb47b… lmata 312 while (fileItem && fileItem.parent && !(fileItem.kind === "group" && fileItem.subKind === "file"))
f7eb47b… lmata 313 fileItem = fileItem.parent;
f7eb47b… lmata 314 locations.add(fileItem.location.file);
f7eb47b… lmata 315 if (treeItem2.kind === "case")
f7eb47b… lmata 316 treeItem2.tests.forEach((test) => testIds.add(test.id));
f7eb47b… lmata 317 else
f7eb47b… lmata 318 testIds.add(treeItem2.id);
f7eb47b… lmata 319 };
f7eb47b… lmata 320 visit(treeItem);
f7eb47b… lmata 321 return { testIds, locations };
f7eb47b… lmata 322 }
f7eb47b… lmata 323 const statusEx = Symbol("statusEx");
f7eb47b… lmata 324 // Annotate the CommonJS export names for ESM import in node:
f7eb47b… lmata 325 0 && (module.exports = {
f7eb47b… lmata 326 TestTree,
f7eb47b… lmata 327 sortAndPropagateStatus,
f7eb47b… lmata 328 statusEx
f7eb47b… lmata 329 });

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button