@testcollab/cli 1.3.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/.github/workflows/release.yml +53 -0
- package/DEVELOPMENT.md +225 -0
- package/LICENSE +21 -0
- package/README.md +378 -0
- package/docs/frameworks.md +485 -0
- package/docs/specgen.md +77 -0
- package/package.json +54 -0
- package/samples/reports/junit.xml +12 -0
- package/samples/reports/mochawesome.json +110 -0
- package/scripts/bump-version.js +145 -0
- package/src/ai/discovery.js +123 -0
- package/src/commands/createTestPlan.js +259 -0
- package/src/commands/featuresync.js +753 -0
- package/src/commands/report.js +1109 -0
- package/src/commands/specgen.js +430 -0
- package/src/index.js +74 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
- master
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
publish:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
environment: main
|
|
20
|
+
permissions:
|
|
21
|
+
id-token: write
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Use Node.js 22
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: 22
|
|
32
|
+
registry-url: https://registry.npmjs.org
|
|
33
|
+
cache: npm
|
|
34
|
+
|
|
35
|
+
- name: Bump version
|
|
36
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'release'
|
|
37
|
+
run: node scripts/bump-version.js
|
|
38
|
+
- name: upgrade npm
|
|
39
|
+
run: npm i -g npm@latest
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: npm ci
|
|
43
|
+
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: npm test
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
- name: Publish to npm
|
|
50
|
+
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'release'
|
|
51
|
+
run: npm publish --access public --provenance
|
|
52
|
+
env:
|
|
53
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
Guide for contributing to the TestCollab CLI.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/TCSoftInc/testcollab-cli.git
|
|
9
|
+
cd testcollab-cli
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Make the CLI available globally (for testing)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm link # creates global 'tc' symlink to your local code
|
|
17
|
+
npm unlink -g testcollab-cli # undo when done
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Running locally
|
|
21
|
+
|
|
22
|
+
You don't need to install the package to test changes. Run directly with Node:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# From the tc-cli directory
|
|
26
|
+
node src/index.js sync --project 123
|
|
27
|
+
node src/index.js createTestPlan --api-key $TOKEN --project 123 ...
|
|
28
|
+
node src/index.js report --api-key $TOKEN --project 123 ...
|
|
29
|
+
node src/index.js specgen --src ../my-app/src --out ../my-app/features
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or use `npm link` (see above) and run `tc` from anywhere.
|
|
33
|
+
|
|
34
|
+
## Environment variables
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Required for sync
|
|
38
|
+
export TESTCOLLAB_TOKEN=your_api_token
|
|
39
|
+
|
|
40
|
+
# Required for specgen (pick one)
|
|
41
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
42
|
+
export GOOGLE_GENAI_API_KEY=...
|
|
43
|
+
|
|
44
|
+
# Optional: point at a different API
|
|
45
|
+
export API_URL=http://localhost:1337 # or use --api-url flag
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Project structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
tc-cli/
|
|
52
|
+
├── src/
|
|
53
|
+
│ ├── index.js # CLI entry point (Commander.js)
|
|
54
|
+
│ ├── commands/
|
|
55
|
+
│ │ ├── featuresync.js # tc sync
|
|
56
|
+
│ │ ├── createTestPlan.js # tc createTestPlan
|
|
57
|
+
│ │ ├── report.js # tc report
|
|
58
|
+
│ │ └── specgen.js # tc specgen
|
|
59
|
+
│ └── ai/
|
|
60
|
+
│ └── discovery.js # AI-powered source code analysis for specgen
|
|
61
|
+
├── tests/
|
|
62
|
+
│ ├── README.md # Testing strategy docs
|
|
63
|
+
│ ├── utils/ # Test helpers (git, API mocks, builders)
|
|
64
|
+
│ └── scenarios/ # Test scenarios per feature
|
|
65
|
+
├── samples/
|
|
66
|
+
│ └── reports/ # Sample Mochawesome & JUnit files
|
|
67
|
+
├── docs/
|
|
68
|
+
│ └── specgen.md # Specgen design notes
|
|
69
|
+
├── .github/workflows/
|
|
70
|
+
│ └── release.yml # CI/CD pipeline
|
|
71
|
+
└── package.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Key technical decisions
|
|
75
|
+
|
|
76
|
+
### ES Modules
|
|
77
|
+
|
|
78
|
+
The package uses `"type": "module"`. This means:
|
|
79
|
+
|
|
80
|
+
- Use `import` / `export`, not `require()`
|
|
81
|
+
- File extensions are required in imports (e.g., `./commands/featuresync.js`)
|
|
82
|
+
- `__dirname` is not available — use `import.meta.url` instead
|
|
83
|
+
|
|
84
|
+
### Dependencies
|
|
85
|
+
|
|
86
|
+
| Package | Purpose |
|
|
87
|
+
|---------|---------|
|
|
88
|
+
| `commander` | CLI argument parsing |
|
|
89
|
+
| `simple-git` | Git operations (diff, log, status) |
|
|
90
|
+
| `@cucumber/gherkin` | Gherkin `.feature` file parsing |
|
|
91
|
+
| `@anthropic-ai/sdk` | Claude AI for specgen |
|
|
92
|
+
| `@google/generative-ai` | Gemini AI for specgen |
|
|
93
|
+
| `testcollab-sdk` | TestCollab API client (createTestPlan, report) |
|
|
94
|
+
| `testcollab-cypress-plugin` | Shared result upload logic (report) |
|
|
95
|
+
|
|
96
|
+
## Testing
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Run all tests
|
|
100
|
+
npm test
|
|
101
|
+
|
|
102
|
+
# Run a specific test file
|
|
103
|
+
npm test tests/scenarios/initial-sync.test.js
|
|
104
|
+
|
|
105
|
+
# Watch mode
|
|
106
|
+
npm test -- --watch
|
|
107
|
+
|
|
108
|
+
# Coverage report
|
|
109
|
+
npm test -- --coverage
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Tests use **real Git repositories** (created in temp dirs) with **mocked network calls**. See `tests/README.md` for the full testing strategy.
|
|
113
|
+
|
|
114
|
+
### Creating test scenarios
|
|
115
|
+
|
|
116
|
+
Use the test utilities in `tests/utils/`:
|
|
117
|
+
|
|
118
|
+
- `git-helpers.js` — Create temp Git repos, add/modify/delete files, commit
|
|
119
|
+
- `api-mocks.js` — Mock TestCollab API responses
|
|
120
|
+
- `scenario-builders.js` — Build complex test scenarios
|
|
121
|
+
|
|
122
|
+
## How each command works
|
|
123
|
+
|
|
124
|
+
### `tc sync` (featuresync.js)
|
|
125
|
+
|
|
126
|
+
1. Validates Git repo and `TESTCOLLAB_TOKEN`
|
|
127
|
+
2. Calls `GET /bdd/sync?project=<id>` to get the last synced commit
|
|
128
|
+
3. Runs `git diff --find-renames` between last sync and HEAD
|
|
129
|
+
4. Parses changed `.feature` files with `@cucumber/gherkin`
|
|
130
|
+
5. Computes SHA-1 hashes for features and scenarios
|
|
131
|
+
6. Calls `POST /bdd/resolve-ids` to map old hashes to existing TestCollab IDs
|
|
132
|
+
7. Builds a `GherkinSyncDelta` payload and POSTs to `POST /bdd/sync`
|
|
133
|
+
|
|
134
|
+
Key details:
|
|
135
|
+
- Rename detection: `R100` = pure rename, `R097` = rename + content change
|
|
136
|
+
- Hash-based matching with title fallback for ID resolution
|
|
137
|
+
- Handles deleted scenarios within modified files
|
|
138
|
+
|
|
139
|
+
### `tc createTestPlan` (createTestPlan.js)
|
|
140
|
+
|
|
141
|
+
1. Validates project, tag, and assignee exist
|
|
142
|
+
2. Creates a test plan named `CI Test: DD-MM-YYYY HH:MM`
|
|
143
|
+
3. Bulk-adds test cases matching the CI tag
|
|
144
|
+
4. Assigns the plan to the specified user
|
|
145
|
+
5. Writes plan ID to `tmp/tc_test_plan`
|
|
146
|
+
|
|
147
|
+
### `tc report` (report.js)
|
|
148
|
+
|
|
149
|
+
1. Validates API key, project, and test plan
|
|
150
|
+
2. Parses the result file based on `--format`:
|
|
151
|
+
- **Mochawesome**: Walks nested suites, extracts test titles and results
|
|
152
|
+
- **JUnit**: Parses XML `<testcase>` elements
|
|
153
|
+
3. Extracts TestCollab case IDs from test names (patterns: `[TC-123]`, `TC-123`, `id-123`, `testcase-123`)
|
|
154
|
+
4. Optionally extracts configuration IDs (`config-id-<id>`, `config-<id>`)
|
|
155
|
+
5. Maps results: pass → 1, fail → 2, skip → 3
|
|
156
|
+
6. Uploads results to the test plan via TestCollab API
|
|
157
|
+
|
|
158
|
+
### `tc specgen` (specgen.js + ai/discovery.js)
|
|
159
|
+
|
|
160
|
+
1. Scans source directory for `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` files
|
|
161
|
+
2. Sends file summaries to AI for **discovery** — identifies target families and targets
|
|
162
|
+
3. Caches discovery results in `.testcollab/specgen.json`
|
|
163
|
+
4. For each target, generates a `.feature` file with 2-4 scenarios using structured AI output
|
|
164
|
+
5. Falls back to a template feature if AI generation fails
|
|
165
|
+
|
|
166
|
+
## Debugging
|
|
167
|
+
|
|
168
|
+
### Add debug logging
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
// Temporary — add anywhere in command files
|
|
172
|
+
console.log('Debug:', JSON.stringify(payload, null, 2));
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Test with a scratch repo
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
mkdir /tmp/test-repo && cd /tmp/test-repo
|
|
179
|
+
git init && git config user.email "test@test.com" && git config user.name "Test"
|
|
180
|
+
|
|
181
|
+
mkdir -p features/auth
|
|
182
|
+
cat > features/auth/login.feature << 'EOF'
|
|
183
|
+
Feature: Login
|
|
184
|
+
Scenario: Valid credentials
|
|
185
|
+
Given the user is on the login page
|
|
186
|
+
When they enter valid credentials
|
|
187
|
+
Then they should see the dashboard
|
|
188
|
+
EOF
|
|
189
|
+
|
|
190
|
+
git add . && git commit -m "Initial"
|
|
191
|
+
node /path/to/tc-cli/src/index.js sync --project 123
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Mock the API
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
global.fetch = jest.fn().mockResolvedValue({
|
|
198
|
+
ok: true,
|
|
199
|
+
json: () => Promise.resolve({ lastSyncedCommit: null }),
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Publishing
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# 1. Dry-run to check what gets published
|
|
207
|
+
npm pack
|
|
208
|
+
|
|
209
|
+
# 2. Bump version
|
|
210
|
+
npm version patch -m "release %s" # or minor / major
|
|
211
|
+
|
|
212
|
+
# 3. Publish
|
|
213
|
+
npm publish
|
|
214
|
+
|
|
215
|
+
# 4. Push tags
|
|
216
|
+
git push --follow-tags
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The GitHub Actions workflow (`.github/workflows/release.yml`) also handles automated publishing on release creation.
|
|
220
|
+
|
|
221
|
+
### What gets published
|
|
222
|
+
|
|
223
|
+
Controlled by `.npmignore`:
|
|
224
|
+
- **Included:** `src/`, `samples/`, `package.json`, `README.md`, `LICENSE`
|
|
225
|
+
- **Excluded:** `tests/`, `DEV_NOTES.md`, `debug-*.js`, `.env`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TestCollab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# TestCollab CLI
|
|
2
|
+
|
|
3
|
+
Command-line tools for syncing Gherkin feature files, running test plans, and uploading results to [TestCollab](https://testcollab.com).
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npm install -g testcollab-cli
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
Upload test results to TestCollab from your CI pipeline in two steps:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
export TESTCOLLAB_TOKEN=your_token_here
|
|
15
|
+
|
|
16
|
+
# Step 1: Create a test plan with your CI-tagged cases
|
|
17
|
+
tc createTestPlan --project 123 --ci-tag-id 456 --assignee-id 789
|
|
18
|
+
|
|
19
|
+
# Step 2: After running your tests, upload results
|
|
20
|
+
tc report --project 123 --test-plan-id 555 --format junit --result-file ./results.xml
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or sync BDD feature files to TestCollab:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
tc sync --project 123
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
| Command | What it does |
|
|
32
|
+
|---------|-------------|
|
|
33
|
+
| [`tc createTestPlan`](#tc-createtestplan) | Create a test plan and assign tagged cases |
|
|
34
|
+
| [`tc report`](#tc-report) | Upload Mochawesome or JUnit results |
|
|
35
|
+
| [`tc sync`](#tc-sync) | Sync `.feature` files from Git to TestCollab (designed for CI/CD, works locally too) |
|
|
36
|
+
|
|
37
|
+
The most common workflow is **createTestPlan → run your tests → report** to automatically upload test results from CI/CD.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### `tc createTestPlan`
|
|
42
|
+
|
|
43
|
+
Creates a test plan, adds all test cases matching a CI tag, and assigns it to a user. Designed for CI pipelines where you want to automatically create a plan before running tests.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
tc createTestPlan \
|
|
47
|
+
--project <id> \
|
|
48
|
+
--ci-tag-id <id> \
|
|
49
|
+
--assignee-id <id> \
|
|
50
|
+
[--api-key <key>] \
|
|
51
|
+
[--api-url <url>]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| Option | Required | Description |
|
|
55
|
+
|--------|----------|-------------|
|
|
56
|
+
| `--project <id>` | Yes | Project ID |
|
|
57
|
+
| `--ci-tag-id <id>` | Yes | Tag ID — test cases with this tag are added to the plan |
|
|
58
|
+
| `--assignee-id <id>` | Yes | User ID to assign the plan execution to |
|
|
59
|
+
| `--api-key <key>` | No | TestCollab API key (or set `TESTCOLLAB_TOKEN` env var) |
|
|
60
|
+
| `--api-url <url>` | No | API base URL (default: `https://api.testcollab.io`). Use `https://api-eu.testcollab.io` for EU region. |
|
|
61
|
+
|
|
62
|
+
**Output:** Writes the created plan ID to `tmp/tc_test_plan` as `TESTCOLLAB_TEST_PLAN_ID=<id>`. You can source this file in subsequent CI steps.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### `tc report`
|
|
67
|
+
|
|
68
|
+
Parses a test result file (Mochawesome JSON or JUnit XML) and uploads results to a TestCollab test plan.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
tc report \
|
|
72
|
+
--project <id> \
|
|
73
|
+
--test-plan-id <id> \
|
|
74
|
+
--format <mochawesome|junit> \
|
|
75
|
+
--result-file <path> \
|
|
76
|
+
[--api-key <key>] \
|
|
77
|
+
[--api-url <url>]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Option | Required | Description |
|
|
81
|
+
|--------|----------|-------------|
|
|
82
|
+
| `--project <id>` | Yes | Project ID |
|
|
83
|
+
| `--test-plan-id <id>` | Yes | Test plan to attach results to |
|
|
84
|
+
| `--format <type>` | Yes | `mochawesome` or `junit` |
|
|
85
|
+
| `--result-file <path>` | Yes | Path to the result file |
|
|
86
|
+
| `--api-key <key>` | No | TestCollab API key (or set `TESTCOLLAB_TOKEN` env var) |
|
|
87
|
+
| `--api-url <url>` | No | API base URL override (default: `https://api.testcollab.io`). Use `https://api-eu.testcollab.io` for EU region. |
|
|
88
|
+
|
|
89
|
+
#### Mapping test cases
|
|
90
|
+
|
|
91
|
+
Your test names must include a TestCollab case ID so results can be matched. Any of these patterns work:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
[TC-123] Login should succeed ← bracketed
|
|
95
|
+
TC-123 Login should succeed ← prefix
|
|
96
|
+
Login should succeed id-123 ← id- prefix
|
|
97
|
+
Login should succeed testcase-123 ← testcase- prefix
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### Configuration-specific runs
|
|
101
|
+
|
|
102
|
+
If your test plan uses multiple configurations, include the config ID in your test names:
|
|
103
|
+
|
|
104
|
+
- **Mochawesome:** Use `config-id-<id>` as a top-level suite title
|
|
105
|
+
- **JUnit:** Include `config-id-<id>` or `config-<id>` in the test case name or classname
|
|
106
|
+
|
|
107
|
+
#### Sample files
|
|
108
|
+
|
|
109
|
+
See `samples/reports/` for example Mochawesome and JUnit files you can reference.
|
|
110
|
+
|
|
111
|
+
#### Supported frameworks
|
|
112
|
+
|
|
113
|
+
Any framework that can produce **Mochawesome JSON** or **JUnit XML** works with `tc report`. Here's how popular frameworks generate compatible output:
|
|
114
|
+
|
|
115
|
+
| Framework | How to get compatible output | `--format` |
|
|
116
|
+
|-----------|------------------------------|------------|
|
|
117
|
+
| **Cypress** | `mochawesome` reporter (built-in plugin) | `mochawesome` |
|
|
118
|
+
| **Playwright** | `--reporter=junit` | `junit` |
|
|
119
|
+
| **Jest** | `jest-junit` package | `junit` |
|
|
120
|
+
| **Pytest** | `--junitxml=results.xml` (built-in) | `junit` |
|
|
121
|
+
| **TestNG** | Generates JUnit-compatible XML | `junit` |
|
|
122
|
+
| **JUnit 4/5** | Native JUnit XML output | `junit` |
|
|
123
|
+
| **Robot Framework** | `--xunit output.xml` | `junit` |
|
|
124
|
+
| **PHPUnit** | `--log-junit results.xml` (built-in) | `junit` |
|
|
125
|
+
| **Cucumber.js** | JUnit formatter plugin | `junit` |
|
|
126
|
+
| **Cucumber JVM** | JUnit XML via built-in plugin | `junit` |
|
|
127
|
+
| **WebDriverIO** | `@wdio/junit-reporter` | `junit` |
|
|
128
|
+
| **TestCafe** | `testcafe-reporter-junit` | `junit` |
|
|
129
|
+
| **Newman (Postman)** | `newman-reporter-junit` | `junit` |
|
|
130
|
+
| **Behave** | `--junit` flag (built-in) | `junit` |
|
|
131
|
+
| **Go (`go test`)** | `go-junit-report` | `junit` |
|
|
132
|
+
| **Kaspresso / Kotlin** | JUnit XML (inherits from JUnit runner) | `junit` |
|
|
133
|
+
|
|
134
|
+
For detailed setup instructions per framework, see [Framework Setup Guide](docs/frameworks.md).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### `tc sync`
|
|
139
|
+
|
|
140
|
+
Synchronizes Gherkin `.feature` files from your Git repository with TestCollab. Features become test suites, scenarios become test cases. Designed to run in CI/CD pipelines (on push to main), but works locally too — it uses Git commit hashes to track what's already been synced.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
tc sync --project <id> [--api-key <key>] [--api-url <url>]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Option | Required | Description |
|
|
147
|
+
|--------|----------|-------------|
|
|
148
|
+
| `--project <id>` | Yes | TestCollab project ID |
|
|
149
|
+
| `--api-key <key>` | No | TestCollab API key (or set `TESTCOLLAB_TOKEN` env var) |
|
|
150
|
+
| `--api-url <url>` | No | API base URL (default: `https://api.testcollab.io`). Use `https://api-eu.testcollab.io` for EU region. |
|
|
151
|
+
|
|
152
|
+
#### How it works
|
|
153
|
+
|
|
154
|
+
1. Detects which `.feature` files changed since the last sync (using `git diff`)
|
|
155
|
+
2. Parses the Gherkin and calculates content hashes
|
|
156
|
+
3. Sends only the changes to TestCollab (creates, updates, renames, or deletes)
|
|
157
|
+
|
|
158
|
+
Only **committed** files are synced. Uncommitted changes are ignored (with a warning).
|
|
159
|
+
|
|
160
|
+
#### Example output
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
🔍 Fetching sync state from TestCollab...
|
|
164
|
+
📊 Last synced commit: a1b2c3d4
|
|
165
|
+
📊 Current HEAD commit: e5f6g7h8
|
|
166
|
+
📄 Found 3 change(s)
|
|
167
|
+
🚀 Syncing with TestCollab...
|
|
168
|
+
|
|
169
|
+
📊 Synchronization Results:
|
|
170
|
+
✨ Created 1 test case(s)
|
|
171
|
+
🔄 Updated 2 test case(s)
|
|
172
|
+
🔄 Renamed 1 suite(s)
|
|
173
|
+
|
|
174
|
+
✅ Synchronization completed successfully
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Try it with a sample project
|
|
178
|
+
|
|
179
|
+
Fork [testcollab-bdd-demo](https://github.com/TCSoftInc/testcollab-bdd-demo) and run `tc sync` to see how it works before integrating with your own project.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Authentication
|
|
184
|
+
|
|
185
|
+
All commands authenticate the same way. Provide your API key using **either** method:
|
|
186
|
+
|
|
187
|
+
1. **`--api-key` flag** (takes precedence)
|
|
188
|
+
2. **`TESTCOLLAB_TOKEN` environment variable** (recommended for CI/CD)
|
|
189
|
+
|
|
190
|
+
**Getting your API token:** Go to TestCollab → Account Settings → API Tokens.
|
|
191
|
+
|
|
192
|
+
**EU region:** If your TestCollab account is hosted in the EU, pass `--api-url https://api-eu.testcollab.io` to all commands.
|
|
193
|
+
|
|
194
|
+
### Setting the token
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# macOS / Linux
|
|
198
|
+
export TESTCOLLAB_TOKEN=your_token_here
|
|
199
|
+
|
|
200
|
+
# Windows (Command Prompt)
|
|
201
|
+
set TESTCOLLAB_TOKEN=your_token_here
|
|
202
|
+
|
|
203
|
+
# Windows (PowerShell)
|
|
204
|
+
$env:TESTCOLLAB_TOKEN = "your_token_here"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## CI/CD Integration
|
|
210
|
+
|
|
211
|
+
The most common use case is uploading test results from CI: create a test plan, run your tests, then report results back to TestCollab.
|
|
212
|
+
|
|
213
|
+
### GitHub Actions
|
|
214
|
+
|
|
215
|
+
#### Upload test results (create plan + run tests + report)
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
name: Test Pipeline
|
|
219
|
+
on:
|
|
220
|
+
push:
|
|
221
|
+
branches: [main]
|
|
222
|
+
|
|
223
|
+
jobs:
|
|
224
|
+
test:
|
|
225
|
+
runs-on: ubuntu-latest
|
|
226
|
+
env:
|
|
227
|
+
TESTCOLLAB_TOKEN: ${{ secrets.TESTCOLLAB_TOKEN }}
|
|
228
|
+
steps:
|
|
229
|
+
- uses: actions/checkout@v4
|
|
230
|
+
|
|
231
|
+
- uses: actions/setup-node@v4
|
|
232
|
+
with:
|
|
233
|
+
node-version: '22'
|
|
234
|
+
|
|
235
|
+
- run: npm install -g testcollab-cli && npm ci
|
|
236
|
+
|
|
237
|
+
# Step 1: Create test plan with CI-tagged cases
|
|
238
|
+
- run: |
|
|
239
|
+
tc createTestPlan \
|
|
240
|
+
--project ${{ secrets.TC_PROJECT_ID }} \
|
|
241
|
+
--ci-tag-id ${{ secrets.TC_CI_TAG_ID }} \
|
|
242
|
+
--assignee-id ${{ secrets.TC_ASSIGNEE_ID }}
|
|
243
|
+
|
|
244
|
+
# Step 2: Read the created test plan ID
|
|
245
|
+
- run: cat tmp/tc_test_plan >> $GITHUB_ENV
|
|
246
|
+
|
|
247
|
+
# Step 3: Run your tests (example: Cypress)
|
|
248
|
+
- run: npx cypress run --reporter mochawesome
|
|
249
|
+
|
|
250
|
+
# Step 4: Upload results to TestCollab
|
|
251
|
+
- run: |
|
|
252
|
+
tc report \
|
|
253
|
+
--project ${{ secrets.TC_PROJECT_ID }} \
|
|
254
|
+
--test-plan-id $TESTCOLLAB_TEST_PLAN_ID \
|
|
255
|
+
--format mochawesome \
|
|
256
|
+
--result-file ./mochawesome-report/mochawesome.json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Sync feature files (on .feature file changes)
|
|
260
|
+
|
|
261
|
+
If you use BDD and want to keep TestCollab in sync with your `.feature` files:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
name: Sync Feature Files
|
|
265
|
+
on:
|
|
266
|
+
push:
|
|
267
|
+
branches: [main]
|
|
268
|
+
paths: ['**/*.feature']
|
|
269
|
+
|
|
270
|
+
jobs:
|
|
271
|
+
sync:
|
|
272
|
+
runs-on: ubuntu-latest
|
|
273
|
+
steps:
|
|
274
|
+
- uses: actions/checkout@v4
|
|
275
|
+
with:
|
|
276
|
+
fetch-depth: 0 # Full history required for accurate diffs
|
|
277
|
+
|
|
278
|
+
- uses: actions/setup-node@v4
|
|
279
|
+
with:
|
|
280
|
+
node-version: '22'
|
|
281
|
+
|
|
282
|
+
- run: npm install -g testcollab-cli
|
|
283
|
+
|
|
284
|
+
- run: tc sync --project ${{ secrets.TC_PROJECT_ID }}
|
|
285
|
+
env:
|
|
286
|
+
TESTCOLLAB_TOKEN: ${{ secrets.TESTCOLLAB_TOKEN }}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
> **Important:** `tc sync` requires `fetch-depth: 0` so it can compute accurate diffs against the last synced commit.
|
|
290
|
+
|
|
291
|
+
### GitLab CI
|
|
292
|
+
|
|
293
|
+
#### Upload test results
|
|
294
|
+
|
|
295
|
+
```yaml
|
|
296
|
+
test-and-report:
|
|
297
|
+
stage: test
|
|
298
|
+
image: node:22
|
|
299
|
+
variables:
|
|
300
|
+
TESTCOLLAB_TOKEN: $TESTCOLLAB_TOKEN
|
|
301
|
+
before_script:
|
|
302
|
+
- npm install -g testcollab-cli && npm ci
|
|
303
|
+
script:
|
|
304
|
+
- tc createTestPlan --project $TC_PROJECT_ID --ci-tag-id $TC_CI_TAG_ID --assignee-id $TC_ASSIGNEE_ID
|
|
305
|
+
- export $(cat tmp/tc_test_plan)
|
|
306
|
+
- npx cypress run --reporter mochawesome
|
|
307
|
+
- tc report --project $TC_PROJECT_ID --test-plan-id $TESTCOLLAB_TEST_PLAN_ID --format mochawesome --result-file ./mochawesome-report/mochawesome.json
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### Sync feature files
|
|
311
|
+
|
|
312
|
+
```yaml
|
|
313
|
+
sync-features:
|
|
314
|
+
stage: test
|
|
315
|
+
image: node:22
|
|
316
|
+
before_script:
|
|
317
|
+
- npm install -g testcollab-cli
|
|
318
|
+
script:
|
|
319
|
+
- tc sync --project $TC_PROJECT_ID
|
|
320
|
+
variables:
|
|
321
|
+
TESTCOLLAB_TOKEN: $TESTCOLLAB_TOKEN
|
|
322
|
+
only:
|
|
323
|
+
changes:
|
|
324
|
+
- "**/*.feature"
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Troubleshooting
|
|
330
|
+
|
|
331
|
+
### Common errors
|
|
332
|
+
|
|
333
|
+
| Error | Cause | Fix |
|
|
334
|
+
|-------|-------|-----|
|
|
335
|
+
| `TESTCOLLAB_TOKEN environment variable is not set` | Missing token | Set the env var (see [Authentication](#authentication)) |
|
|
336
|
+
| `Not in a Git repository` | CLI run outside a Git repo | Run from inside a Git repository |
|
|
337
|
+
| `Failed to fetch sync state: 404` | Wrong project ID | Check the project ID in TestCollab |
|
|
338
|
+
| `409 Conflict` | Repo state changed since last sync | `git pull` and retry |
|
|
339
|
+
| `Could not process features/x.feature` | Gherkin syntax error | Fix the `.feature` file syntax |
|
|
340
|
+
|
|
341
|
+
### Tips
|
|
342
|
+
|
|
343
|
+
- **Commit before syncing** — Only committed `.feature` files are synced
|
|
344
|
+
- **Sync often** — Smaller changesets are easier to review
|
|
345
|
+
- **Use CI** — Automate sync on push so your test cases are always current
|
|
346
|
+
- **Test first** — Try sync on a dev project before pointing at production
|
|
347
|
+
- **Large repos** — The CLI only processes changed files, so performance scales with changes, not repo size. Keep individual syncs under 6MB.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Requirements
|
|
352
|
+
|
|
353
|
+
- Node.js 18.0.0 or higher
|
|
354
|
+
- Git 2.0 or higher
|
|
355
|
+
|
|
356
|
+
## Installation options
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# Global (recommended)
|
|
360
|
+
npm install -g testcollab-cli
|
|
361
|
+
tc sync --project 123
|
|
362
|
+
|
|
363
|
+
# Local (per-project)
|
|
364
|
+
npm install testcollab-cli --save-dev
|
|
365
|
+
npx tc sync --project 123
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Links
|
|
369
|
+
|
|
370
|
+
- [TestCollab](https://testcollab.com)
|
|
371
|
+
- [Documentation](https://help.testcollab.com)
|
|
372
|
+
- [Sample BDD project](https://github.com/TCSoftInc/testcollab-bdd-demo)
|
|
373
|
+
- [Report a bug](https://github.com/TCSoftInc/testcollab-cli/issues)
|
|
374
|
+
- [Support](mailto:support@testcollab.com)
|
|
375
|
+
|
|
376
|
+
## License
|
|
377
|
+
|
|
378
|
+
MIT
|