TestKase
TestKase
|Docs
Test ManagementAutomation

CLI Reference

Complete reference for the @testkase/reporter CLI — all flags, supported formats, debugging, and usage examples.

Installation

Install the reporter as a dev dependency (npm):

npm install --save-dev @testkase/reporter

Or run it directly without installation:

npx @testkase/reporter report --help

Usage

npx @testkase/reporter report \
  --token <PAT> \
  --project-id <PROJECT_ID> \
  --org-id <ORG_ID> \
  --format <FORMAT> \
  --results-file <PATH> \
  [--cycle-id <CYCLE_ID>]        # optional, defaults to TCYCLE-1
  [--api-url <API_URL>]          # optional, defaults to https://api.testkase.com

Flag Reference

FlagRequiredDescription
--tokenYesYour TestKase Personal Access Token (PAT). Generate one from API Keys. Store as a CI/CD secret — never hardcode in pipeline files.
--api-urlNoTestKase API base URL. Defaults to https://api.testkase.com.
--project-idYesTestKase project ID (e.g., PRJ-1). Found in your project settings or URL.
--org-idYesTestKase organization ID. Found on your Profile page.
--cycle-idNoTarget test cycle ID (e.g., TCYCLE-5). Defaults to TCYCLE-1 (the Master Cycle, which always contains every test case in the project). Override to report into a specific cycle — but the test cases you are reporting on must already be linked to that cycle. See Cycle prerequisite.
--formatYesTest output format. Must match the format of your results file. One of: junit, playwright, cypress, testng, nunit, cucumber.
--results-fileYesPath to the test results file (e.g., test-results/junit.xml). Supports absolute paths, relative paths, and glob patterns (e.g., "test-results/junit-*.xml") to match multiple files — useful when a reporter creates one file per spec.
--build-idNoOptional label to tag results with your CI build number (e.g., --build-id "#142"). Stored alongside each execution so you can tell which CI run produced a given result. Typically set from a CI variable like $GITHUB_RUN_NUMBER or $CI_PIPELINE_IID.
--dry-runNoPreview results without pushing to TestKase. Shows matched/unmatched tests, status mapping, and skipped handling.
--verboseNoEnable detailed logging output. Shows API request/response details, file parsing progress, and matching decisions.
--silentNoSuppress all output except errors. Useful for quiet CI logs. Mutually exclusive with --verbose — if both are passed, --silent wins. Note that this also hides warnings, including "N tests have no automation ID" and every attachment failure, so a silent run can look clean while reporting nothing.
--report-skipped-asNoHow to map skipped tests. Options: blocked (default — environment issues), not-executed, ignore (skip entirely).
--automation-id-formatNoRegex pattern used to extract Automation IDs from test names. Default: \[(\d{5})\]. The first capture group is used as the ID. Use _(\\d{5})_ for frameworks that only expose the method name (TestNG, NUnit, Espresso). The captured value must be 5 characters or fewer — the API rejects a longer automation_id with a 400, so a pattern that captures more than the ID itself fails the whole batch.
--missing-id-in-scriptNoHow to handle test results with no [XXXXX] Automation ID in the test name. Options: skip (default — ignore untagged tests), fail (exit with error), create (create a new test case in TestKase).
--unknown-id-in-testkaseNoHow to handle extracted Automation IDs that do not match any test case in TestKase. Options: skip (default — log and continue), fail (exit with error).
--attachments-dirNoPath to a directory of test artifacts (screenshots, videos, logs) to upload. Files whose name contains an Automation ID are mapped to that specific test case; files without one are attached to every executed test case. See Attachments.
--app-urlNoWeb app URL used when building result links. Defaults to a value derived from --api-url — api.testkase.com becomes www.testkase.com.
--timezoneNoAccepted but currently ignored — it has no effect. Execution timestamps are always sent in UTC (ISO-8601) and rendered in your TestKase display timezone.

Configuration Sources

You do not have to pass every flag on the command line. Each setting is resolved in this order, and the first source that has a value wins:

  1. The command-line flag
  2. A config file in your repository
  3. An environment variable

A config file outranks the environment variable. If .testkaserc.json sets a literal token value, the TESTKASE_PAT exported in your CI job is ignored. Use a ${TESTKASE_PAT} placeholder instead — an empty or unset placeholder falls through to the environment as normal.

Environment variables

