Overview
The TestCollab CLI (@testcollab/cli) lets you create test plans and upload automated test results directly from your CI/CD pipeline. It supports two report formats:
JUnit XML — works with Java (JUnit, TestNG), Python (pytest), C# (NUnit, xUnit), Go, PHP, Robot Framework, and most other test frameworks
Mochawesome JSON — works with Cypress and Mocha-based frameworks
Installation
Requires Node.js 18+.
npm install -g @testcollab/cli
Or install as a dev dependency in your project:
npm install @testcollab/cli --save-dev npx tc report ...
Authentication
The CLI authenticates using an API token. You can get your token from TestCollab → Account Settings → API Tokens.
Set it as an environment variable (recommended for CI/CD):
export TESTCOLLAB_TOKEN=your_api_token_here
Or pass it directly via flag:
tc report --api-key your_api_token_here ...
The --api-key flag takes precedence over the environment variable if both are set.
API Region
By default the CLI connects to https://api.testcollab.io (US region). If your account is on the EU region, pass:
--api-url https://api-eu.testcollab.io
Workflow: 3 Steps
The CLI follows a 3-step workflow in your CI pipeline:
Create a test plan —
tc createTestPlancreates a plan with tagged test cases and writes the plan ID to a fileRun your tests — execute your test suite normally (Cypress, Playwright, pytest, JUnit, etc.)
Upload results —
tc reportparses the result file and uploads it to the test plan
Step 1: Create Test Plan
tc createTestPlan \ --project <project-id> \ --ci-tag-id <tag-id> \ --assignee-id <user-id>
Flag | Required | Description |
| Yes | Your TestCollab project ID |
| Yes | Tag ID — test cases with this tag are added to the plan |
| Yes | User ID to assign the plan execution to |
| No | API token (or set |
| No | API base URL (defaults to US region) |
This command creates a test plan and writes the plan ID to tmp/tc_test_plan in the format:
TESTCOLLAB_TEST_PLAN_ID=555
You can source this file in subsequent CI steps to get the plan ID.
Step 2: Run Your Tests
Run your test framework as usual. Make sure to output results in JUnit XML or Mochawesome JSON format. See the Supported Frameworks section below for specific commands.
Step 3: Upload Results
tc report \ --project <project-id> \ --test-plan-id <plan-id> \ --format <mochawesome|junit> \ --result-file <path-to-results>
Flag | Required | Description |
| Yes | Your TestCollab project ID |
| Yes | Test plan ID (from Step 1) |
| Yes |
|
| Yes | Path to the result file |
| No | API token (or set |
| No | API base URL (defaults to US region) |
Test Case ID Mapping
For the CLI to match your test results to TestCollab test cases, include the test case ID in your test names using any of these patterns:
Pattern | Example Test Name |
|
|
|
|
|
|
|
|
All patterns are case-insensitive. The number after the prefix is the TestCollab test case ID.
Configuration Support
If your test plan uses multiple configurations (e.g., different browsers or environments), you can tag tests with a configuration ID:
Mochawesome: Use
config-id-<id>as a top-level suite titleJUnit: Include
config-id-<id>in the test casenameorclassnameattribute
Results are grouped by configuration ID and matched to the correct execution in the test plan.
Supported Frameworks
Any framework that outputs JUnit XML or Mochawesome JSON works with the CLI. Here are common examples:
Framework | Output Command | Format |
Cypress | Built-in mochawesome reporter |
|
Playwright |
|
|
Jest |
|
|
Pytest |
|
|
JUnit 4/5 | Native XML output |
|
TestNG | Native JUnit XML output |
|
NUnit / xUnit (.NET) | Native JUnit XML output |
|
Robot Framework |
|
|
PHPUnit |
|
|
Go (go test) |
|
|
Cucumber | JUnit formatter plugin |
|
WebdriverIO |
|
|
TestCafe |
|
|
Newman (Postman) |
|
|
CI/CD Examples
GitHub Actions
name: Tests
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
env:
TESTCOLLAB_TOKEN: ${{ secrets.TESTCOLLAB_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm install -g @testcollab/cli && npm ci
- name: Create test plan
run: |
tc createTestPlan \
--project ${{ secrets.TC_PROJECT_ID }} \
--ci-tag-id ${{ secrets.TC_CI_TAG_ID }} \
--assignee-id ${{ secrets.TC_ASSIGNEE_ID }}
- name: Load test plan ID
run: cat tmp/tc_test_plan >> $GITHUB_ENV
- name: Run tests
run: npx playwright test --reporter=junit --output=results.xml
- name: Upload results
if: always()
run: |
tc report \
--project ${{ secrets.TC_PROJECT_ID }} \
--test-plan-id $TESTCOLLAB_TEST_PLAN_ID \
--format junit \
--result-file ./results.xml
GitLab CI
test:
image: node:22
variables:
TESTCOLLAB_TOKEN: $TESTCOLLAB_TOKEN
script:
- npm install -g @testcollab/cli && npm ci
- tc createTestPlan --project $TC_PROJECT_ID --ci-tag-id $TC_CI_TAG_ID --assignee-id $TC_ASSIGNEE_ID
- source tmp/tc_test_plan
- npx playwright test --reporter=junit --output=results.xml
- tc report --project $TC_PROJECT_ID --test-plan-id $TESTCOLLAB_TEST_PLAN_ID --format junit --result-file ./results.xml
Jenkins (Pipeline)
pipeline {
agent any
environment {
TESTCOLLAB_TOKEN = credentials('testcollab-token')
TC_PROJECT_ID = '42'
TC_CI_TAG_ID = '10'
TC_ASSIGNEE_ID = '5'
}
stages {
stage('Setup') {
steps {
sh 'npm install -g @testcollab/cli && npm ci'
}
}
stage('Create Plan') {
steps {
sh "tc createTestPlan --project ${TC_PROJECT_ID} --ci-tag-id ${TC_CI_TAG_ID} --assignee-id ${TC_ASSIGNEE_ID}"
script {
env.TESTCOLLAB_TEST_PLAN_ID = sh(script: "grep -oP '(?<=TESTCOLLAB_TEST_PLAN_ID=).*' tmp/tc_test_plan", returnStdout: true).trim()
}
}
}
stage('Test') {
steps {
sh 'npx playwright test --reporter=junit --output=results.xml'
}
}
stage('Report') {
steps {
sh "tc report --project ${TC_PROJECT_ID} --test-plan-id ${TESTCOLLAB_TEST_PLAN_ID} --format junit --result-file ./results.xml"
}
}
}
}
Azure DevOps
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '22.x'
- script: npm install -g @testcollab/cli && npm ci
displayName: Install dependencies
- script: |
tc createTestPlan \
--project $(TC_PROJECT_ID) \
--ci-tag-id $(TC_CI_TAG_ID) \
--assignee-id $(TC_ASSIGNEE_ID)
displayName: Create test plan
env:
TESTCOLLAB_TOKEN: $(TESTCOLLAB_TOKEN)
- script: |
source tmp/tc_test_plan
echo "##vso[task.setvariable variable=TESTCOLLAB_TEST_PLAN_ID]$TESTCOLLAB_TEST_PLAN_ID"
displayName: Load test plan ID
- script: npx playwright test --reporter=junit --output=results.xml
displayName: Run tests
- script: |
tc report \
--project $(TC_PROJECT_ID) \
--test-plan-id $(TESTCOLLAB_TEST_PLAN_ID) \
--format junit \
--result-file ./results.xml
displayName: Upload results
condition: always()
env:
TESTCOLLAB_TOKEN: $(TESTCOLLAB_TOKEN)
Bitbucket Pipelines
pipelines:
default:
- step:
name: Run Tests & Upload Results
image: node:22
script:
- npm install -g @testcollab/cli && npm ci
- tc createTestPlan --project $TC_PROJECT_ID --ci-tag-id $TC_CI_TAG_ID --assignee-id $TC_ASSIGNEE_ID
- source tmp/tc_test_plan
- npx playwright test --reporter=junit --output=results.xml
- tc report --project $TC_PROJECT_ID --test-plan-id $TESTCOLLAB_TEST_PLAN_ID --format junit --result-file ./results.xml
Troubleshooting
Common Errors
Error | Solution |
| Set the |
| Check the project ID and ensure your API token has access |
| Verify the tag ID belongs to the specified project |
| Check the path to your result file is correct |
| Your JUnit XML file may be empty or malformed |
Warnings
Warning | Meaning |
| Some test names don't include a recognized ID pattern (TC-123, id-123, etc.) |
| The test case ID exists but isn't assigned to the specified user in the plan |
Prerequisites Checklist
Before setting up the CLI in your pipeline, make sure you have:
A TestCollab API token (from Account Settings → API Tokens)
Your project ID (visible in the project URL or settings)
A tag applied to the test cases you want to include in CI runs (note the tag ID)
The assignee user ID for the pipeline executions
Test case IDs embedded in your test names (e.g.,
[TC-42] Login test)
