Chuyển đến nội dung chính

TestPlanIt Reporter Reporter

@testplanit/wdio-reporter is a 3rd party package, for more information please see GitHub | npm

WebdriverIO reporter and service for TestPlanIt - report test results directly to your TestPlanIt instance.

This package includes:

  • Reporter - Tracks test execution in worker processes and reports results to TestPlanIt
  • Service - Manages the test run lifecycle in the main process, ensuring all workers report to a single test run

Installation

npm install @testplanit/wdio-reporter
# or
pnpm add @testplanit/wdio-reporter
# or
yarn add @testplanit/wdio-reporter

Quick Start

1. Generate an API Token

  1. Log into your TestPlanIt instance
  2. Go to Settings > API Tokens
  3. Click Generate New Token
  4. Copy the token (it starts with tpi_)

2. Configure the Reporter and Service

Add both the service and reporter to your wdio.conf.js or wdio.conf.ts:

// wdio.conf.js
import { TestPlanItService } from '@testplanit/wdio-reporter';

export const config = {
services: [
[TestPlanItService, {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
runName: 'E2E Tests - {date} {time}',
captureScreenshots: true,
}]
],
reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
}]
],
// ... rest of config
}

Note: The service is recommended when running with maxInstances > 1. It creates a single test run before workers start, eliminating race conditions. Without the service, the reporter can still manage test runs on its own using file-based coordination (oneReport: true).

Service vs Reporter

AspectServiceReporter
ProcessMain WDIO processEach worker process
TimingRuns once before/after all workersRuns in each worker
Test run creationCreates in onPrepareFallback: creates if no service
Result reporting-Reports each test result
Screenshot captureOptional (captureScreenshots)-
Screenshot upload-Uploads in onRunnerEnd
Run completionCompletes in onCompleteSkips if service-managed

Linking Test Cases

Embed TestPlanIt case IDs in your test titles using brackets (configurable via caseIdPattern):

describe('Authentication', () => {
it('[12345] should login with valid credentials', async () => {
// This test will be linked to case ID 12345
});

it('[12346] [12347] should show error for invalid password', async () => {
// This test will be linked to multiple cases: 12346 and 12347
});

it('should redirect to dashboard after login', async () => {
// No case ID - will be skipped unless autoCreateTestCases is enabled
});
});

Custom Case ID Patterns

The caseIdPattern option accepts a regex with a capturing group for the numeric ID:

// Default: brackets - "[12345] should work"
caseIdPattern: /\[(\d+)\]/g

// C-prefix: "C12345 should work"
caseIdPattern: /C(\d+)/g

// TC- prefix: "TC-12345 should work"
caseIdPattern: /TC-(\d+)/g

// JIRA-style: "TEST-12345 should work"
caseIdPattern: /TEST-(\d+)/g

Reporter Options

OptionTypeRequiredDefaultDescription
domainstringYes-Base URL of your TestPlanIt instance
apiTokenstringYes-API token for authentication
projectIdnumberYes-Project ID to report results to
testRunIdnumber | stringNo-Existing test run ID or name to append results to
runNamestringNo'{suite} - {date} {time}'Name for new test runs. Supports placeholders: {date}, {time}, {browser}, {platform}, {spec}, {suite}
testRunTypestringNoAuto-detectedTest framework type: 'REGULAR', 'MOCHA', 'CUCUMBER', etc. Auto-detected from WDIO config
configIdnumber | stringNo-Configuration ID or name for the test run
milestoneIdnumber | stringNo-Milestone ID or name for the test run
stateIdnumber | stringNo-Workflow state ID or name for the test run
tagIds(number | string)[]No-Tags to apply (IDs or names). Non-existent tags are created automatically
caseIdPatternRegExp | stringNo/\[(\d+)\]/gRegex to extract case IDs from test titles. Must include a capturing group
autoCreateTestCasesbooleanNofalseAuto-create test cases matched by suite name + test title
createFolderHierarchybooleanNofalseCreate nested folders based on suite structure. Requires autoCreateTestCases and parentFolderId
parentFolderIdnumber | stringNo-Parent folder for auto-created cases (ID or name)
templateIdnumber | stringNo-Template for auto-created cases (ID or name)
uploadScreenshotsbooleanNotrueUpload intercepted screenshots
includeStackTracebooleanNotrueInclude stack traces in results
completeRunOnFinishbooleanNotrueMark test run as completed when done
oneReportbooleanNotrueCombine parallel workers from the same spec file into a single test run. Does not persist across spec file batches — use the service for that
timeoutnumberNo30000API request timeout in ms
maxRetriesnumberNo3Number of retries for failed requests
verbosebooleanNofalseEnable verbose logging

Tip: Options like configId, milestoneId, stateId, parentFolderId, and templateId accept either numeric IDs or string names. When a string is provided, the system looks up the resource by exact name match.

Service Options