VariableReplacesNotes
TESTKASE_PAT--tokenThe usual way to pass the PAT in CI.
TESTKASE_API_URL--api-urlFalls back to https://api.testkase.com when neither is set.

Both work for report, create-run and list-projects.

Config file

The reporter looks for a config file starting in the working directory and walking up the tree. It accepts a "testkase" key in package.json, or a .testkaserc, .testkaserc.json, .testkaserc.yaml, .testkaserc.yml, .testkaserc.js or testkase.config.js file. Values may contain ${ENV_VAR} placeholders, which are substituted from the environment — so the file can stay in git while the secret does not.

A .testkaserc.json in the repository root:

{
  "token": "${TESTKASE_PAT}",
  "projectId": "PRJ-1",
  "organizationId": 1173,
  "buildId": "${GITHUB_RUN_NUMBER}"
}

With that file committed, the CI step is just:

npx @testkase/reporter@1 report --format junit --results-file test-results/junit.xml

Only these keys are read:

KeyEquivalent flag
token--token
apiUrl--api-url
projectId--project-id
organizationId--org-id
defaultCycleId--cycle-id
buildId--build-id
appUrl--app-url

defaultFormat, automationIdFormat, missingIdInScript, unknownIdInTestkase and reportSkippedAs are silently ignored in the config file — those flags always carry their built-in default, which wins over the file. Pass them on the command line. --format and --results-file have no config-file equivalent at all and are always required.

Exit Codes

The report command sets a distinct exit code per failure class, so a pipeline can tell "the tests failed" apart from "the reporting failed":

CodeMeaningWhat to do
0Success. Also returned when the file parsed but contained no test results, when no Automation IDs were found and the policy is skip, and for every --dry-run.Nothing. Note that a green exit does not by itself prove anything was reported — read the Reported: N succeeded summary line.
1Results were sent but the API rejected some of them. The most common cause is a test case that is not linked to the target cycle.Check the Errors: list at the end of the output (first 10 shown). See Cycle Prerequisite.
2Authentication or API failure. A required credential is missing (--token, --project-id), the PAT was rejected, or a call to resolve IDs or send results failed outright — including a network error or timeout.Check the token, the org/project IDs and network access from the runner. Nothing was reported, or only earlier batches were.
3File, format or parse error. The results file does not exist, the glob matched nothing, --format is not one of the six supported values, or the file's content does not match the format (XML file with a JSON format, or the reverse).Fix the path or the --format value. No API call was made.
4ID policy failure. Raised only when you opt in: --missing-id-in-script fail with untagged tests, or --unknown-id-in-testkase fail with IDs that do not exist in TestKase.Tag the tests or generate the missing Automation IDs.

create-run exits 2 when --token, --project-id or --org-id is missing; list-projects exits 2 when --token or --org-id is missing (it has no --project-id).

# Fail the build on a reporting problem, but not on rejected individual results
# `|| code=$?` keeps this safe under `set -e` (which CI shells such as GitHub
# Actions' `run:` blocks enable by default).
npx @testkase/reporter@1 report --format junit --results-file test-results/junit.xml || code=$?
if [ "${code:-0}" -ge 2 ]; then
  echo "TestKase reporting failed (exit $code)"
  exit "$code"
fi

How Results Are Sent

Knowing what the reporter does on the wire matters when a CI runner loses the network halfway through.

  • Batches of 500. Results are sent in batches of at most 500 — the maximum the API accepts in one request. Large suites simply make several calls; there is no cap on the total per run.
  • No automatic retry. The reporter does not retry a failed call. An API call that times out (30 seconds) or errors ends the run with exit 2.
  • Partial progress is kept. Batches that already succeeded are not rolled back when a later one fails. Within a batch, each test case is processed independently: some can succeed while others are rejected, which is the 1 exit code.
  • Re-running is safe. Each result is stored per (test case, automation ID, environment) and updated in place, so re-running the same command after a network failure repairs the run rather than duplicating it.
  • Request size. The API accepts a request body of up to 10 MB. A batch of 500 results whose error messages carry very long stack traces can exceed it; splitting the results file, or trimming stack traces at the source, is the fix.
  • Rate limit. The API allows 200 requests per minute from the same address and answers 429 beyond that. A plain reporting run is a handful of calls, but uploading hundreds of attachments makes two API calls per file per test case and can reach the limit.

Cycle Prerequisite

Every test case you report on must already be linked to the target test cycle. The API rejects a result whose test case is not in that cycle with Test case not linked with this test cycle, and the reporter exits with code 1 — which turns your pipeline red on the very first run.

  • TCYCLE-1 — the Master Cycle, created automatically with every project — always contains every test case, so it needs no setup. It is the default when you omit --cycle-id.
  • Any other cycle only contains the test cases you added to it. Add them on the cycle's test case tab before you point the reporter at it.

Per-Automation-ID Run Tracking

Each test result sent by the reporter is tagged with the automation ID that produced it. TestKase stores a separate run entry per (test case, automation ID, environment) combination, which powers the Automation Runs card on the execute page.

The environment is filled in automatically by the reporter when the results file carries one — from the Playwright project name for --format playwright, or from a trailing [Chrome]-style tag on the suite name for --format junit. The same automation ID reported from two different environments therefore produces two run entries, not one that overwrites the other.

How It Works

  1. The reporter extracts [XXXXX] automation IDs from your test names.
  2. Each result is sent with its automation_id to the execute-bulk API.
  3. The backend creates (or updates) a run entry per test case, per automation ID, per environment.
  4. When the same automation ID reports again from the same environment, the existing entry is updated (UPSERT) — no duplicates.
  5. The test case's overall status uses worst-status-wins precedence: fail > blocked > not_executed > pass.

When a Test Case Has Multiple Automation IDs

If a test case is linked to multiple automation IDs (e.g., one per CI pipeline or browser), the reporter sends one result per automation ID in the same bulk call. Each run is tracked independently:

  • If 12345 passes and 67890 fails → overall status is Fail (worst wins)
  • Both runs remain visible in the Automation Runs card with individual status, duration, and error details
  • Re-running 67890 as Pass updates that specific entry and re-computes the overall status

See the automation guide for the full behavior.

Retry Details

When tests run with retries enabled, the reporter captures the full retry log — status, duration, and error for each attempt — and stores it in the Error Message field of the automation run. Flaky tests (failed then eventually passed) are detected automatically and labelled as such in Actual Result.

See Retry Details on the execution docs for how this appears on the execute page.

What lands in Actual Result. The reporter writes one of four values, so you can filter or search on them exactly:

OutcomeActual Result
Flaky (failed, then passed on a retry)Flaky — passed after N retry(ies) — with an em dash, and retry(ies) literally
FailedThe error message from the results file (for Playwright, its first line)
PassedPassed
Skipped, reported as BlockedBlocked
Skipped, reported as Not ExecutedLeft empty

The full per-attempt log goes into Error Message, not Actual Result.

Retry support by format:

FormatSupportDetails
playwrightFullExtracts every test.results[] entry from Playwright JSON with per-attempt status, duration, error message, and stack trace
junitPartialDetects Maven Surefire's <flakyFailure>, <flakyError>, <rerunFailure>, <rerunError> elements. Captures per-attempt error + stack but not per-attempt duration (format limitation). Gradle's test-retry plugin writes each attempt as a separate <testcase> element instead, so its retries are parsed as separate results, not as attempts of one test
cypressNoneMochawesome JSON does not record per-attempt retry data
testngNoneTestNG XML uses a single <test-method> per result
nunitNoneNUnit XML uses a single <test-case> per result
cucumberNoneCucumber JSON does not have a retry concept

When a format does not support retries, the reporter only sees the final attempt — previous attempts are discarded by the test framework before the result file is written. This is a framework/format limitation, not a TestKase limitation.

If your framework supports both a native format and JUnit (e.g. Playwright), prefer the native format for richer retry data. Playwright's native JSON captures per-attempt durations; its JUnit output does not.

Attachments

The reporter can upload screenshots, videos, logs, and other artifacts and attach them to the matched test cases on the execute page. Attachments come from two sources, and both run automatically on every report invocation:

1. Framework-parsed attachments

Some result formats embed artifact paths directly, and the reporter picks them up with no extra flags:

  • Playwright JSON — attachments recorded on each test (screenshots, videos, traces). For retried tests, only the final attempt's artifacts are kept.
  • JUnit XML — [[ATTACHMENT|path]] entries in a test's <system-out> (the convention Playwright's JUnit reporter and others use).
  • NUnit XML — <attachments><attachment><filePath>…</filePath></attachment></attachments> on a test case.
  • Cucumber JSON — step embeddings, which carry their data inline (base64) rather than as a path. The embedding's mime_type decides whether the API accepts it.

Each parsed artifact is attached to the test case(s) mapped to that result's Automation ID. Relative paths are resolved against the results file's directory.

2. Generic --attachments-dir scan

Point --attachments-dir at a folder of artifacts and the reporter scans every file in it:

npx @testkase/reporter report \
  --token $TESTKASE_PAT \
  --project-id PRJ-1 \
  --org-id 1173 \
  --format junit \
  --results-file test-results/junit.xml \
  --attachments-dir test-results/screenshots
  • If a file's name contains an Automation ID it is attached to that specific test case. The filename is matched with the same --automation-id-format regex used for test names, so with the default pattern the brackets are part of the match: name the file login-[48271].png, not login-48271.png.
  • If a file has no Automation ID in its name, it is attached to every test case that was executed in this run.

Limits & upload flow

  • Per-file cap: 50 MB. Files larger than 50 MB are skipped with a warning; the rest still upload. A file that slips past the reporter's own check is rejected by the API with File exceeds 50MB limit.
  • File types are restricted. The API accepts images (PNG, JPEG, GIF, WebP, SVG, BMP, TIFF, ICO, AVIF, HEIC/HEIF), video (MP4, MOV, AVI, MKV, WebM) and documents (PDF, Word, Excel, .txt, .csv, .md). Anything else is rejected with Unsupported file type — which notably includes .zip (Playwright traces), .json, .html and .xml, and any file whose extension the reporter cannot map at all.
  • The reporter maps a narrower set of extensions than the API accepts. For files picked up by --attachments-dir, the reporter derives the content type from the extension, and it only knows .png, .jpg, .jpeg, .gif, .webp, .svg, .mp4, .webm, .avi, .pdf, .txt, .log, .csv (plus .zip, .json, .html, .xml, which the API then rejects). Anything else — including .mov, .mkv, .bmp, .tiff, .heic, .md and Office documents — is sent as application/octet-stream and rejected with Unsupported file type, even though the API would have accepted the format under its proper content type. Convert screen recordings to .mp4 or .webm before pointing --attachments-dir at them.
  • Organization storage quota. Uploaded files count against your organization's storage. Once it is full, uploads are rejected with Organization storage limit exceeded until you free space or add storage.
  • Uploads use presigned S3 URLs in three steps: the reporter requests a presigned URL, PUTs the file to storage, then finalizes the attachment. An upload that reaches storage but never finalizes — because the run was cancelled or the last call failed — is cleaned up by a daily sweep that removes unfinalized uploads once they are more than 24 hours old, so in the worst case one lingers for about two days. It never counts against your quota in the meantime, because quota is only charged when an upload finalizes.
  • Every attachment failure is a warning, never an error. Skipped and failed uploads do not change the exit code. Run with --verbose to see per-file upload decisions, and check the Attachments: N uploaded, N skipped, N failed summary line at the end of the run.

Supported Formats

FormatFile TypeFrameworksQuick Start
junit.xmlJest, Mocha, pytest, Selenium, WebdriverIO, Robot Framework, Detox, Espresso, XCUITest, PlaywrightMost universal — works with any framework that produces JUnit XML
playwright.jsonPlaywrightRicher data than JUnit (attachments, retries, traces)
cypress.jsonCypress (via mochawesome)Native Cypress JSON output
testng.xmlTestNG, Appium (with TestNG)Java/Android test suites
nunit.xmlNUnit.NET test suites
cucumber.jsonCucumber (JS/Java/Ruby)BDD scenarios

Format-Specific Guidance

JUnit XML (--format junit)

The most universal format. Most test frameworks can produce JUnit XML output, making this the recommended default for cross-framework compatibility.

FrameworkCommand / Setup
Jestnpx jest --reporters=jest-junit (requires jest-junit package)
Mochanpx mocha --reporter mocha-junit-reporter
pytestpytest --junitxml=test-results/junit.xml
Playwrightnpx playwright test --reporter=junit
Java (Maven)Surefire plugin — outputs to target/surefire-reports/ by default
.NETdotnet test --logger "junit;LogFileName=junit.xml" --results-directory test-results (requires the JunitXml.TestLogger NuGet package — dotnet add package JunitXml.TestLogger; without it you get The test logger 'junit' was not found)
Robot Frameworkrobot --xunit test-results/robot-junit.xml
WebdriverIO@wdio/junit-reporter package (the unscoped wdio-junit-reporter is a WebdriverIO v4 package, last published in 2018 — do not use it)

See the Test Frameworks section for detailed setup guides.


