Skip to content

feat(testmanagement): create test cases with a custom template (template_id) + listTestCaseTemplates#328

Merged
gaurav-singh-9227 merged 1 commit into
mainfrom
feat/testcase-template-id-custom-templates
Jun 26, 2026
Merged

feat(testmanagement): create test cases with a custom template (template_id) + listTestCaseTemplates#328
gaurav-singh-9227 merged 1 commit into
mainfrom
feat/testcase-template-id-custom-templates

Conversation

@gaurav-singh-9227

@gaurav-singh-9227 gaurav-singh-9227 commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

What & why

Follow-up to #319 (which added a template param that only selects system templates). This adds the ability to create a test case with a custom template, plus a way to discover template ids. Both verified end-to-end against prod.

The key finding

A custom template can only be selected by numeric template_id — the template slug only ever picks a system template (step_type is constrained to test_case_steps/test_case_bdd and isn't unique).

createTestCase therefore routes to the v1 create endpoint when a template_id is supplied (it honours the id), and keeps using the v2 endpoint otherwise.

Why not the documented v2 endpoint?

The natural choice would be the documented v2 create (POST /api/v2/projects/{id}/folders/{folder_id}/test-cases). It cannot apply a custom template, confirmed two ways:

1. No template-selection field exists in the v2 contract. The documented request body is name, description, owner, preconditions, test_case_steps, issues, issue_tracker, tags, case_type, priority, custom_fields. There is no template_id / template_name. The only documented template value is "test_case_bdd" — a system step-type, not a custom template.

2. v2 silently ignores template_id at runtime. A direct call with a valid, project-linked custom template id returns HTTP 200 success:true, but the field is dropped — the case is created with the default template:

POST /api/v2/projects/PR-…/folders/…/test-cases
Body: {"test_case":{"name":"…","template_id":656127,"test_case_steps":[…]}}

→ HTTP 200, success:true
   response.template_id : <absent>
   response.template    : "test_case_steps"
   read-back template_id: 2   (default — NOT the requested 656127)

Tested across placements — template_id inside test_case, template_id as a top-level sibling, and template set to the numeric id string — all produced the default template. So this is not a payload-shape issue; the v2 endpoint does not carry template selection at all.

v1 is the only public endpoint that honours template_id (it is also the endpoint the TM web dashboard itself uses for template-based creates), so the PR uses v1 for that path only.

How v1 is wired in

  • When template_id is set → POST /api/v1/projects/{numericId}/test-cases (API-TOKEN auth, folder carried in the body). Same user credentials as the rest of the server (getBrowserStackAuth(config)), same API-TOKEN header style already used by form-fields-v2 / project lookup / TCG calls.
  • v1 keys custom_fields by id with option ids, whereas v2 keys by name with values — so on the v1 path we translate the by-name shape → v1's by-id shape via the project's form fields, keeping multi-select custom fields working alongside a template.
  • With no template_id, the proven v2 path is unchanged — zero regression for the common case.
  • A post-create read-back warns if the applied template differs from the request — so if v2 ever gains template_id support (see below) and we migrate back, any regression surfaces loudly instead of silently.

Changes

  • list-templates.tslistTestCaseTemplates tool → GET /api/v1/admin-v2/settings/templates?entity_type=TestCase (API-TOKEN), client-side name filter.
  • create-testcase.tstemplate_id param; v1 routing when set; toV1CustomFields translation; post-create read-back warning.

Testing

npm run build green — lint, format, tsc, and 198 tests pass.

Existing tests (sanity)

The pre-existing testmanagement suite is unchanged and still green — notably the v2 default create path, priority normalization, the template system-slug pass-through + silent-fallback warning, and the multi-select custom_fields-by-name behaviour from #319 all continue to pass (this PR leaves the no-template_id path entirely on v2).

New tests (9)

createTestCasetemplate_id routing & verification (6)

  1. passes template_id through to the request body and does not warn when appliedtemplate_id reaches body.test_case.template_id; no mismatch warning when the applied template equals the requested one.
  2. warns when the API applies a different template_id than requested — if the created case comes back with a different template_id, the tool surfaces a clear mismatch warning instead of reporting plain success.
  3. does not emit the slug warning when template_id is supplied (id takes precedence) — the template system-slug fallback warning is suppressed when template_id is present, so the two paths don't double-warn.
  4. reads the case back and warns when template_id is omitted from the create response but not applied — the real create response has no template_id, so the tool re-reads the case via the v1 search endpoint and warns when the applied template differs (covers the silent-miss failure mode).
  5. routes to the v1 create endpoint with API-TOKEN auth when template_id is set — asserts the request targets /api/v1/projects/{id}/test-cases with the API-TOKEN header (not v2 + Basic), the folder is carried in the body (folder_id top-level and test_case.test_case_folder_id), and MCP-only params (project_identifier, folder_id) do not leak into the test_case payload.
  6. translates custom_fields name→id and option value→id on the v1 path — with form fields mocked, { aaas: ["m40","m48"] } (v2/by-name shape) is rewritten to { 194184: [111, 222] } (v1/by-id shape) in the request body.

listTestCaseTemplates (3)

  1. queries the admin-v2 templates endpoint with API-TOKEN auth and surfaces ids — hits GET /api/v1/admin-v2/settings/templates?entity_type=TestCase with the API-TOKEN header and returns each template's numeric id and name.
  2. filters by name client-side — a name argument narrows the returned list (matching template kept, non-matching default dropped) and the count reflects the filtered set.
  3. reports when no templates match the name filter — returns a clear No templates matching "…" message rather than an empty/confusing result.

End-to-end verification (prod, throwaway folder, deleted after)

Path Result
listTestCaseTemplates via compiled tool returned real templates with ids ✅
createTestCase with a custom template_id applied that template (not the default) ✅
createTestCase with template_id + multi-select custom_fields + priority + tags + steps applied the requested template and both custom-field values, plus priority/tags/steps — isError:false
createTestCase with an invalid template_id rejected with a clear error, nothing created (no silent fallback) ✅
createTestCase with no template_id (v2 path) unchanged ✅

Server boots clean and registers all tools.

Notes / limitations / follow-up

  • The v1 create endpoint is undocumented (though it is what the TM dashboard uses); the read-back warning guards against silent regression. Follow-up: request template_id support on the documented v2 create so this path can move back to v2.
  • BDD custom templates would also need feature/scenario fields on the schema (today's schema is steps-oriented) — out of scope.

@gaurav-singh-9227 gaurav-singh-9227 marked this pull request as draft June 25, 2026 10:32
@gaurav-singh-9227 gaurav-singh-9227 changed the title feat(testmanagement): select custom templates via template_id + listTestCaseTemplates [BLOCKED on TM backend] testmanagement: custom-template selection not possible via public API Jun 25, 2026
@gaurav-singh-9227 gaurav-singh-9227 changed the title [BLOCKED on TM backend] testmanagement: custom-template selection not possible via public API testmanagement: list templates (works) + template_id on create (blocked on TM gateway) Jun 25, 2026
@gaurav-singh-9227 gaurav-singh-9227 marked this pull request as ready for review June 25, 2026 13:08
@gaurav-singh-9227 gaurav-singh-9227 changed the title testmanagement: list templates (works) + template_id on create (blocked on TM gateway) feat(testmanagement): create test cases with a custom template (template_id) + listTestCaseTemplates Jun 25, 2026
…TestCaseTemplates

Follow-up to #319, which added a `template` param that only ever selects a
SYSTEM template (the TM create logic maps the slug to {is_system, step_type},
and step_type is constrained to test_case_steps/test_case_bdd and isn't unique).
A custom template is selectable only by its numeric template_id.

Two capabilities, both verified end-to-end against prod:

- listTestCaseTemplates: lists templates with their numeric ids via
  GET /api/v1/admin-v2/settings/templates?entity_type=TestCase (API-TOKEN auth),
  with a client-side name filter.

- createTestCase template_id: the public v2 create endpoint silently drops
  template_id, but the v1 create endpoint honours it. When template_id is set we
  route to POST /api/v1/projects/{numericId}/test-cases (API-TOKEN, folder in the
  body) and translate custom_fields from the by-name shape (v2) to v1's by-id
  shape (field name -> id, option value -> option id) so multi-select custom
  fields keep working alongside a template. With no template_id, the proven v2
  path is unchanged (zero regression). A post-create read-back warns if the
  applied template differs (e.g. id not linked to the project).

Verified live: create with template_id + multi-select custom_fields + priority
+ tags + steps applied all of them. Tests +6. npm run build green
(lint, format, tsc, tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gaurav-singh-9227 gaurav-singh-9227 force-pushed the feat/testcase-template-id-custom-templates branch from 3577e1e to 3939fb7 Compare June 25, 2026 14:06
@gaurav-singh-9227 gaurav-singh-9227 merged commit 412426c into main Jun 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants