update_test_steps
Update existing test steps on a test case version. Provide step IDs and new step details, expected results, or test data. Returns the updated step objects.
Instructions
Update existing test steps on a test case version. Each step must include its step id (from create_test_steps or get_test_case response). Returns the updated step objects.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Test case ID | |
| versionNo | Yes | Test case version number | |
| steps | Yes | Steps to update |
Implementation Reference
- src/index.ts:335-341 (handler)The async handler that performs PUT request to update test steps for a given test case version. Receives id, versionNo, and steps, then sends them to the API endpoint.
async ({ id, versionNo, steps }) => ok( await qtmFetch(`/testcases/${id}/versions/${versionNo}/teststeps`, { method: "PUT", body: JSON.stringify(steps), }) ) - src/index.ts:321-334 (schema)Zod schema defining the input parameters for update_test_steps: id (union string|number), versionNo (integer), and steps (array of objects with id, stepDetails, expectedResult, testData).
{ id: ID.describe("Test case ID"), versionNo: z.number().int().describe("Test case version number"), steps: z .array( z.object({ id: z.number().int().describe("Step ID to update"), stepDetails: z.string().optional(), expectedResult: z.string().optional(), testData: z.string().optional(), }) ) .describe("Steps to update"), }, - src/index.ts:318-342 (registration)Registration of the 'update_test_steps' tool via the 'tool' wrapper which calls server.registerTool with the name, description, schema, and callback handler.
tool( "update_test_steps", "Update existing test steps on a test case version. Each step must include its step id (from create_test_steps or get_test_case response). Returns the updated step objects.", { id: ID.describe("Test case ID"), versionNo: z.number().int().describe("Test case version number"), steps: z .array( z.object({ id: z.number().int().describe("Step ID to update"), stepDetails: z.string().optional(), expectedResult: z.string().optional(), testData: z.string().optional(), }) ) .describe("Steps to update"), }, async ({ id, versionNo, steps }) => ok( await qtmFetch(`/testcases/${id}/versions/${versionNo}/teststeps`, { method: "PUT", body: JSON.stringify(steps), }) ) ); - src/index.ts:69-73 (helper)The 'ok' helper function wraps API response data into the MCP content structure expected by the tool callback.
function ok(data: unknown) { return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }], }; } - src/index.ts:25-66 (helper)The 'qtmFetch' helper function used by the tool handler to make HTTP requests to the QMetry API.
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; }