Playwright (--format playwright)

Use the JSON reporter for the richest data (attachments, retries, traces):

// playwright.config.ts
reporter: [['json', { outputFile: 'test-results/playwright.json' }]],
# 1. Run tests (generates test-results/playwright.json)
npx playwright test

# 2. Report to TestKase
npx @testkase/reporter report --format playwright \
  --results-file test-results/playwright.json ...

Alternatively, use --format junit with Playwright's JUnit reporter for cross-framework compatibility:

// playwright.config.ts
reporter: [['junit', { outputFile: 'test-results/playwright-junit.xml' }]],
# 1. Run tests (generates test-results/playwright-junit.xml)
npx playwright test

# 2. Report to TestKase
npx @testkase/reporter report --format junit \
  --results-file test-results/playwright-junit.xml ...

The reporter extracts 5-digit Automation IDs from test titles using the [XXXXX] bracket pattern. See the Playwright guide for full setup instructions.


Cypress (--format cypress)

Use cypress-mochawesome-reporter for native Cypress JSON output. It needs three pieces of configuration — the reporter, the plugin hook, and the support-file import. Miss either of the last two and no JSON file is written at all:

// cypress.config.js
const { defineConfig } = require('cypress');

module.exports = defineConfig({
  reporter: 'cypress-mochawesome-reporter',
  reporterOptions: { reportDir: 'test-results', overwrite: false, json: true },
  e2e: {
    setupNodeEvents(on, config) {
      require('cypress-mochawesome-reporter/plugin')(on);
    },
  },
});
// cypress/support/e2e.js
import 'cypress-mochawesome-reporter/register';
# Report to TestKase
npx @testkase/reporter report --format cypress \
  --results-file test-results/mochawesome.json ...

Alternatively, use --format junit with mocha-junit-reporter for cross-framework compatibility:

// cypress.config.js
reporter: 'mocha-junit-reporter',
reporterOptions: { mochaFile: 'test-results/junit-[hash].xml' }
# Report to TestKase
npx @testkase/reporter report --format junit \
  --results-file test-results/junit-*.xml ...

See the Cypress guide for full setup instructions.


TestNG (--format testng)

Where TestNG writes testng-results.xml depends on how you run it:

RunnerPath to testng-results.xml
Maven (Surefire)target/surefire-reports/testng-results.xml
TestNG directly (java -cp … org.testng.TestNG, IDE runners)test-output/testng-results.xml
GradleNot written by default — Gradle sets useDefaultListeners = false, which disables TestNG's own reporters. Either set useDefaultListeners = true inside useTestNG { }, or use --format junit against Gradle's own XML in build/test-results/test/
# 1. Run tests
mvn test

# 2. Report to TestKase
npx @testkase/reporter report --format testng \
  --results-file target/surefire-reports/testng-results.xml ...

See the TestNG guide for full setup instructions.


NUnit (--format nunit)

Generate NUnit XML reports with the --logger flag:

# 1. Generate results
dotnet test --logger "nunit;LogFileName=nunit-results.xml" --results-directory test-results

# 2. Report to TestKase
npx @testkase/reporter report --format nunit \
  --results-file test-results/nunit-results.xml ...

Pass --results-directory explicitly. Without it the logger writes into TestResults/ relative to the test project, not into your working directory, and the reporter exits 3 with "File not found".

See the NUnit guide for full setup instructions.


Cucumber (--format cucumber)

Cucumber tests produce JSON reports. Configure the JSON formatter in your runner:

// cucumber.js
module.exports = { default: '--format json:test-results/cucumber.json' }
# Report to TestKase
npx @testkase/reporter report --format cucumber \
  --results-file test-results/cucumber.json ...

See the Cucumber guide for full setup instructions.

Additional Commands

create-run

Create a new test cycle in TestKase:

npx @testkase/reporter create-run \
  --token $TESTKASE_PAT \
  --project-id PRJ-1 \
  --org-id 1173 \
  --api-url https://api.testkase.com \
  --title "CI Build #$GITHUB_RUN_NUMBER"

Returns the cycle ID on success.

FlagRequiredDescription
--tokenYesPAT token (or env: TESTKASE_PAT)
--project-idYesProject ID (e.g., PRJ-1)
--org-idYesOrganization ID
--api-urlNoAPI base URL. Defaults to https://api.testkase.com.
--titleYesCycle title (e.g., "CI Build #123")

