create_test_steps
Add one or more test steps to a specific version of a test case. Each step requires step details, with optional expected result and test data. Returns created step IDs.
Instructions
Add one or more test steps to a specific version of a test case. Each step has stepDetails (required), expectedResult, and testData. Returns the created step objects with their IDs.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Test case ID | |
| versionNo | Yes | Test case version number | |
| steps | Yes | Steps to create |
Implementation Reference
- src/index.ts:293-316 (registration)The tool 'create_test_steps' is registered using the local 'tool()' wrapper (lines 172-184) which calls server.registerTool. It is defined at lines 293-316 with name 'create_test_steps', description, input schema, and handler callback all inline.
tool( "create_test_steps", "Add one or more test steps to a specific version of a test case. Each step has stepDetails (required), expectedResult, and testData. Returns the created step objects with their IDs.", { id: ID.describe("Test case ID"), versionNo: z.number().int().describe("Test case version number"), steps: z .array( z.object({ stepDetails: z.string().describe("Step action/description"), expectedResult: z.string().optional(), testData: z.string().optional(), }) ) .describe("Steps to create"), }, async ({ id, versionNo, steps }) => ok( await qtmFetch(`/testcases/${id}/versions/${versionNo}/teststeps`, { method: "POST", body: JSON.stringify(steps), }) ) ); - src/index.ts:309-316 (handler)The handler function for 'create_test_steps'. It is an async callback that destructures { id, versionNo, steps } from the input, then makes a POST request to /testcases/{id}/versions/{versionNo}/teststeps with the steps array as the JSON body. The response is wrapped via the ok() helper to produce MCP content.
async ({ id, versionNo, steps }) => ok( await qtmFetch(`/testcases/${id}/versions/${versionNo}/teststeps`, { method: "POST", body: JSON.stringify(steps), }) ) ); - src/index.ts:296-308 (schema)The input schema for 'create_test_steps', defined as a Zod object. It requires: id (string|number union), versionNo (integer), and steps (array of objects each with required stepDetails string and optional expectedResult/testData strings).
{ id: ID.describe("Test case ID"), versionNo: z.number().int().describe("Test case version number"), steps: z .array( z.object({ stepDetails: z.string().describe("Step action/description"), expectedResult: z.string().optional(), testData: z.string().optional(), }) ) .describe("Steps to create"), }, - src/index.ts:69-73 (helper)The ok() helper wraps an API response into the MCP content format (content array with a single text block containing JSON). It is used by the create_test_steps handler to format the response.
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 is the HTTP fetch abstraction used by create_test_steps to make the API call. It handles authentication via apiKey header, JSON parsing, and retry with exponential backoff on 429 rate limiting.
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; }