@testmo/testmo-link 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # @testmo/testmo-link
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@testmo/testmo-link.svg)](https://www.npmjs.com/package/@testmo/testmo-link)
4
+
5
+ `testmo-link` links automation test results to manual test cases in your Testmo repository,
6
+ enabling **automation coverage tracking**. It is a standalone tool, separate from the main
7
+ `@testmo/testmo-cli` package.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ $ npm install -g @testmo/testmo-link
13
+ ```
14
+
15
+ This installs the `testmo-link` binary globally.
16
+
17
+ ## Update
18
+
19
+ ```bash
20
+ $ npm update -g @testmo/testmo-link
21
+ ```
22
+
23
+ ## Authentication
24
+
25
+ Set `TESTMO_TOKEN` to your Testmo API token before running:
26
+
27
+ ```bash
28
+ export TESTMO_TOKEN=testmo_api_...
29
+ ```
30
+
31
+ Never pass the token as a command-line argument — it will appear in process listings, shell
32
+ history, and CI/CD logs. Store it as a CI/CD secret and expose it as an environment variable.
33
+
34
+ If your environment requires an HTTP proxy, set `--proxy` or the `HTTP_PROXY` / `HTTPS_PROXY`
35
+ environment variables.
36
+
37
+ ## Quick start
38
+
39
+ ```bash
40
+ # Submit test results (requires @testmo/testmo-cli)
41
+ RUN_ID=$(TESTMO_TOKEN=**** testmo automation:run:submit \
42
+ --instance https://your-instance.testmo.net \
43
+ --project-id 1 \
44
+ --name "My Tests" \
45
+ --source backend \
46
+ --results results.xml | grep -E '^[0-9]+$' | tail -1)
47
+
48
+ # Link results to repository cases
49
+ TESTMO_TOKEN=**** testmo-link \
50
+ --instance https://your-instance.testmo.net \
51
+ --project-id 1 \
52
+ --run-id $RUN_ID \
53
+ --config linking.yml
54
+ ```
55
+
56
+ > **Note:** `automation:run:submit` outputs the run ID to stdout alongside progress messages.
57
+ > The `grep -E '^[0-9]+$' | tail -1` pattern extracts just the numeric ID.
58
+
59
+ Use `--dry-run` to preview what would be linked before making any changes:
60
+
61
+ ```bash
62
+ TESTMO_TOKEN=**** testmo-link \
63
+ --instance https://your-instance.testmo.net \
64
+ --project-id 1 \
65
+ --run-id $RUN_ID \
66
+ --config linking.yml \
67
+ --dry-run
68
+ ```
69
+
70
+ Running `testmo-link` twice on the same run is safe — already-linked tests are skipped by
71
+ default. Use `--force` to re-link them (for example, after correcting a wrong mapping).
72
+
73
+ ## Linking methods
74
+
75
+ `testmo-link` supports three methods for matching test results to repository cases. They can be used individually or combined — the first method to find a match wins (based on the `precedence` order in your config).
76
+
77
+ ### Config mappings
78
+
79
+ Explicit test name → case ID mappings defined in your config file:
80
+
81
+ ```yaml
82
+ config_mappings:
83
+ - test_name: "test_login_success"
84
+ case_id: 42
85
+ - test_name: "test_checkout_flow"
86
+ case_id: 100
87
+ ```
88
+
89
+ The `test_name` must exactly match the test name as it appears in your submitted results.
90
+
91
+ ### Annotation scanning
92
+
93
+ Add `@TestmoId:N` comments to your test source files:
94
+
95
+ ```python
96
+ # @TestmoId:42
97
+ def test_login_success():
98
+ ...
99
+ ```
100
+
101
+ ```java
102
+ // @TestmoId:42
103
+ @Test
104
+ public void testLoginSuccess() {
105
+ ...
106
+ }
107
+ ```
108
+
109
+ Configure annotation scanning in your config file:
110
+
111
+ ```yaml
112
+ annotations:
113
+ enabled: true
114
+ base_path: /path/to/project # root directory for glob resolution (default: cwd)
115
+ paths:
116
+ - "tests/**/*.py"
117
+ - "src/test/**/*.java"
118
+ patterns: # optional: override the default @TestmoId:(\d+) pattern
119
+ - "@TestmoId:(\\d+)"
120
+ ```
121
+
122
+ The scanner extracts the test name from the code immediately below each annotation and matches it against your submitted results by name. If the same test name appears in more than one file, the `file` field from the test result is used to disambiguate.
123
+
124
+ ### Pattern matching
125
+
126
+ Fetches all cases from your repository and matches test names to case names by normalizing both sides (lowercase, underscores and hyphens become spaces):
127
+
128
+ ```
129
+ test_login_success → "login success" → matches case "Login Success"
130
+ Login_Success → "login success" → matches case "Login Success"
131
+ ```
132
+
133
+ Configure optional regex rules to extract the relevant part of your test name:
134
+
135
+ ```yaml
136
+ pattern_matching:
137
+ enabled: true
138
+ rules:
139
+ - type: name_match
140
+ pattern: "test_(.+)" # captures everything after "test_"
141
+ ```
142
+
143
+ If a test name matches multiple cases, it is skipped with a warning.
144
+
145
+ ## Configuration file
146
+
147
+ Create a YAML or JSON file and pass it with `--config`. All sections are optional.
148
+
149
+ ```yaml
150
+ # Explicit name → case ID mappings
151
+ config_mappings:
152
+ - test_name: "test_login_success"
153
+ case_id: 42
154
+
155
+ # Annotation scanning
156
+ annotations:
157
+ enabled: true
158
+ base_path: /path/to/project
159
+ paths:
160
+ - "tests/**/*.py"
161
+
162
+ # Pattern matching
163
+ pattern_matching:
164
+ enabled: true
165
+ rules:
166
+ - type: name_match
167
+ pattern: "test_(.+)"
168
+
169
+ # Order in which methods are tried (first match wins)
170
+ # Default: [annotation, config, pattern]
171
+ precedence:
172
+ - annotation
173
+ - config
174
+ - pattern
175
+
176
+ # Settings (all can also be set via CLI flags; flags take priority)
177
+ settings:
178
+ conflict_resolution: error # error | warn | silent
179
+ dry_run: false
180
+ force: false
181
+ fail_on_unmatched: false
182
+ verbose: false # same as --verbose
183
+ output_file: null # path — same as --output <file>
184
+ ```
185
+
186
+ ### Precedence
187
+
188
+ When multiple methods are enabled, they are applied in the order defined by `precedence`. The **first method that returns a match wins**. If all enabled methods agree on the same case ID for a test, there is no conflict.
189
+
190
+ ### Conflict resolution
191
+
192
+ A conflict occurs when two methods match the same test to **different** case IDs. The `conflict_resolution` setting controls what happens:
193
+
194
+ | Mode | Behaviour |
195
+ |------|-----------|
196
+ | `error` (default) | Skips the test, increments error count, exits with code 1 |
197
+ | `warn` | Uses the highest-precedence match, logs a warning |
198
+ | `silent` | Uses the highest-precedence match, no warning logged |
199
+
200
+ ## CLI reference
201
+
202
+ | Flag | Description |
203
+ |------|-------------|
204
+ | `--instance <url>` | **Required.** Full URL of your Testmo instance, e.g. `https://my-company.testmo.net` |
205
+ | `--project-id <id>` | **Required.** Project ID |
206
+ | `--run-id <id>` | **Required.** Automation run ID to link |
207
+ | `--config <file>` | Path to a YAML or JSON config file with linking rules |
208
+ | `--dry-run` | Preview what would be linked without creating any links |
209
+ | `--force` | Re-link tests that are already linked to a repository case |
210
+ | `--fail-on-unmatched` | Exit with code 1 if any tests could not be matched to a case |
211
+ | `--conflict-resolution <mode>` | How to handle conflicts between methods: `error` (default), `warn`, `silent` |
212
+ | `--proxy <address>` | HTTP(S) proxy for all outbound connections |
213
+ | `--verbose` | Print debug detail to the terminal |
214
+ | `--output <file>` | Write all output (always including debug detail) to a file |
215
+ | `--ansi` / `--no-ansi` | Force enable or disable ANSI colour output |
216
+ | `-V, --version` | Print version number and exit |
217
+ | `-h, --help` | Display help and exit |
218
+
219
+ CLI flags take priority over the equivalent `settings` in your config file.
220
+
221
+ ## Exit codes
222
+
223
+ | Code | Meaning |
224
+ |------|---------|
225
+ | `0` | Success — all matched tests linked (or dry-run completed) |
226
+ | `1` | Error — API failure, conflict in `error` mode, `--fail-on-unmatched` triggered, or config/validation error |
227
+
228
+ ## Summary output
229
+
230
+ After running, `testmo-link` prints a summary:
231
+
232
+ ```
233
+ Automation linking complete (1.2s):
234
+ Matched/linked: 8
235
+ Already linked: 2 (skipped)
236
+ Unmatched: 1
237
+ By method:
238
+ annotation: 5
239
+ config: 2
240
+ pattern: 1
241
+ ```
242
+
243
+ The "By method" breakdown only appears when more than one method contributed matches. The "Errors" line only appears when there are conflict errors or API failures.
244
+
245
+ Use `--output <file>` to capture full output including debug detail to a file — useful for CI/CD without cluttering the build log.
246
+
247
+ ## Relationship to @testmo/testmo-cli
248
+
249
+ `testmo-link` is intentionally separate from `@testmo/testmo-cli`. Not all customers need
250
+ automation coverage tracking, so the two tools are published independently. You can use
251
+ `@testmo/testmo-cli` alone to submit test results, and add `@testmo/testmo-link` only when
252
+ you want to link those results to manual test cases in your repository.
253
+
254
+ ## Documentation
255
+
256
+ Full documentation including CI/CD integration guides, framework-specific annotation setup,
257
+ troubleshooting, and configuration examples:
258
+
259
+ [support.testmo.com](https://support.testmo.com/)
260
+
261
+ ## License
262
+
263
+ Copyright (c) Testmo GmbH (Berlin, Germany)<br>
264
+ All rights reserved.<br>
265
+ contact@testmo.com<br>
266
+ www.testmo.com