Skip to main content

TestRail Import & Advisory

Migrate a manual TestRail suite into Proofarc in two steps: preview (score every case on how ready it is to automate — creates nothing) and import (turn the selected cases into runnable API scenarios / UI test skeletons). Works from a standard TestRail CSV export — columns are matched by name, so re-ordered or renamed exports still parse.

1. Preview — the automatability advisory

POST /api/testrail/preview { "csv": "<raw CSV text>" }
MCP: preview_testrail_import(csv, full=False)

Every case gets a band:

BandMeaningImport behavior
READYconcrete HTTP call or UI action extracted, checkable expected resultimported by default
NEEDS_WORKautomatable but missing something (selectors, concrete steps) — comes with fixesonly when explicitly selected via case_ids
MANUALnothing to build from (vague/no steps)skipped, with the reason

The preview also returns structure advice across the whole set: shared login preconditions ("extract one reusable setup, bind credentials via credentialTag"), section → suite mapping, near-duplicate titles, and CRUD coverage gaps per section.

What the parser understands

  • Prose or terse stepsSend a POST request to /auth/login and POST /auth/login both extract the method + path (up to a few filler words between verb and path).
  • Multi-row "separated steps" exports — continuation rows (empty ID/Title) merge into the parent case.
  • Numbered steps1. … 2. … split into individual steps.
  • Bodies and status codes — a JSON body in a step becomes the request body; a status code in the Expected Result becomes the assertion (Response is 201 → expect 201).
  • Unknown columns are reported, never silently dropped (unknownHeaders in the response).

Example CSV (standard export shape)

ID,Title,Section,Type,Priority,References,Preconditions,Steps,Expected Result
C1001,Login returns a JWT,User API > Auth,Functional,Critical,JIRA-401,API reachable,"1. POST /auth/login with {""username"":""admin"",""password"":""admin123""}","Response is 200 and body contains a non-empty accessToken"
C1004,Create a user,User API > Users,Functional,Critical,,Valid bearer token,"Send a POST request to /api/users with {""username"":""testuser""}","Response is 201, body has an id"

2. Import — create runnable tests

POST /api/testrail/import { "csv": "...", "projectId": 1, "environmentId": 2, "targetId": 3, "caseIds": ["C1001"] }
MCP: import_testrail_cases(csv, project, case_ids=None, environment=None, target=None)
  • case_ids empty → all READY cases import; pass ids explicitly to force a NEEDS_WORK case.
  • API cases become API scenarios; UI cases become UI test skeletons (selectors marked TODO — crawl the target to fill them).
  • Every created test is tagged testrail:Cxxxx for traceability back to the suite.
  • Skipped cases are returned with the reason — nothing is dropped silently.

Host & application binding

Pass target (+ environment) and the import binds each scenario to that target's application — no base_url is stored. The host resolves at run time from the environment's target, so imported tests run against dev/staging/prod without editing (see Creating Scenarios → Choosing the base URL). This binding is correct in multi-application projects: the scenario gets the target's app, not the project's first one.

After import

  1. find_scenarios(tags=["testrail:C1001"]) — locate the imported tests.
  2. Execute one against the environment to confirm the flow end-to-end.
  3. For UI skeletons: crawl the target, replace the TODO selectors, then run.
  4. Auth: follow the advisory — bind a credentialTag instead of hardcoding credentials from the Preconditions text.