You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
enhancement(import): link JUnit/CLI results to existing cases by ID (#394)
* enhancement(import): link JUnit/CLI results to existing cases by ID
Adds opt-in case-ID matching to the test-results importer so renaming an
automated test no longer creates a duplicate case. A result can declare the
existing case it belongs to via an ID in the test name (presets: brackets
[123], C123, TC-123) or a test_id / testplanit_case_id JUnit property. When
present, the result links to that case (scoped to the project) and skips
name+className matching; multiple IDs link to multiple cases. Unknown IDs are
skipped and surfaced as warnings rather than creating duplicates.
Configured via the CLI --case-matcher / --case-id-format flags; default off,
so existing imports are unchanged. Matching uses a fixed set of compiled
presets only, so no caller-supplied regex runs server-side.
* docs(import-export): enhance CSV and test results import instructions
Updated the import-export documentation to clarify the process for importing test cases and results. Added details on using the Import button and drag-and-drop functionality, and improved formatting examples for test steps to include code blocks with the `text` language specified. This enhances readability and user understanding of the import features.
* chore(workspace): add iframe-resizer to allowed builds
Updated the pnpm workspace configuration to include 'iframe-resizer' in the list of allowed builds, enhancing the build process for the project.
-`-f, --folder <value>` - Parent folder for test cases (ID or exact name)
98
98
-`-t, --tags <values>` - Tags (comma-separated IDs or names; use quotes for names with commas)
99
99
-`-r, --test-run <value>` - Existing test run to append results (ID or exact name)
100
+
-`--case-matcher <mode>` - Link results to existing cases by ID: `off`, `name`, `property`, `auto` (default: `off`)
101
+
-`--case-id-format <preset>` - Case-ID pattern in the test name when matching by name: `brackets`, `c`, `tc` (default: `brackets`)
100
102
101
103
**Note:** For project, state, config, milestone, folder, and test run options, the CLI looks up entities by exact name match. If no match is found, an error is returned. For tags, if a tag name doesn't exist, it will be created automatically.
102
104
105
+
**Linking results to existing cases by ID:** By default a result is matched to a case by name and class name, so renaming a test creates a duplicate. With `--case-matcher`, a result instead links to an existing case by an ID in the test name (`--case-id-format`: `brackets` → `[123]`, `c` → `C123`, `tc` → `TC-123`) or a `test_id` / `testplanit_case_id` JUnit `<property>` (`property`/`auto`). Multiple IDs link one result to multiple cases; an ID not found in the project is skipped with a warning.
|`-d, --attachments-dir <path>`| Base directory for resolving attachment paths (default: directory of test result file) |
145
145
|`--no-attachments`| Skip uploading attachments from test results |
146
146
|`-a, --run-attachments <files...>`| Files to attach to the test run (e.g., test plans, reports) |
147
+
|`--case-matcher <mode>`| Link results to existing cases by ID: `off`, `name`, `property`, `auto` (default: `off`) |
148
+
|`--case-id-format <preset>`| Case-ID pattern in the test name when matching by name: `brackets`, `c`, `tc` (default: `brackets`) |
147
149
148
150
:::note
149
151
For project, state, config, milestone, folder, and test run options, the CLI looks up entities by exact name match. If no match is found, an error is returned. For tags, if a tag name doesn't exist, it will be created automatically.
@@ -171,6 +173,42 @@ Use `-d, --attachments-dir` to specify a custom base directory for resolving rel
171
173
172
174
Use `--no-attachments` to skip uploading test result attachments entirely.
173
175
176
+
#### Linking results to existing cases by ID
177
+
178
+
By default the importer matches each result to a case by **name and class name**. If your automation renames a test, the importer no longer recognizes it and creates a duplicate case. To prevent this, assign each automated test the ID of the case it belongs to, and turn on case-ID matching with `--case-matcher`. When a result carries a recognized ID, it links to that case **regardless of the test name**, so renames stop creating duplicates.
179
+
180
+
There are two ways to carry the ID, controlled by `--case-matcher`:
181
+
182
+
-**`name`** — the ID is embedded in the test name; the pattern is chosen with `--case-id-format` (see below).
183
+
-**`property`** — the ID is carried in a JUnit `<property>` named `test_id` (or `testplanit_case_id`), following the convention used by TestRail and Xray (see below).
184
+
-**`auto`** — try the `test_id` property first, then fall back to the name pattern.
185
+
186
+
Name patterns (`--case-id-format`):
187
+
188
+
| Preset | Matches | Example test name |
189
+
| -------- | --------- | ------------------- |
190
+
|`brackets` (default) |`[123]`, `[C123]`, `[123, 456]`|`[123] user can log in`|
191
+
|`c`|`C123`|`C123 user can log in`|
192
+
|`tc`|`TC-123`, `TC123`|`TC-123 user can log in`|
193
+
194
+
Property form (`--case-matcher property` or `auto`):
195
+
196
+
```xml
197
+
<testcasename="user can log in"classname="auth.LoginTests">
198
+
<properties>
199
+
<propertyname="test_id"value="123"/>
200
+
</properties>
201
+
</testcase>
202
+
```
203
+
204
+
Notes:
205
+
206
+
- A single test may reference multiple cases (`[123, 456]` or `value="123,456"`); each referenced case receives the same result.
207
+
- Tests **without** an ID still import normally — they are matched/created by name and class name as before.
208
+
- If a referenced case ID does not exist in the target project, that result is **skipped** (never auto-created under a wrong name) and reported as a warning at the end of the import.
209
+
- The ID is the numeric TestPlanIt case ID; a leading `C` or `#` is tolerated.
210
+
- Property matching requires a reporter that writes per-`<testcase>` properties (e.g. pytest's `record_property`, the Playwright JUnit reporter with `embedAnnotationsAsProperties`, NUnit `[Property]`). Frameworks that only emit suite-level properties (e.g. Maven Surefire) should use the name-based pattern instead.
Response is Server-Sent Events (SSE) with progress updates:
@@ -768,6 +774,8 @@ Response is Server-Sent Events (SSE) with progress updates:
768
774
{"complete": true, "testRunId": 12345}
769
775
```
770
776
777
+
By default each result is matched to a case by **name + class name**, so renaming an automated test creates a duplicate case. Set `caseMatcher` to instead link results to an existing case by an ID carried in the test name (`caseIdFormat` preset) or a `test_id` / `testplanit_case_id` JUnit property — see [Linking results to existing cases by ID](./cli.md#linking-results-to-existing-cases-by-id) in the CLI guide for the full behavior. Results whose referenced case ID is not found in the project are skipped and listed in the final SSE event as `caseIdWarnings`.
778
+
771
779
### Export
772
780
773
781
There is no server-side export endpoint. CSV, PDF, and other exports are generated in the browser from data already loaded by the Repository view — the export reflects the current filter, scope, and column selection in the UI. Use the **Export** button in the Repository toolbar to configure and download.
0 commit comments