A cycle created this way is empty — do not report straight into it. create-run creates the cycle and nothing else; it does not copy or link any test cases. Point --cycle-id at that fresh cycle and every result is rejected with Test case not linked with this test cycle and the reporter exits 1. See Cycle Prerequisite. To get a per-build view without this problem, report into a cycle that already holds the test cases (or TCYCLE-1) and tag the run with --build-id, which is what the CI templates do.

list-projects

List all projects accessible with your PAT. Useful for verifying your token and finding project IDs:

npx @testkase/reporter list-projects \
  --token $TESTKASE_PAT \
  --org-id 1173 \
  --api-url https://api.testkase.com
FlagRequiredDescription
--tokenYesPAT token (or env: TESTKASE_PAT)
--org-idYesOrganization ID
--api-urlNoAPI base URL. Defaults to https://api.testkase.com.

Dry Run & Debugging

Before pushing results to TestKase for the first time, use the --dry-run flag to preview the matching without actually updating any data:

npx @testkase/reporter report \
  --token $TESTKASE_PAT \
  --project-id PRJ-1 \
  --org-id 1173 \
  --format junit \
  --results-file test-results/junit.xml \
  --dry-run \
  --verbose

What Dry Run Shows

  • Extracted Automation IDs — Every ID the reporter pulled out of your test names, with the status, duration and test name it came from.
  • Tests with no Automation ID — Tests in the results file whose names did not match the --automation-id-format regex.
  • Status mapping — What status each test would be reported as (Pass, Fail, Blocked, Not Executed).
  • Skipped handling — How skipped tests are being mapped based on your --report-skipped-as setting.

A dry run makes no API calls — with one exception, below. It cannot tell you whether an extracted ID actually exists in TestKase, or whether the target cycle contains the matching test case — it only shows what the reporter parsed out of your results file. Run once without --dry-run to confirm the IDs resolve.

Because nothing is sent, --dry-run does not need --token or --project-id (unless you combine it with --missing-id-in-script create, which does). You can run it locally against a results file before you have a PAT. It always exits 0 unless the file itself could not be read or parsed (3), or --missing-id-in-script fail is set and tests are untagged (4).

Verbose Logging

Add --verbose for detailed output during troubleshooting. This shows:

  • API request/response details
  • File parsing progress
  • Individual test case matching decisions
  • Error details with stack traces

Questions

▶My first run reported nothing

This is the most common first-run failure. If you pass --cycle-id TCYCLE-5, open that cycle in TestKase and confirm the test cases behind your Automation IDs are listed there. Otherwise every result is rejected and the reporter exits 1.

▶Why wasn't my attachment attached?

The brackets are not optional. login-48271.png does not match the default \[(\d{5})\] pattern — it counts as a file with no Automation ID and is uploaded to every executed test case. Use login-[48271].png, or pass the --automation-id-format that matches your naming (e.g. _(\\d{5})_ for login_48271_chrome.png).

▶What happens to an attachment with no ID?

A file with no Automation ID in its name is uploaded once per executed test case, not once. Point --attachments-dir at a folder of 20 unnamed screenshots on a run covering 100 test cases and the reporter performs 2,000 uploads — enough to hit the API rate limit and to consume storage quota quickly. Name artifacts after the Automation ID (login-[48271].png) whenever you can.

▶Does a failed attachment fail the build?

Attachment upload failures never change the exit code. If every screenshot fails to upload, the reporter still exits 0 — the Attachments: N uploaded, N failed summary line is the only signal.

▶Which results format should I use?

Which format should I use? - Playwright supports both --format playwright (JSON) and --format junit (XML). Use playwright for richer data (attachments, retry details). Use junit if you want a universal format across multiple frameworks.

  • All other frameworks — start with junit unless a framework-specific format is listed above.
  • Use framework-specific formats (playwright, cypress, testng, nunit, cucumber) only when the framework has a native reporter that provides richer data than JUnit XML.
▶Is --dry-run completely safe?

--dry-run does not neutralise --missing-id-in-script create. Test-case creation runs before the dry-run check, so --dry-run --missing-id-in-script create still calls the API and still writes new test cases and Automation IDs into your project — it only skips sending the results. To preview safely, leave --missing-id-in-script at its default skip.

▶How do I check my setup before wiring up CI?

Run with --dry-run --verbose as part of your initial setup to verify everything is configured correctly before enabling real reporting. This is especially useful for validating Automation ID matching.