update_test_step_execution
Update a single test step execution result within a test case execution by specifying the test cycle ID and step execution ID to modify execution result, actual result, or comment.
Instructions
Update a single step-level execution result within a test case execution. testStepExecutionId comes from get_test_cycle_executions step data. Returns 200 with updated step data.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cycleId | Yes | Test cycle ID | |
| testStepExecutionId | Yes | Test step execution ID | |
| executionResultId | No | Execution result ID | |
| actualResult | No | Actual result text | |
| comment | No |
Implementation Reference
- src/index.ts:462-479 (handler)The handler function that executes the 'update_test_step_execution' tool logic. It calls qtmFetch with PUT to /testcycles/{cycleId}/teststep-executions/{testStepExecutionId} and returns the updated step data.
tool( "update_test_step_execution", "Update a single step-level execution result within a test case execution. testStepExecutionId comes from get_test_cycle_executions step data. Returns 200 with updated step data.", { cycleId: ID.describe("Test cycle ID"), testStepExecutionId: ID.describe("Test step execution ID"), executionResultId: z.number().int().optional().describe("Execution result ID"), actualResult: z.string().optional().describe("Actual result text"), comment: z.string().optional(), }, async ({ cycleId, testStepExecutionId, ...rest }) => { const data = await qtmFetch( `/testcycles/${cycleId}/teststep-executions/${testStepExecutionId}`, { method: "PUT", body: JSON.stringify(rest) } ); return ok(data ?? { message: `Step execution ${testStepExecutionId} updated` }); } ); - src/index.ts:465-471 (schema)Input schema for the tool, defining parameters: cycleId (ID), testStepExecutionId (ID), executionResultId (optional int), actualResult (optional string), and comment (optional string).
{ cycleId: ID.describe("Test cycle ID"), testStepExecutionId: ID.describe("Test step execution ID"), executionResultId: z.number().int().optional().describe("Execution result ID"), actualResult: z.string().optional().describe("Actual result text"), comment: z.string().optional(), }, - src/index.ts:171-184 (registration)The 'tool' wrapper function that registers tools via server.registerTool. The 'update_test_step_execution' tool is registered through this helper at line 462-479.
/** Thin wrapper around registerTool for concise, non-deprecated tool registration. */ const tool = <Shape extends z.ZodRawShape>( name: string, description: string, inputSchema: Shape, // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (args: z.infer<z.ZodObject<Shape>>) => Promise<any> ) => server.registerTool( name, { description, inputSchema }, // eslint-disable-next-line @typescript-eslint/no-explicit-any callback as any ); - src/index.ts:25-66 (helper)The qtmFetch helper function used by the handler to make HTTP requests to the QMetry API with retry logic for rate limiting (429).
async function qtmFetch( path: string, options: RequestInit = {}, attempt = 1 ): Promise<unknown> { const url = `${BASE_URL}${path}`; const headers: Record<string, string> = { apiKey: API_KEY ?? "", "Content-Type": "application/json", Accept: "application/json", ...(options.headers as Record<string, string> | undefined), }; const response = await fetch(url, { ...options, headers }); // Exponential back-off for rate limiting (max 3 attempts) if (response.status === 429 && attempt < 3) { const retryAfter = Number.parseInt( response.headers.get("Retry-After") ?? "1", 10 ); const delay = Math.max(retryAfter * 1000, 1000) * attempt; await new Promise((r) => setTimeout(r, delay)); return qtmFetch(path, options, attempt + 1); } const text = await response.text(); let body: unknown; try { body = text ? JSON.parse(text) : null; } catch { body = text; } if (!response.ok) { throw new Error( `HTTP ${response.status} ${response.statusText}: ${JSON.stringify(body)}` ); } return body; } - src/index.ts:69-73 (helper)The 'ok' helper function that wraps API responses into MCP tool content format used by the handler to return results.
function ok(data: unknown) { return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], }; }