get_suite_hierarchy
Retrieve hierarchical test suite structures from Zebrunner Test Case Management with configurable depth and output formats for project organization.
Instructions
๐ณ Get hierarchical test suite tree with configurable depth
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_key | Yes | Project key | |
| root_suite_id | No | Start from specific root suite | |
| max_depth | No | Maximum tree depth | |
| format | No | Output format | json |
| include_clickable_links | No | Include clickable links to Zebrunner web UI |
Implementation Reference
- src/handlers/tools.ts:146-196 (handler)Core handler function implementing the get_suite_hierarchy tool logic: fetches all suites, optionally filters descendants of a root suite, builds hierarchy tree using HierarchyProcessor, limits recursion depth, formats output, and handles errors.async getSuiteHierarchy(input: z.infer<typeof GetSuiteHierarchyInputSchema>) { const { projectKey, rootSuiteId, maxDepth, format } = input; try { const allSuites = await this.client.getAllTestSuites(projectKey); let suitesToProcess = allSuites; // Filter by root suite if specified if (rootSuiteId) { const descendants = HierarchyProcessor.getSuiteDescendants(rootSuiteId, allSuites); const rootSuite = allSuites.find(s => s.id === rootSuiteId); suitesToProcess = rootSuite ? [rootSuite, ...descendants] : descendants; } // Build hierarchical tree const hierarchyTree = HierarchyProcessor.buildSuiteTree(suitesToProcess); // Limit depth if specified const limitDepth = (suites: any[], currentDepth: number): any[] => { if (currentDepth >= maxDepth) { return suites.map(suite => ({ ...suite, children: [] })); } return suites.map(suite => ({ ...suite, children: suite.children ? limitDepth(suite.children, currentDepth + 1) : [] })); }; const limitedTree = limitDepth(hierarchyTree, 0); const formattedData = FormatProcessor.format(limitedTree, format); return { content: [ { type: "text" as const, text: typeof formattedData === 'string' ? formattedData : JSON.stringify(formattedData, null, 2) } ] }; } catch (error: any) { return { content: [ { type: "text" as const, text: `Error retrieving suite hierarchy: ${error.message}` } ] }; } }
- src/types/api.ts:112-117 (schema)Zod input schema defining parameters for the get_suite_hierarchy tool: projectKey (required), rootSuiteId (optional), maxDepth (default 5, max 10), format (default 'json').export const GetSuiteHierarchyInputSchema = z.object({ projectKey: z.string().min(1), rootSuiteId: z.number().int().positive().optional(), maxDepth: z.number().int().positive().max(10).default(5), format: z.enum(['dto', 'json', 'string']).default('json') });
- src/index-enhanced.ts:133-143 (registration)MCP server tool registration for 'get_suite_hierarchy', including inline schema validation and binding to ZebrunnerToolHandlers.getSuiteHierarchy method.server.tool( "get_suite_hierarchy", "Get hierarchical test suite tree with configurable depth", { projectKey: z.string().min(1), rootSuiteId: z.number().int().positive().optional(), maxDepth: z.number().int().positive().max(10).default(5), format: z.enum(['dto', 'json', 'string']).default('json') }, async (args) => toolHandlers.getSuiteHierarchy(args) );
- src/utils/hierarchy.ts:26-52 (helper)Key helper methods used by the handler: buildSuiteTree constructs the hierarchical tree from flat suite list, getSuiteDescendants retrieves all descendant suites for a given root suite ID.static buildSuiteTree(suites: ZebrunnerTestSuite[]): ZebrunnerTestSuite[] { const suiteMap = new Map<number, ZebrunnerTestSuite>(); const rootSuites: ZebrunnerTestSuite[] = []; // First pass: create map and initialize children arrays suites.forEach(suite => { suiteMap.set(suite.id, { ...suite, children: [] }); }); // Second pass: build parent-child relationships suites.forEach(suite => { const suiteWithChildren = suiteMap.get(suite.id)!; // Handle self-referencing suites (treat them as root suites) if (suite.parentSuiteId === suite.id) { console.error(`โ ๏ธ Self-referencing suite detected: ${suite.id} (${suite.title || suite.name})`); // Set parentSuiteId to null for self-referencing suites suiteWithChildren.parentSuiteId = null; rootSuites.push(suiteWithChildren); } else if (suite.parentSuiteId && suiteMap.has(suite.parentSuiteId)) { const parent = suiteMap.get(suite.parentSuiteId)!; parent.children = parent.children || []; parent.children.push(suiteWithChildren); } else { rootSuites.push(suiteWithChildren); } });