@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 +266 -0
- package/dist/controller/automationLink.js +636 -0
- package/dist/core/controller.js +50 -0
- package/dist/index.js +202 -0
- package/dist/lib/errors.js +68 -0
- package/dist/lib/logger.js +117 -0
- package/dist/lib/retry.js +67 -0
- package/dist/linking/annotationScanner.js +745 -0
- package/dist/linking/patternMatcher.js +173 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# @testmo/testmo-link
|
|
2
|
+
|
|
3
|
+
[](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
|