uipath-test · git:20261106.9222806 · 2026-11-06 · sha256 6991a07d5c75402b
uipath-test git:20261106.9222806A
Immutable. This exact content never changes and is served at /api/v1/blob/6991a07d5c75402b.
---
name: uipath-test
description: "UiPath Test Manager (`uip tm`) — test projects, requirements, cases, sets, executions, logs, defects; recurring test set schedules; AI test case generation, requirement evaluation, obsolete test case search; CI run of every test in an uploaded package; performance (load) test scenarios; test reports; package/run external Playwright suites. Orchestrator→uipath-platform. Studio/RPA test authoring→uipath-rpa."
allowed-tools: Bash, Read, Write, Glob, Grep
user-invocable: true
---
# UiPath Test Assistant
Manage UiPath Test Manager projects, requirements (AI generation/evaluation/obsolete-case search), cases/sets, executions/logs, defects, attachments/results, custom fields, performance scenarios, labels, and persona-tailored reports.
## Use For
Use for Test Manager CRUD; CI runs of every test in an uploaded package; execution analysis, coverage, regression trends, failure rates, go/no-go summaries, failed-run triage, flaky-versus-regression analysis, failure evidence, load testing/failure diagnosis, and QA-engineer, developer, or release-manager reports.
When the request asks to operate Test Manager through its Integration Service connector (not `uip tm`), run `uip is resources run` per `/uipath-platform` (`references/integration-service/resources.md`). Building a `.flow`/`.bpmn`/API workflow that uses the connector→its authoring skill.
## Critical Rules
1. Before any Test Manager operation run `uip login status --output json`; if unauthenticated run `uip login`.
2. Pass `--output json` to every `uip` command.
3. Retry a failing `uip` command at most 3 times; after three failures stop and report the error. Never use REST.
4. An empty list stops and informs the user rather than proceeding with a null key. Exception: empty `tm testcases list --filter` may be a prefix miss; apply Rule 8 and stop only if that also finds nothing. Empty filtered project/customfield lookups are real empty results and stop normally.
5. Confirm a target key before deletion unless the user authorized that exact delete. Every delete requires `--yes` or `-y`; omission exits without deleting.
6. For a required named folder run `uip or folders list -n <folder-name> --all --output json`; when choosing a folder omit `--all` to list only member folders. Run `/uipath-platform` for folder details.
7. Discover before assuming: never guess automation names, folder keys, project IDs, or testcase keys; list first, e.g. `uip tm testcases list-automations` or `uip or folders list -n <folder-name> --all`.
8. Narrow named entities server-side. Inspect `uip tm <resource> list --help` or `uip or <resource> list --help` and use the narrowing flag; never list all and filter client-side. This applies to every `uip tm`/`uip or` entity and result filter: failed-run logs use `executions testcaselogs list --only-failed`; case failures use `testcases list-result-history --only-failed`. `tm testcases list --filter` is prefix matching. If a mid-name term returns zero, retry with a broader contextual prefix; relist without `--filter` only when no workable prefix exists, walking every page under Rule 11 before concluding absence.
9. `uip tm testcases run` and `uip tm testsets run` require a project default folder. Attempt the run first. Only when failure text exactly includes `"Message": "HTTP 400: Please assign folder to project level before executing testcases."` and `errorCode: itemNotFound`, run `uip tm project set-default-folder --project-key <PROJECT_KEY> --folder-key <FOLDER_KEY> --output json`, then retry once. Obtain keys with `uip or folders list -n <folder-name> --all --output json`. Never overwrite a working default. Do not interpret other errors as missing folders: an unusable default gives opaque `HTTP 5xx`; a nonexistent folder gives `"HTTP 400: Internal Server Error."` with `errorCode: unknown`; both stop under Rule 10. This is the only named run exception; all other run failures stop.
10. Any `uip` failure or ambiguity stops and asks the user: command errors, malformed output, unclear flags/values, multiple matches, missing identifiers, or unexpected schemas. Never use REST. Exceptions: (a) Rule 9 missing-folder error; (b) `uip tm wait` exit code 2 with `Timed out after <N>s waiting for execution '<EXECUTION_ID>'. Last status: <status>.`, which means bounded timeout worked—report non-finish and continue remaining steps; `Polling failed/interrupted/aborted ...` or exit code 1 is a real failure; (c) requirement AI exit 2 with `ErrorCode: timeout`: the job is still running, so resume it with the `--activity-id … --wait` command its `Instructions` name, never a new start; (d) `uip tm run --type package` exit 1 with `"Code": "RunPackageTestsFailed"` or `"RunPackageCancelled"` and `"ErrorCode": "execution_failed"`, which means the run finished with failed or no tests, or was cancelled: report `Data` (counts, `OutputPath`, `ExecutionUrl`) and do not retry; (e) `ValidationError` about a passed flag (`unknown option`, `missing required option`): read `<command> --help`, fix the flags, and run it again once (counts toward Rule 3); a second usage error on the same command stops. Every other failure stops.
11. Walk pages before concluding absence. Responses contain only `Data`, with no total/cursor/has-more. If absent and the page has exactly `--limit` rows (default 50), increase `--offset` by the page size until a short page; maximum page size is 100. `--limit` above 100 fails with `HTTP 400 … Page size cannot be greater than 100.` Lists without `--limit`/`--offset`, such as `tm testcases list`, must use filter flags (Rule 8).
## Quick Start
1. Verify auth under Rule 1; if needed set the tenant with `uip login tenant set <TENANT_NAME> --output json`; run `/uipath-platform` for authentication details.
2. Ask for the project name/key before any Test Manager call, except new work with no project named, which goes to the default project. For multiple projects ask once for all. Resolve each with `uip tm project list --filter <NAME_OR_KEY> --output json`; zero matches stops and asks; multiple matches require presenting candidates and asking the user to choose. Reuse confirmed `PROJECT_KEY`.
3. Common reads: `uip tm testsets list --project-key <PROJECT_KEY> --filter <TEST_SET_NAME_OR_KEY> --output json`; `uip tm testsets list-testcases --project-key <PROJECT_KEY> --test-set-key <TEST_SET_KEY> --output json`; `uip tm executions list --project-key <PROJECT_KEY> --test-set-id <TEST_SET_ID> --limit 100 --output json`; `uip tm executions testcaselogs list --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY> --output json` (add `--only-failed` for a red run, then `testcases list-result-history --test-case-id <TEST_CASE_ID> --only-failed` for regression versus flake — [references/failure-triage-guide.md](references/failure-triage-guide.md)); `uip tm testcaselog list-assertions --project-key <PROJECT_KEY> --test-case-log-id <TEST_CASE_LOG_ID> --output json`; `uip tm teststeplog list --project-key <PROJECT_KEY> --test-case-log-id <TEST_CASE_LOG_ID> --output json`.
## Concepts and CLI
Requirements define what must be tested; cases define scenarios and may contain **teststeps**; sets group cases; executions arise from set/case runs; testcase logs lead to step logs; assertions are assertion steps. Test Manager AI uses requirement descriptions and attachments to propose cases, improve requirements, or flag linked obsolete cases; each is a background job with an activity id. Defects originate from one testcase log and sync to Jira, Azure DevOps, or another tracker.
Performance scenarios load-test automated cases through load groups containing case, Orchestrator package/folder, and profile (virtual users, ramp-up, peak, ramp-down). Dry runs check scenarios; performance runs apply full load and consume tenant performance-testing licence.
External Playwright packages are uploaded Orchestrator suites. Ingestion creates one testcase per Playwright test, without a link step, labels each `PW_Tag_*`, `PW_Project_*`, `PW_Suite_*`, and `PW_File_*`, and runs on serverless cloud runtimes. See [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md).
Use `uip tm`; discover syntax with `uip tm --help` and `uip tm <command> <subcommand> --help`; **Always pass `--output json` to every `uip` command; all commands below require it.** For file values pass `"$(cat <FILE>)"`, never retype read content.
## Commands
### Projects, folders, requirements
Projects: `uip tm project list --filter <NAME_OR_KEY>`; `project create --name <PROJECT_NAME> --project-key <PROJECT_KEY>`; `project update --project-key <PROJECT_KEY> --name <PROJECT_NAME>` (name/description); `project delete --project-key <PROJECT_KEY>`; `project set-default-folder --project-key <PROJECT_KEY> --folder-key <FOLDER_KEY>`; `project clear-default-folder --project-key <PROJECT_KEY>`; `project owners list --project-key <PROJECT_KEY> [<PROJECT_KEY> ...]`. Folders: `uip or folders list -n <name> --all --output json` returns all visible folders.
`project list`, `create`, and `update` rows carry `IsDefault`. Inspect with `uip tm project list --limit 1 --output json` without `--filter`; first row is default only when `Data[0].IsDefault` is `true`, otherwise report "no default visible", not as "the tenant has none" (it may have none, or this login may lack access). `uip tm project get-default --output json` returns or creates `Default Project`, key `TMDP`, opened to the tenant's Everyone group; run only when work needs a project, never merely to inspect. <!-- Intended: get-default may create the tenant's default without asking; the agent then says which project it used. --> When the user asks to create test cases, test sets or requirements, or to run a package, and names no project, run `get-default`, use its `ProjectKey`, and tell the user the work went into that project (name and key). Only for new work: to read, change or delete existing items, ask for the project (Quick Start step 2). `uip tm project update --project-key <PROJECT_KEY> --set-default --output json` makes an existing project default (needs `TM.Administration` or tenant administrator); access does not change, so inaccessible projects yield `permission_denied` from `get-default`. There is no `project create --set-default`. For `permission_denied` from either command report `Message` and `Instructions` and stop (Rule 10).
`uip tm project-permissions get` returns `Data.Permissions` (the permission names the **caller** holds on that project) and `Data.Count`; it requires `Project.Read`, so success includes `Project.Read` (`Count >= 1`). No access is 403 (or 404 for unseen project), never successful empty permissions. Only `get` is exposed. `uip tm project settings get --project-key <PROJECT_KEY>` reads time zone, execution-name format, step cap, default folder, and governance; `project settings update --project-key <PROJECT_KEY> [--time-zone <IANA_NAME>] [--execution-name-format <TEMPLATE>]` writes only the first two. IANA names, placeholders, read-only fields and half-applied updates: [references/project-settings-guide.md](references/project-settings-guide.md).
Requirements: `uip tm requirements list --project-key <PROJECT_KEY>` optionally `--test-case-id <UUID>` (requirements a test case covers — use this, never scan `list-testcase-ids` per requirement), `--filter`, `--labels`, `--requirement-ids`, `--limit`, `--offset`. Also `list-by-test-execution --project-key <PROJECT_KEY> --execution-id <uuid>`; `get --project-key <PROJECT_KEY> (--requirement-id <uuid> | --requirement-key <key>)` (mutually exclusive); `create --project-key <PROJECT_KEY> --name <name>`; `update --project-key <PROJECT_KEY> --requirement-id <uuid>` (name/description, at least one); `delete --project-key <PROJECT_KEY> --requirement-ids <uuid...>`; `export --project-key <PROJECT_KEY> --output-file <path>` (`.xlsx`); `list-testcase-ids --project-key <PROJECT_KEY> --requirement-id <uuid>`; `testcases --project-key <PROJECT_KEY> --requirement-id <uuid> (--add-testcase-ids <uuid...> | --remove-testcase-ids <uuid...>)` (mutually exclusive).
Migration: `uip tm project export` → `uip tm project import` moves or backs up a whole project as `.tmh`; see [references/project-migration-guide.md](references/project-migration-guide.md). Jobs: `uip tm migration get|list|download`; schemas: `uip tm migration schemas list|download`. These are minutes-long jobs: pass `--wait` (export also `--output-file`), otherwise use the job id with `migration get`; never start another export/import to check. Automation is included by default (`--exclude automation` drops it); governance, project config (Test Cloud only, otherwise 403), and prompts require `--include`. Test sets travel only as `.tmh`; cases/requirements may also use Excel (`testcases export`, `requirements export`). If export format/purpose is unspecified ask. Before import ask existing versus new project (`--create-project`); for a taken key ask for `--new-project-key`.
### AI on requirements and prompt library
`uip tm requirements generate-testcases`, `uip tm requirements evaluate`, and `uip tm requirements find-obsolete-testcases` start jobs and return `ActivityId`; **each start spends AI units: start once, then reuse `--activity-id <ACTIVITY_ID>` to wait/show/create/unlink/delete; never start again to retry.** Use bounded `--timeout 540` and a 600 s shell limit. Scenarios, `Score`, `ConfidenceLevel`, and outcomes: [references/requirement-ai-guide.md](references/requirement-ai-guide.md).
`uip tm prompts list|get|create` manages reusable project AI guidelines. `ModeOfUse` (`--mode-of-use` on `create`, `--modes-of-use` on `list`) is the Autopilot offering; ask when none is named. There is no `update` or `delete`; names are not unique. Before create run `get --name <NAME>` (exact, case-sensitive); `ErrorCode: not_found` means absent, not Rule 10 stop. If found, do not recreate; report it and say changes require Test Manager UI. Several matches: `get` fails; use `--prompt-id` from `list`. `list` mixes `PromptType: Internal` samples and `UserDefined` team prompts; `--filter` is a prefix match on name or description. Guidelines are required, max 4096 characters, via `--guidelines` or multiline `--guidelines-file`; over-limit fails before sending. AI requirement commands take no prompt id: pass library `Guidelines` as `--instructions`. Export with `uip tm project export --include prompts`; default export omits them.
### Test cases
CRUD: `uip tm testcases create --project-key <PROJECT_KEY> --name <TEST_CASE_NAME>`; `list --project-key <PROJECT_KEY>` optionally `--filter <text>` (name/key PREFIX); `update --project-key <PROJECT_KEY> --test-case-key <TEST_CASE_KEY> --name <TEST_CASE_NAME>` (name, description, precondition, or postcondition; one required); `delete --project-key <PROJECT_KEY> --test-case-key <TEST_CASE_KEY>`; `get --test-case-key` adds pre/postcondition, `Created`, and `PackageEntryPointId`; `get --automation-id <PACKAGE_ENTRY_POINT_ID>` returns one case though several may share it, so list and match `PackageEntryPointId` for all; `list-requirements --test-case-key <TEST_CASE_KEY>` lists the requirements covering a case (run it to answer which requirements cover a test case); `list-packages`/`list-studio-projects` list distinct names with prefix `--filter`. “Which sets include cases labelled X” is one `list-testsets --labels X`, never a per-case loop; it shows explicit assignments only, not dynamic-label inclusion—say so.
Automation: `link-automation --project-key <PROJECT_KEY> --test-case-key <TEST_CASE_KEY> --folder-key <FOLDER_KEY> --package-name <PACKAGE_NAME> --test-name <TEST_NAME>`; optional `--entry-point-id <PACKAGE_ENTRY_POINT_ID>` from `list-automations`, overriding `--test-name`; `unlink-automation --project-key <PROJECT_KEY> --test-case-key <TEST_CASE_KEY>`; `list-automations --project-key <PROJECT_KEY> --folder-key <FOLDER_KEY>` optionally `--package-name <PACKAGE_NAME>` (rows carry `PackageEntryPointId`); `list-testsets --project-key <PROJECT_KEY> --test-case-key <TEST_CASE_KEY>`.
Clone: `clone` returns `Accepted` without a key and copies in background, steps last. Find it using the `list --filter` in `Instructions`; never clone again to check/retry. After 5xx list first because it may exist. Labels, documents, requirements, and parameters copy only with `--include`.
`bulk-create --file` accepts a JSON array of `{"name", "labels": [...], "steps": [{"description", "expectedResult"}]}`. Names are not unique, so reruns duplicate; pass `--skip-existing` when some names may already exist. File error exit 3 creates nothing. Later-batch failure leaves earlier items: report and ask before rerunning. `KeysResolved: false` still means created. `list --automated` omits Playwright-linked cases. A 403 on `group-by` (licence/feature off): stop and tell the user.
Steps: `uip tm testcases steps list --project-key <PROJECT_KEY> --test-case-id <TEST_CASE_ID>` uses UUID, not key; `steps get --project-key <PROJECT_KEY> --step-id <UUID>`; flag mode `steps add --project-key <PROJECT_KEY> --test-case-id <UUID> --description <text>` (`--description` required), or repeated JSON mode `steps add --project-key <PROJECT_KEY> --test-case-id <UUID> --step '<json>' [--step '<json>' ...]` (mutually exclusive, non-atomic; earlier steps persist); `steps update --project-key <PROJECT_KEY> --step-id <UUID>` updates passed fields only; `steps move --project-key <PROJECT_KEY> --step-id <UUID> --target-position <n>` uses 0-based position; `steps delete --project-key <PROJECT_KEY> --step-id <UUID> --yes`.
History/run: `list-result-history --project-key <PROJECT_KEY> --test-case-id <TEST_CASE_ID>` optionally `--only-failed`, `--filter`, `--limit`, `--offset`; `run --project-key <PROJECT_KEY> --test-case-id <TEST_CASE_ID> --name <EXECUTION_NAME> --execution-type <manual|automated|none|mixed>` starts one or more space-separated testcase UUIDs and optionally accepts `--async`, `--folder-key`, `--robot-user-key`, `--machine-key`.
Membership: `uip tm testcases add --test-set-key <TEST_SET_KEY> (--test-case-keys <KEY1> <KEY2> … | --labels <Label1> <Label2> …)` (mutually exclusive/variadic); keys also accept comma form (`DEMO:1,DEMO:2`), labels do not (`--labels A,B` is one label). Labels match OR, exact, case-insensitive; quote spaces. Without `--dynamic`, current matches copy once; testcases labeled later are not added. `uip tm testcases remove --test-set-key <TEST_SET_KEY> --test-case-keys <KEY1,KEY2,...>` removes static links; it succeeds but does nothing for a testcase included only by a dynamic label — change its labels or the set's dynamic labels instead. `uip tm testcases add --test-set-key <TEST_SET_KEY> --labels <Label1> <Label2> … --dynamic` stores labels on the set and includes every current and future case carrying any matching label; it merges labels (max 30), keeps static links, and returns `DynamicLabels` and `MatchedTestCases`; `--limit` and `--test-case-keys` are rejected. `uip tm testcases remove --test-set-key <TEST_SET_KEY> --dynamic [--labels <Label1> …] --yes` removes the named labels, or all of them when `--labels` is omitted, returning `Result` `Removed`, `Cleared`, or `NotSet`; disallowed for externally sourced sets. Use dynamic for tracking suites and omission for snapshots. If `uip tm testcases add --help` lacks `--dynamic`, use labels without it and rerun when labels change.
Parameters (`uip tm testcases parameters`, test cases only): use `--default-value`, not `--value`. Names are exact, case-insensitive, unique per case, never fuzzy (`User name` ≠ `Username`). Check `list --search` and exact `Name`; empty or `get --parameter-name <NAME>` `not_found` means absent, not Rule 4/10 stop. Near miss: ask the user to confirm the closest. **An existing parameter is never changed by an "add" request**, even when the request gives a different value: never run `update` for it. Single add: say it exists and ask for another name. Adding to several test cases: skip it, leave its value, and list it as skipped. Adding to many test cases: `list` each, `add` only missing names, then summarise added vs skipped per test case. Changing a missing name requires confirmation before creation. A rename onto a name in use is refused; report it. `delete` may return `Success` with no change; report `Data.Passed`/`Data.Failed`. Confirm deletes under Rule 5.
IDs: use `--test-case-id <UUID>` with `run`, `steps list`, `steps add`, `list-result-history`, and `testcaselog start`/`finish`; obtain from `testcases list` (`Id`) or newly opened run logs (see Execution lifecycle). Use singular `--test-case-key <PROJECT_KEY:NUMBER>` with `update`, `delete`, `link-automation`, `unlink-automation`, `list-testsets`; plural `--test-case-keys <KEY1,KEY2,...>` for bulk membership. Use `--step-id <UUID>` with every `steps` command except `list` and `add`, from `steps list` (`Id`).
### Test sets and executions
Sets: `uip tm testsets create --project-key <PROJECT_KEY> --name <TEST_SET_NAME>` optionally `--dynamic-labels <Label1> …` (assigns cases dynamically by those labels; returns `DynamicLabels`, `MatchedTestCases`); `list --project-key <PROJECT_KEY>` optionally `--filter <text>`, `--folder-key`, `--include-last-execution`; `update --test-set-key <TEST_SET_KEY> --name <TEST_SET_NAME>`; `delete --test-set-key <TEST_SET_KEY>`; `list-testcases --project-key <PROJECT_KEY> --test-set-key <TEST_SET_KEY>` lists the cases a run executes — static plus dynamic matches — with `AssignmentType` `Static`, `Dynamic`, or `Both`; `get-dynamic-assignment --project-key <PROJECT_KEY> --test-set-key <TEST_SET_KEY>` returns `DynamicLabels` (`[]` if none) and `MatchedTestCases`.
Run: `uip tm testsets run --test-set-key <TEST_SET_KEY>` runs and returns an execution ID; optionally `--execution-type <automated|manual|mixed|none>` (default `automated`), `--input-path <FILE>`, Playwright `--playwright-project <name>`. `playwright-context --test-set-key <TEST_SET_KEY>` returns `IsPlaywright`, available projects, selected projects. Keys are `PROJECT_KEY:NUMBER`; Add/remove membership — static or `--dynamic` — with `uip tm testcases add`/`uip tm testcases remove`, not `testsets` verbs. Probe first and branch on `IsPlaywright`; support and CLI external-package commands are required. `--playwright-project` is one case-sensitive `playwright.config` name, at most one per execution, and persists; every case must come from one Playwright package; unknown names fail listing valid ones. See [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md), beginning with availability and absent-support action.
Other set commands: `get`, `clone`, `set-execution-order`, `settings get`, `settings set`, `assign-user`, `set-folder`, `set-robot`, `set-execution-target`, `autoselect-packages`, `group-by`, `list --labels`. `clone` waits and returns `TestSetKey`; `--no-wait` returns `Accepted` without key. Timeout fails: stop and never clone again. Names may repeat, so give copies unique names. Folder, robot, packages, enforce flag, and order are not copied. Read `list-testcases` first; `set-execution-order` must include every assigned case and applies only after `settings set --enforce-execution-order`. Only enforce is writable; stop-on-failure, coverage, video, remote control, and Autopilot are read-only — say so. `--folder-path`, `--robot-name`, and `--assignee-email` resolve in Orchestrator. A 403 there or on `set-execution-target`/`group-by` (licence/feature off): stop and tell the user. `autoselect-packages` saves nothing.
Executions: `uip tm executions list --project-key <PROJECT_KEY>` optionally `--test-set-id <UUID>`, `--filter <text>`, `--status`, `--execution-type`, `--execution-finished-interval`, `--limit`, `--offset`; use it for the common one-test-set or single-project query. `list-filtered --project-key <PROJECT_KEY>` uses `--test-set-id`, `--status`, `--execution-type`, `--execution-finished-interval`, `--limit`, `--offset`, `--updated-by`, `--labels`, `--test-execution-ids`, `--sort-by`; it has no `--filter`, using `--search` for names. Use it for label filtering, multiple execution IDs, custom ordering, or `--updated-by`. Both share the same enum values, lower-case and rejected otherwise: `--status <pending|running|cancelling|finished|cancelled>`, `--execution-type <manual|automated|none|mixed|autonomous>`, `--execution-finished-interval <lastHour|lastDay|lastWeek|last15Days|last30Days>`. Response `Status` is capitalized (`Running`, `Finished`); do not reuse response values as filters.
`get-stats --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY>` aggregates pass/fail/none; `report get` summarizes completed runs. List rows already carry `Passed`/`Failed`/`None`, equal to `get-stats`, so one list call answers the totals for every run on a set. `uip tm executions run --execution-id <EXECUTION_ID> --execution-type <TYPE>` reruns, optionally `--test-case-log-ids <UUID...>` and `--async`; `retry --execution-id <EXECUTION_ID>` retries only failed cases, optionally `--project-key`, `--test-set-key`, `--execution-type`; nested `testcaselogs list --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY>` optionally `--only-failed`, `--filter`, `--limit`, `--offset`. Use `testcases run` for testcase UUIDs, `testsets run` for a set key, and `uip tm executions run` to rerun an execution.
### Execution lifecycle
There is no `executions create`. Open a manual run with `uip tm testsets run --test-set-key <KEY> --execution-type manual` or `uip tm testcases run --test-case-id <TCID> --execution-type manual` for specific cases. `finish` requires **all three of `--result`, `--has-error`, and `--executed-by`**; omission yields `ValidationError`/exit 3 with an **empty message** (the biggest cause of an unrecorded run). `--executed-by` is stored as the authenticated caller regardless of value, so pass the login email. The run self-closes only when its last log finishes. Report totals with `uip tm executions get-stats`, never a hand tally. Full open/record/finish, force-close, and `set-reporting-date` rules: [references/executions-guide.md](references/executions-guide.md).
### Test set schedules
Verbs: `uip tm schedules create|update|list|next-runs|enable|disable|delete`; `list` is the only read and has no get by id. Recover values with `list` before `update`; update replaces the whole definition (pass every flag you want kept) and cannot change enabled state (use enable/disable). `delete` and `--all` require `--yes`. `--cron` has 6 or 7 fields starting with seconds, not Unix cron; daily 02:00 is `0 0 2 1/1 * ? *`; five fields are refused client-side. Every recurrence requires `--cron-details` JSON. `--start-time`/`--disable-time` are wall-clock `YYYY-MM-DDTHH:mm` in `--timezone`; seconds and `Z` are refused. Pass `next-runs` ids from `list`; the underlying endpoint uses another GUID and returns `200` with an empty list for a bad id. See [references/schedules-guide.md](references/schedules-guide.md).
### Run an uploaded package (CI)
`uip tm run --type package --package-name <PACKAGE_NAME> --package-version <VERSION> --folder-path <FOLDER_PATH> --project-key <PROJECT_KEY> --output json` runs every test in an uploaded Orchestrator package, re-runs failures with `--max-retries <N>`, and writes a report. Pack/upload first with `uip rpa pack` / `uip or packages upload`. Without a project run `uip tm project get-default --output json` and use `ProjectKey`. Get `<VERSION>` from `uip or packages versions <PACKAGE_NAME> --folder-path <FOLDER_PATH> --output json`; app version `1.0` selects latest `1.0.x`; exact versions must be latest patch, while older versions exit 3 with nothing created. Under a CI limit pass `--timeout <SECONDS>` below it (default 7200); a step killed first leaves no report. Exit 1 with `RunPackageTestsFailed`/`RunPackageCancelled` is a test result: report it (Rule 10(d)). Exit 4 means timeout: execution may continue and `Data.OutputPath` contains a partial report with unfinished tests skipped; report timeout and never count skipped as passed. Other nonzero exits stop (Rule 10). `--input-path` names that no test declares are listed in `Data.IgnoredInputs`; tell the user (usually a typo).
### Logs, reports, attachments, and results
Start/finish: `uip tm testcaselog start --project-key <PROJECT_KEY> --execution-id <EXECUTION_ID> --test-case-id <TEST_CASE_ID>` optionally `--run-id <NUMBER>`. Finish with `finish --project-key <PROJECT_KEY> --execution-id <EXECUTION_ID> --test-case-id <TEST_CASE_ID> --result <None|Passed|Failed|Restricted> --has-error <true|false> --executed-by <EMAIL>`; all mandatory; omission gives `ValidationError`/exit 3 with empty message. `--executed-by` is validated non-empty then discarded; stored `ExecutedBy` is authenticated caller. If no executor is named, use `uip login status` → `Data.UserEmail`; never say the result was attributed to the named executor. Optional: `--detail-link <URL>`, `--run-id`, `--is-post-condition-met`, `--step-logs <json>`, `--step-logs-file <path>`. `start` needs an existing execution; open one with `uip tm testcases run … --execution-type manual` or `testsets run … --execution-type manual`. <!-- Verified 2026-10-22, CLI 1.205.0 on alpha: finish without --executed-by fails ValidationError/exit 3 even with --has-error. -->
Record manual step results on finish (`--step-logs`/`--step-logs-file`): `start` returns testcase-log `Id` and creates one step log per step. List with `uip tm teststeplog list --project-key <PROJECT_KEY> --test-case-log-id <TEST_CASE_LOG_ID> --output json`; pass each back as `{"id":"<STEP_LOG_ID>","testCaseLogId":"<TEST_CASE_LOG_ID>","result":"Passed","comment":"<text>","hasError":false}`. Match step-log `id`, not `testStepId`; unknown ids are silently ignored; only `result`, `comment`, `hasError`, and `hasAttachment` persist.
Read logs with `testcaselog list` (filters `--results`/`--statuses`/`--labels`/`--search`/`--assignees`; no date/execution filter—use `executions testcaselogs list`), `get --test-case-log-id <ID>` (`--include-assertions`), and `latest --test-case-ids <ID...>` (newest per case). A result is overridden only when `Result` and `OriginalResult` are both populated and differ; empty `OriginalResult` means not overridden. Correct settled results with `override create|update|delete|get`; `create` needs `--result` and `--reason`. Assign with `assign --assignee-email <EMAIL>` (CLI resolves) or `--assignee-id <IDP_UUID>`. `cancel --test-case-log-id <ID> --yes` stops one automated Orchestrator job but returns `CancelRequested` even for manual/finished logs, which ignore it; confirm with `get` (`Status` `Cancelling`). Whole runs use `executions cancel`. See [references/testcaselog-guide.md](references/testcaselog-guide.md).
`uip tm testcaselog list-assertions --project-key <PROJECT_KEY> --test-case-log-id <TEST_CASE_LOG_ID>` lists assertions; `render-assertions` returns markdown; `get-robot-logs` returns an expiring link or downloads with `--output-file`; `uip tm teststeplog list --project-key <PROJECT_KEY> --test-case-log-id <TEST_CASE_LOG_ID> --output json` lists steps.
`uip tm report get --execution-id <EXECUTION_ID> (--project-key <KEY> | --test-set-key <KEY>)` summarizes completed runs (`TotalTests`/`Passed`/`Failed`/`None`, `PassRate` over passed + failed so `None` does not lower it, and `FailedTests`). Exactly one project identifier is required; execution alone exits `Provide --project-key or --test-set-key`.
Attachments/results: `uip tm attachment download --execution-id <EXECUTION_ID>` downloads testcase attachments; `attachment upload --object-id <UUID> --object-type <type> --file <path>` uploads to an object such as `--object-type testCaseLog`; `uip tm result download --execution-id <EXECUTION_ID>` downloads JUnit XML, optionally `--project-key`, `--test-set-key`, `--result-path <DIR>`. For one file, use `uip tm attachment` (`upload` returns `AttachmentId`): find the object first with `list --test-case-keys` / `--requirement-keys`, select by `FileName`, then use `AttachmentId`; no match or a duplicate name: ask the user. Existing id: `get --attachment-id <ID> --object-type <TYPE>` reads metadata. `list` shows only `userBased` unless `--source` is passed (`orchestrator`, `studio`, `taskCapture`); unresolved keys appear under `Unresolved` and must be named; unknown `--object-ids` yields `AttachmentCount: 0`. `--object-type` is parent type, not file type; wrong type may still succeed. `download --attachment-id` writes to current folder under server name unless `--result-path`/`--output-file`, and never replaces a file: on `already exists`, stop and ask the user; pass `--overwrite` only when the user asked. `update` only renames with `--file-name`. `--all` is one page per call; follow `Pagination`. `delete --attachment-id <ID> --object-type <TYPE> --yes` requires Rule 5 confirmation.
Exports: `uip tm testcases export` writes `.xlsx` (`--test-case-ids`, otherwise whole project); `uip tm report export` writes reports with `--execution-id --format excel|pdf|junit`, or selected result PDFs with `--test-case-log-ids` (two or more become one `.zip`). When the user wants a file, pass `--wait --output-file <path>`. Without `--wait`, poll `uip tm export-jobs get --job-id` while `Initiated`/`InProgress`, stop on `Failed`/`Cancelled`, then run `attachment download --attachment-id <AttachmentId>` as `Instructions` says. Never start the same export twice. Existing `--output-file` is refused before start; ask and use `--overwrite` only when told. `export-jobs get` requires starting project (others 404). JUnit disabled (`feature is not enabled`) or 403 result PDFs (licence): report it, don't retry.
### Playwright pack
`uip tm pack --project-path <dir> --type playwright --project-key <PROJECT_KEY> --name <PackageName> --package-version <ver> -o <out-dir>` packs a Playwright suite into `.nupkg`; lockfile and `@playwright/test` are required. `--package-version` is NuGet/SemVer-style with three or four numeric parts and optional prerelease/build suffix (`1.0.0`, `1.0.0.0`, `1.0.1-beta.1`); `1.0` and nonnumeric values are rejected. `--project-key` enables automatic testcase ingestion; `--no-create-test-cases` skips it; `--dry-run` previews. Upload with `uip or packages upload <nupkg>`. Packing is offline and needs no auth. The upload → ingestion → label-fill → run pipeline is in [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md).
### Defects
`uip tm defects` supports `create | list | get | update | delete | get-external-issue | get-related | attachments list|download`; raise from failed results, change status/priority/tracker link, and trace it. Defects are UUID-only: find `DefectId` in `executions testcaselogs list`. Before any defects call, read [references/defects-guide.md](references/defects-guide.md); `update`/`delete` often take 10–40 s and require a shell limit of at least 120 s.
### Wait, user, custom fields, and labels
`uip tm wait --execution-id <EXECUTION_ID>` waits for terminal state; optionally `--project-key`, `--test-set-key`, `--timeout <SECONDS>`. `uip tm user get` gets the authenticated profile.
Project-scoped custom-field definitions attach to Requirement/TestCase/TestSet, with per-object label/value rows, via `uip tm customfield …`. For full surface, scopes, case-sensitive `--object-type`/`--data-type` enums (`Requirement|TestCase|TestSet`, `Text|Label`), `--values` JSON semantics, and every label/value verb, read [references/custom-fields-guide.md](references/custom-fields-guide.md).
Use `uip tm objectlabel …` for metadata on `Requirement`, `TestCase`, `TestSet`, `TestExecution`, or `TestCaseLog`. Read [references/object-labels-guide.md](references/object-labels-guide.md), especially label id versus object id and `--remove-other-labels` deleting hidden internal labels.
### Performance (load) testing
1. Find the automated case with `testcases list`, then folder/package with `testcases list-automations`. `IsAutomated: false` with `PackageName` is still a legacy link: use that package and never say it lacks automation.
2. Create `uip tm perf-scenario create --project-key <PROJECT_KEY> --name <NAME>`, then `perf-scenario load-groups add --scenario-key <SCENARIO_KEY> --test-case-key <TEST_CASE_KEY> --folder-key <FOLDER_KEY> --package-name <PACKAGE_NAME>`. `add` ignores profile flags and resets to 20 virtual users. Update with `perf-scenario load-groups update --load-group-id <LOAD_GROUP_ID> --project-key <PROJECT_KEY> --virtual-users <N>` using returned id; omit `--package-version` (latest resolves). Robot defaults to `standard`, requiring connected machine with Performance Testing runtimes; serverless requires `--robot-type serverless` on `update` with the profile.
3. Dry-run with `perf-scenario execute --scenario-key <SCENARIO_KEY> --wait`; it ignores profile and uses one virtual user, so do not ask load values first. Full run requires passing `list-dry-run-reports` and enough units from `licenses get`. Before full execution show profile from `get` and have the user confirm/change it with `load-groups update`. Dry-run `RecommendedMultiplexingFactor`/`--multiplexing-factor` applies only to machine robots; leave unset for serverless.
4. Full run: `perf-scenario execute --scenario-key <SCENARIO_KEY> --execution-type performanceTesting --wait`; inspect groups with `load-groups list --execution-id <EXECUTION_ID>` and numbers with `results get`. `report generate --format pdf|html --report-file <FILE>` only publishes a report you write from those results (markdown for pdf, HTML for html) and returns `ViewUrl`.
`get`, `delete`, `execute`, and `list-dry-run-reports` take only `--scenario-key` (the key, such as `CLAIM:7441`, already carries the project); `--project-key` fails `unknown option`. `create`, `list`, `stop`, and `licenses get` take `--project-key`; `licenses get` requires one although any project gives the same number. `execute --wait` exit 1 means cancellation, automation failure, or any `SloViolationReasons`, even if output says `Success`: report reasons and never rerun. Exit 4 means `--timeout-sec` (default 1800) passed and run continues: read `results get --execution-id <EXECUTION_ID>`; a new execute starts another run. If shell limit is too short, start without `--wait`, give `ExecutionId`, and use `results get` and `stop --execution-id <EXECUTION_ID> --project-key <PROJECT_KEY>`.
Perf-service reads reject `--project-key` (`unknown option`): `results get`, `http-errors list`, `automation-errors list`, `transaction-metrics list`. The latter three require `--start-time-ms 0 --end-time-ms <DURATION_MS>` with `Duration` from `executions list`. `transaction-metrics` has rows only for API groups; `[]` elsewhere means no data, not zero latency. `--full` and `results get` include per-second series; slim with `--query` and omit series for go/no-go summaries.
There are two load-group ids: the scenario's load-group ids from `get`/`load-groups add` are for `load-groups update`/`remove`; execution ids from `load-groups list --execution-id <EXECUTION_ID>` are for `load-groups get`, `jobs list`, `robot-logs list`, `http-errors`, `automation-errors`, and `transaction-metrics`; the wrong one returns 404 `not_found`.
Find scenarios with `perf-scenario list --project-key <PROJECT_KEY> --search <NAME>` (`Data.Scenarios`). Past runs: `perf-scenario executions list --project-key <PROJECT_KEY> --scenario-id <SCENARIO_ID>`, optionally `--execution-type dryRun|performanceTesting` (`Data.Data`; response `ExecutionType` capitalized). Scenario UUID is absent from `list`/`get`. `list-dry-run-reports --scenario-key <SCENARIO_KEY>` returns `ScenarioId` only when a group's case has `AutomationId` (Studio-linked; `link-automation` sets none); otherwise list without `--scenario-id` and match rows whose `Name` starts with the scenario name. `report compare --scenario-id <SCENARIO_ID> --execution-ids <ID...> --report-file <HTML_FILE>` publishes an HTML comparison you write from each run's `results get` (oldest to newest, one scenario) and returns `ViewUrl`; add `--project-key` for an in-app link.
`licenses get` returns tenant-wide `RemainingVirtualUserUnits` and can lag up to 4 hours. A full run consumes virtual users × 1 (API), 10 (Chrome/Edge), or 100 (other targets); dry runs consume none. If units are short, stop and tell the user. Triage a failed group with `robot-logs list --load-group-id <ID> --level Error` and `jobs list --load-group-id <ID>`; A 403 means the tenant's performance testing feature or the user's permission is off: stop under Rule 10. `delete --scenario-key <SCENARIO_KEY> --yes` permanently removes scenario/groups (confirm first, Rule 5) but keeps past executions unlinked; it does not stop a running execution, so run `stop` first.
## Troubleshooting
For `401 Unauthorized` on a REST API, run `uip login` to re-authenticate. For unexpected command failure, first verify syntax with `uip tm <command> --help`, then authentication with `uip login status --output json`; Rule 10 still controls whether to proceed.
## Navigate to a Workflow
- Read, correct (`override`), assign, or manually record a test case log, and `Result` vs `OriginalResult`: [references/testcaselog-guide.md](references/testcaselog-guide.md)
- Back up, copy or move a project, in one tenant or across tenants and environments (`uip tm project export` → `import`): [references/project-migration-guide.md](references/project-migration-guide.md)
- Execution lifecycle (manual open/record/finish), filtered reads, cancel, delete, xlsx export, and reporting date (`uip tm executions`): [references/executions-guide.md](references/executions-guide.md)
- Failed-run root cause, assertions, step logs, evidence, and flaky-versus-regression analysis: [references/failure-triage-guide.md](references/failure-triage-guide.md)
- Raise a defect from a failed result, trace it to its test case/requirements, link it to a tracker issue (`uip tm defects`): [references/defects-guide.md](references/defects-guide.md)
- AI on a requirement: propose and create test cases, evaluate the requirement, find and unlink or delete obsolete test cases (`uip tm requirements generate-testcases`, `evaluate`, `find-obsolete-testcases`): [references/requirement-ai-guide.md](references/requirement-ai-guide.md)
- Shareable tester or release-manager report: [references/test-result-report-guide.md](references/test-result-report-guide.md)
- Publish a project and link it to a Test Manager testcase (Studio/RPA): [references/publish-and-link-guide.md](references/publish-and-link-guide.md)
- Pack, ingest, label, and run Playwright on serverless: [references/playwright-first-mile-guide.md](references/playwright-first-mile-guide.md)
- Run a test set on a cadence, cron shapes, and single-vs-bulk batch semantics (`uip tm schedules`): [references/schedules-guide.md](references/schedules-guide.md)
- Custom-field definitions, labels, and values (`uip tm customfield`): [references/custom-fields-guide.md](references/custom-fields-guide.md)
- Object labels / tag metadata on test entities (`uip tm objectlabel`): [references/object-labels-guide.md](references/object-labels-guide.md)
- Project time zone, execution name format, and what is read-only (`uip tm project settings`): [references/project-settings-guide.md](references/project-settings-guide.md)
## Anti-patterns
- Do not proceed if authentication fails; all Test Manager API calls require a valid bearer token.
- Do not guess command names: verb-noun composites are required; bare verbs do not exist. Confirm with `uip tm <resource> --help --output json`.
- Do not hand-build a package run; use `uip tm run --type package`, not `link-package` → `testsets create` → `testcases add` → `testsets run` → `wait` → `result download`.
- Do not run `project get-default` to inspect the default; it creates one, opened to tenant Everyone, when none exists. Read the first `project list` row.
- Do not `link-automation` Playwright cases; ingestion links them automatically. Manual linking is only for Studio/RPA.