status, duration: test.results.length ? Math.max(0, test.results[0].duration) : 0, project }; this._addChild(testCaseItem, testItem); this._treeItemByTestId.set(test.id, testItem); testCaseItem.duration = testCaseItem.children.reduce((a, b) => a + b.duration, 0); } }; for (const projectSuite of rootSuite?.suites || []) { if (filterProjects && !projectFilters.get(projectSuite.title)) continue; for (const fileSuite of projectSuite.suites) { const fileItem = this._fileItem(fileSuite.location.file.split(pathSeparator), true); visitSuite(projectSuite.project(), fileSuite, fileItem); } } for (const loadError of loadErrors) { if (!loadError.location) continue; const fileItem = this._fileItem(loadError.location.file.split(pathSeparator), true); fileItem.hasLoadErrors = true; } } _addChild(parent, child) { parent.children.push(child); child.parent = parent; this._treeItemById.set(child.id, child); } filterTree(filterText, statusFilters, runningTestIds) { const tokens = filterText.trim().toLowerCase().split(" "); const filtersStatuses = [...statusFilters.values()].some(Boolean); const filter = (testCase) => { const titleWithTags = [...testCase.tests[0].titlePath(), ...testCase.tests[0].tags].join(" ").toLowerCase(); if (!tokens.every((token) => titleWithTags.includes(token)) && !testCase.tests.some((t) => runningTestIds?.has(t.id))) return false; testCase.children = testCase.children.filter((test) => { return !filtersStatuses || runningTestIds?.has(test.test.id) || statusFilters.get(test.status); }); testCase.tests = testCase.children.map((c) => c.test); return !!testCase.children.length; }; const visit = (treeItem) => { const newChildren = []; for (const child of treeItem.children) { if (child.kind === "case") { if (filter(child)) newChildren.push(child); } else { visit(child); if (child.children.length || child.hasLoadErrors) newChildren.push(child); } } treeItem.children = newChildren; }; visit(this.rootItem); } _fileItem(filePath, isFile) { if (filePath.length === 0) return this.rootItem; const fileName = filePath.join(this.pathSeparator); const existingFileItem = this._treeItemById.get(fileName); if (existingFileItem) return existingFileItem; const parentFileItem = this._fileItem(filePath.slice(0, filePath.length - 1), false); const fileItem = { kind: "group", subKind: isFile ? "file" : "folder", id: fileName, title: filePath[filePath.length - 1], location: { file: fileName, line: 0, column: 0 }, duration: 0, parent: parentFileItem, children: [], status: "none", hasLoadErrors: false }; this._addChild(parentFileItem, fileItem); return fileItem; } sortAndPropagateStatus() { sortAndPropagateStatus(this.rootItem); } flattenForSingleProject() { const visit = (treeItem) => { if (treeItem.kind === "case" && treeItem.children.length === 1) { treeItem.project = treeItem.children[0].project; treeItem.test = treeItem.children[0].test; treeItem.children = []; this._treeItemByTestId.set(treeItem.test.id, treeItem); } else { treeItem.children.forEach(visit); } }; visit(this.rootItem); } shortenRoot() { let shortRoot = this.rootItem; while (shortRoot.children.length === 1 && shortRoot.children[0].kind === "group" && shortRoot.children[0].subKind === "folder") shortRoot = shortRoot.children[0]; shortRoot.location = this.rootItem.location; this.rootItem = shortRoot; } testIds() { const result = /* @__PURE__ */ new Set(); const visit = (treeItem) => { if (treeItem.kind === "case") treeItem.tests.forEach((t) => result.add(t.id)); treeItem.children.forEach(visit); }; visit(this.rootItem); return result; } fileNames() { const result = /* @__PURE__ */ new Set(); const visit = (treeItem) => { if (treeItem.kind === "group" && treeItem.subKind === "file") result.add(treeItem.id); else treeItem.children.forEach(visit); }; visit(this.rootItem); return [...result]; } flatTreeItems() { const result = []; const visit = (treeItem) => { result.push(treeItem); treeItem.children.forEach(visit); }; visit(this.rootItem); return result; } treeItemById(id) { return this._treeItemById.get(id); } collectTestIds(treeItem) { return treeItem ? collectTestIds(treeItem) : /* @__PURE__ */ new Set(); } } function sortAndPropagateStatus(treeItem) { for (const child of treeItem.children) sortAndPropagateStatus(child); if (treeItem.kind === "group") { treeItem.children.sort((a, b) => { const fc = a.location.file.localeCompare(b.location.file); return fc || a.location.line - b.location.line; }); } let allPassed = treeItem.children.length > 0; let allSkipped = treeItem.children.length > 0; let hasFailed = false; let hasRunning = false; let hasScheduled = false; for (const child of treeItem.children) { allSkipped = allSkipped && child.status === "skipped"; allPassed = allPassed && (child.status === "passed" || child.status === "skipped"); hasFailed = hasFailed || child.status === "failed"; hasRunning = hasRunning || child.status === "running"; hasScheduled = hasScheduled || child.status === "scheduled"; } if (hasRunning) treeItem.status = "running"; else if (hasScheduled) treeItem.status = "scheduled"; else if (hasFailed) treeItem.status = "failed"; else if (allSkipped) treeItem.status = "skipped"; else if (allPassed) treeItem.status = "passed"; } function collectTestIds(treeItem) { const testIds = /* @__PURE__ */ new Set(); const visit = (treeItem2) => { if (treeItem2.kind === "case") treeItem2.tests.map((t) => t.id).forEach((id) => testIds.add(id)); else if (treeItem2.kind === "test") testIds.add(treeItem2.id); else treeItem2.children?.forEach(visit); }; visit(treeItem); return testIds; } const statusEx = Symbol("statusEx"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { TestTree, collectTestIds, sortAndPropagateStatus, statusEx });