OptionTypeRequiredDefaultDescription
domainstringYes-Base URL of your TestPlanIt instance
apiTokenstringYes-API token for authentication
projectIdnumberYes-Project ID to report results to
runNamestringNo'Automated Tests - {date} {time}'Name for the test run. Supports {date}, {time}, {platform}
testRunTypestringNo'MOCHA'Test framework type
configIdnumber | stringNo-Configuration ID or name
milestoneIdnumber | stringNo-Milestone ID or name
stateIdnumber | stringNo-Workflow state ID or name
tagIds(number | string)[]No-Tags to apply (IDs or names)
captureScreenshotsbooleanNofalseAuto-capture screenshots on test failure via afterTest hook
completeRunOnFinishbooleanNotrueMark test run as completed when all workers finish
timeoutnumberNo30000API request timeout in ms
maxRetriesnumberNo3Number of retries for failed requests
verbosebooleanNofalseEnable verbose logging

Note: The service's runName does not support {browser}, {spec}, or {suite} placeholders since it runs before any workers start.

Examples

import { TestPlanItService } from '@testplanit/wdio-reporter';

export const config = {
maxInstances: 5,
services: [
[TestPlanItService, {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
runName: 'E2E Tests - {date} {time}',
captureScreenshots: true,
milestoneId: 'Sprint 42',
tagIds: ['regression', 'automated'],
}]
],
reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
autoCreateTestCases: true,
createFolderHierarchy: true,
parentFolderId: 'Automated Tests',
templateId: 1,
}]
],
}

Reporter Only (Single Worker)

export const config = {
reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
runName: 'E2E Tests - {browser} - {date}',
configId: 1,
milestoneId: 2,
}]
],
}

Append to Existing Test Run

reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
testRunId: 123, // Existing run ID
}]
]

You can also reference a test run by name:

reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
testRunId: 'Nightly Regression', // Looked up by name
}]
]

Auto-Create Test Cases with Folder Hierarchy

reporters: [
['@testplanit/wdio-reporter', {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: 1,
autoCreateTestCases: true,
createFolderHierarchy: true,
parentFolderId: 'Automated Tests',
templateId: 'Default Template',
}]
]

With createFolderHierarchy, nested describe blocks create matching folders:

describe('Authentication', () => {         // Creates folder: Automated Tests > Authentication
describe('Login', () => { // Creates folder: Automated Tests > Authentication > Login
it('should accept valid credentials'); // Test case placed in Login folder
});
});

Environment-Based Configuration

import { TestPlanItService } from '@testplanit/wdio-reporter';

export const config = {
services: [
[TestPlanItService, {
domain: process.env.TESTPLANIT_URL,
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: Number(process.env.TESTPLANIT_PROJECT_ID),
runName: `CI Build ${process.env.CI_BUILD_NUMBER} - ${process.env.CI_BRANCH}`,
milestoneId: process.env.CI_MILESTONE_ID,
}]
],
reporters: [
['@testplanit/wdio-reporter', {
domain: process.env.TESTPLANIT_URL,
apiToken: process.env.TESTPLANIT_API_TOKEN,
projectId: Number(process.env.TESTPLANIT_PROJECT_ID),
autoCreateTestCases: true,
parentFolderId: 10,
templateId: 1,
}]
],
}

Output

When tests complete, the service outputs a summary:

[TestPlanIt Service] Test run created: "E2E Tests - 2025-01-15 10:30:00" (ID: 456)

[TestPlanIt Service] ══════════════════════════════════════════
[TestPlanIt Service] Test Run ID: 456
[TestPlanIt Service] Status: Completed
[TestPlanIt Service] View: https://testplanit.example.com/projects/runs/1/456
[TestPlanIt Service] ══════════════════════════════════════════

Verbose Mode

Enable verbose logging for debugging on both the service and reporter:

services: [
[TestPlanItService, {
// ... other options
verbose: true,
}]
],
reporters: [
['@testplanit/wdio-reporter', {
// ... other options
verbose: true,
}]
]

This will log:

  • Reporter/service initialization
  • Test run and suite creation
  • ID resolution (name lookups)
  • Status mappings
  • Each test result submission
  • Screenshot captures and uploads
  • API errors and retries

Error Handling

  • Service errors in onPrepare will throw and stop the test suite
  • Service errors in onComplete are logged but don't throw (to avoid hiding test results)
  • Reporter errors are logged but don't fail the test suite
  • Failed API requests are retried (configurable via maxRetries)
  • Individual test result failures don't stop other results from being reported

TypeScript Support

Full TypeScript support is included:

import { TestPlanItService } from '@testplanit/wdio-reporter';
import type { TestPlanItReporterOptions, TestPlanItServiceOptions } from '@testplanit/wdio-reporter';

const serviceOptions: TestPlanItServiceOptions = {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN!,
projectId: 1,
captureScreenshots: true,
};

const reporterOptions: TestPlanItReporterOptions = {
domain: 'https://testplanit.example.com',
apiToken: process.env.TESTPLANIT_API_TOKEN!,
projectId: 1,
autoCreateTestCases: true,
parentFolderId: 10,
templateId: 1,
};

Compatibility

WebdriverIO VersionSupported
9.xYes
8.xYes

Requires Node.js 18 or later.

License

MIT

Welcome! How can I help?

WebdriverIO AI Copilot