"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var testTree_exports = {}; __export(testTree_exports, { TestTree: () => TestTree, collectTestIds: () => collectTestIds, sortAndPropagateStatus: () => sortAndPropagateStatus, statusEx: () => statusEx }); module.exports = __toCommonJS(testTree_exports); class TestTree { constructor(rootFolder, rootSuite, loadErrors, projectFilters, pathSeparator) { this._treeItemById = /* @__PURE__ */ new Map(); this._treeItemByTestId = /* @__PURE__ */ new Map(); const filterProjects = projectFilters && [...projectFilters.values()].some(Boolean); this.pathSeparator = pathSeparator; this.rootItem = { kind: "group", subKind: "folder", id: rootFolder, title: "", location: { file: "", line: 0, column: 0 }, duration: 0, parent: void 0, children: [], status: "none", hasLoadErrors: false }; this._treeItemById.set(rootFolder, this.rootItem); const visitSuite = (project, parentSuite, parentGroup) => { for (const suite of parentSuite.suites) { if (!suite.title) { visitSuite(project, suite, parentGroup); continue; } let group = parentGroup.children.find((item) => item.kind === "group" && item.title === suite.title); if (!group) { group = { kind: "group", subKind: "describe", id: "suite:" + parentSuite.titlePath().join("") + "" + suite.title, // account for anonymous suites title: suite.title, location: suite.location, duration: 0, parent: parentGroup, children: [], status: "none", hasLoadErrors: false }; this._addChild(parentGroup, group); } visitSuite(project, suite, group); } for (const test of parentSuite.tests) { const title = test.title; let testCaseItem = parentGroup.children.find((t) => t.kind !== "group" && t.title === title); if (!testCaseItem) { testCaseItem = { kind: "case", id: "test:" + test.titlePath().join(""), title, parent: parentGroup, children: [], tests: [], location: test.location, duration: 0, status: "none", project: void 0, test: void 0, tags: test.tags }; this._addChild(parentGroup, testCaseItem); } const result = test.results[0]; let status = "none"; if (result?.[statusEx] === "scheduled") status = "scheduled"; else if (result?.[statusEx] === "running") status = "running"; else if (result?.status === "skipped") status = "skipped"; else if (result?.status === "interrupted") status = "none"; else if (result && test.outcome() !== "expected") status = "failed"; else if (result && test.outcome() === "expected") status = "passed"; testCaseItem.tests.push(test); const testItem = { kind: "test", id: test.id, title: project.name, location: test.location, test, parent: testCaseItem, children: [], 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 });