list-test-cases
Retrieve test cases from a qTest module using module ID and optional filters for properties like Type, Status, or Priority.
Instructions
Test Design — fetch test cases from a qTest module with optional property filters (Type, Status, Priority, version, etc.). Requires moduleId (numeric).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Numeric project ID as string | |
| moduleId | Yes | Numeric ID of the module | |
| filters | No | Filter by fields (AND logic); omit to return all |
Implementation Reference
- The getTestCases function is the handler for the list-test-cases tool. It fetches test cases from qTest API with pagination, then optionally filters by top-level fields (e.g., version, name) or custom properties (e.g., Type, Status, Priority) using case-insensitive AND logic.
export async function getTestCases(args: GetTestCasesArgs): Promise<QTestTestCase[]> { const { projectId, moduleId: resolvedModuleId, filters } = args const all: QTestTestCase[] = [] let page = 1 while (true) { const raw = await qtestFetch( config, projectId, `/test-cases?parentId=${resolvedModuleId}&parentType=module&page=${page}&size=100`, 'GET' ) const batch = extractArray<QTestTestCase>(raw) all.push(...batch) if (batch.length < 100) break page++ } if (!filters || filters.length === 0) return all return all.filter((tc) => filters.every((filter) => { const fieldNameLower = filter.field.toLowerCase() const filterValueLower = filter.value.toLowerCase() // Check top-level fields first (e.g. version, name, pid) const topLevelMatch = Object.entries(tc).find( ([k]) => k.toLowerCase() === fieldNameLower ) if (topLevelMatch) { return String(topLevelMatch[1] ?? '').toLowerCase() === filterValueLower } // Fall back to properties array const prop = tc.properties?.find( (p: QTestProperty) => p.field_name.toLowerCase() === fieldNameLower ) if (!prop) return false return prop.field_value_name.toLowerCase() === filterValueLower }) ) } - GetTestCasesArgs interface defines the input schema: projectId (string), moduleId (number), and an optional filters array with field/value pairs.
export interface GetTestCasesArgs { projectId: string moduleId: number filters?: Array<{ field: string; value: string }> } - src/server.ts:19-42 (registration)Registration of the 'list-test-cases' tool using server.registerTool with Zod input schema and a handler that calls getTestCases and returns JSON text content.
server.registerTool( 'list-test-cases', { description: 'Test Design — fetch test cases from a qTest module with optional property filters (Type, Status, Priority, version, etc.). Requires moduleId (numeric).', inputSchema: { projectId: z.string().describe('Numeric project ID as string'), moduleId: z.number().int().describe('Numeric ID of the module'), filters: z .array( z.object({ field: z.string().describe('Field name — top-level (e.g. "version") or property (e.g. "Type", "Status")'), value: z.string().describe('Value to match (case-insensitive)'), }) ) .optional() .describe('Filter by fields (AND logic); omit to return all'), }, }, async ({ projectId, moduleId, filters }) => { const result = await getTestCases({ projectId, moduleId, filters }) return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] } } ) - src/client.ts:31-56 (helper)qtestFetch helper used by getTestCases to make authenticated HTTP requests to the qTest API.
export async function qtestFetch( config: QTestConfig, projectId: string, endpoint: string, method: 'GET' | 'POST' | 'DELETE', body?: unknown ): Promise<unknown> { const url = `${config.baseUrl}/api/v3/projects/${projectId}${endpoint}` const response = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.token}`, }, body: body !== undefined ? JSON.stringify(body) : undefined, }) if (!response.ok) { const text = await response.text() throw new Error(`HTTP ${response.status}: ${text}`) } if (response.status === 204 || response.headers.get('content-length') === '0') { return null } const text = await response.text() return text ? JSON.parse(text) : null } - src/client.ts:58-67 (helper)extractArray helper used to parse the API response into an array of QTestTestCase objects.
export function extractArray<T>(raw: unknown): T[] { if (Array.isArray(raw)) return raw as T[] if (raw && typeof raw === 'object') { for (const key of ['items', 'data', 'object'] as const) { const val = (raw as Record<string, unknown>)[key] if (Array.isArray(val)) return val as T[] } } return [] }