Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

TestGlance

CIGitHub MarketplaceLicense: MITCoverage

Zero-config test reporting for GitHub Actions. Never breaks your CI.

  • Zero config — auto-detects test report files; no report-path required
  • Rich CI summaries — failed tests with stack traces, slowest tests, per-suite breakdowns
  • PR comments — multi-job test summaries posted directly on pull requests
  • Inline annotations — failed tests annotated directly on the PR diff (opt-in)
  • Non-blocking — guaranteed exit code 0, your builds are always safe

Quick Start

No signup, no account, no outbound calls to TestGlance.

- uses: testglance/action@v1

That's it. TestGlance auto-detects your test reports and generates a CI summary.

Have your AI agent install it

Most agents (Claude Code, Cursor, Windsurf, ...) will set this up end-to-end if you point them at the install prompt:

Install TestGlance in this project — instructions and per-framework guides at https://www.testglance.dev/install/index.md

The agent fetches the matching https://www.testglance.dev/install/<framework>.md page (vitest, jest, playwright, mocha, cypress, pytest, go, rspec, phpunit, junit5, dotnet, or other), wires up the JUnit reporter, and adds the workflow step. The copy-pasteable prompt is on the TestGlance landing page.

With PR Comments

permissions:
contents: readpull-requests: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}

Requires pull-requests: write permission. See Permissions for details.

With TestGlance Platform (coming soon)

The hosted TestGlance dashboard — health scores, flaky test detection, and trend tracking — is in development. The api-key input is reserved for this integration but is not yet active.

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soon

Features

  • Failed Test Details — up to 30 lines of stack traces per failure, formatted in collapsible sections
  • Slowest Tests — configurable top-N ranking to spot performance bottlenecks
  • Suite Breakdown — per-suite pass/fail/skip counts and durations
  • Auto-Detection — finds **/test-results/*.xml, **/junit.xml, **/ctrf/*.json, and more
  • Multi-File Merge — glob patterns merge multiple report files into a single summary
  • Inline Annotations — opt-in failure annotations on the PR diff at the exact file:line
  • PR Comments — multi-job summaries merged into a single comment, updated on re-runs
  • Run History — recent runs tracked via GitHub Actions Cache; no account, no external service
  • Flaky Test Detection — flags tests that flip between pass and fail across recent runs
  • Performance Regression Detection — flags tests running far slower than their historical median, with a duration trend sparkline
  • HTML Report — self-contained report uploaded as a workflow artifact on every run
  • SaaS Dashboard(coming soon) — optional org-wide health scores and long-term trend tracking

Feature Comparison

FeatureTestGlancedorny/test-reporterctrf-io/github-test-reportermikepenz/action-junit-reportEnricoMi/publish-unit-test-result-action
Zero Config
JUnit + CTRFBothJUnit onlyCTRF onlyJUnit onlyJUnit only
Failed Test Details
Slowest Tests
Suite Breakdown
Check Runs
PR Comments
Never Fails CIConfigurableConfigurableConfigurable
Multi-File Merge
Auto-Detect Files
SaaS DashboardComing soon

Usage Examples

Basic — Auto-Detect

- uses: testglance/action@v1

With PR Comments

- uses: testglance/action@v1with:
github-token: ${{ github.token }}

With Inline Failure Annotations

permissions:
checks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: truecheck-name: Unit Tests

With TestGlance Platform (coming soon)

- uses: testglance/action@v1with:
api-key: ${{ secrets.TESTGLANCE_API_KEY }} # reserved — SaaS coming soongithub-token: ${{ github.token }}

Multi-Job Workflows

Each GitHub Actions job runs on its own runner with its own filesystem and Job Summary. Add the TestGlance step to every job that produces test reports — results are automatically merged into a single PR comment.

jobs:
unit:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}e2e:
needs: unitruns-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: actions/checkout@v4
- run: pnpm install && pnpm test:e2e
- uses: testglance/action@v1if: always()with:
github-token: ${{ github.token }}

Use if: always() so results are reported even when tests fail. Use test-job-name to disambiguate jobs in the merged PR comment if the default job name isn't clear enough.

Org-Wide Reusable Workflow

See examples/reusable-workflow.yml for a workflow_call template you can deploy across your organization. More examples in the examples/ directory.

Inputs

InputRequiredDefaultDescription
report-pathNo'' (auto-detect)Path to test report file(s). Supports glob patterns.
api-keyNo''TestGlance project API key (reserved — SaaS coming soon)
api-urlNohttps://www.testglance.devTestGlance API URL (reserved — SaaS coming soon)
report-formatNoautoFormat: junit, ctrf, or auto (detect from extension)
test-job-nameNo''Override the display name for this test job
slowest-testsNo10Number of slowest tests to show in CI summary (0 to disable)
show-all-testsNoautoList every test name under each suite in the CI summary. auto shows them when the run is small enough to fit.
send-resultsNotrueSend results to TestGlance API. Automatically forced to false when no api-key is provided.
github-tokenNo''GitHub token for PR comments and Check Runs
annotate-failuresNofalseAnnotate failed tests inline on the PR diff (creates a Check Run)
check-nameNoTest ResultsName of the Check Run created by annotate-failures
annotation-levelNofailureSeverity for inline failure annotations: failure, warning, or notice. warning/notice keep the check advisory.
summary-templateNo''Path to a Handlebars template that replaces the default CI summary. See Custom Templates.
comment-templateNo''Path to a Handlebars template that replaces the default PR comment body. See Custom Templates.
historyNotrueTrack run history via GitHub Actions Cache. Powers flaky and performance-regression detection.
history-limitNo20Maximum number of runs kept in history
compare-branchNo''On PRs, baseline the trend line and "vs base" comparison against this branch (e.g. main). Defaults to the PR base branch
flaky-thresholdNo2Minimum pass/fail status flips over the last 10 runs to flag a test as flaky
perf-thresholdNo200Percent increase over a test's median historical duration to flag as a regression (200 = 3× slower)
html-reportNotrueGenerate a self-contained HTML report and upload it as a workflow artifact
artifact-nameNotestglance-reportName of the uploaded HTML report artifact

Note on annotation-level: The Check Run's conclusion is still failure whenever tests fail, regardless of annotation-level. Setting warning or notice only changes the severity of the inline annotations — it does not change the check outcome. This is the dial for teams who want inline failure annotations without those annotations tripping required-checks branch protection.

Permissions

TestGlance's core functionality (CI summaries, auto-detection) requires no special permissions. Additional features degrade gracefully when permissions are missing — they log a warning and skip, never failing your build.

PermissionFeatureBehavior if Missing
contents: readBaseline (checkout code)Required for all modes
pull-requests: writePR commentsSkipped with warning log, CI stays green
checks: writeCheck Runs + inline annotationsSkipped with warning log, CI stays green

Minimum standalone permissions

permissions:
contents: read

Full feature permissions

permissions:
contents: readpull-requests: writechecks: write

Setting permissions

Add a permissions block at the job level or workflow level:

jobs:
test:
runs-on: ubuntu-latestpermissions:
contents: readpull-requests: writechecks: writesteps:
- uses: testglance/action@v1with:
github-token: ${{ github.token }}annotate-failures: true

Important: When you add a permissions block, GitHub removes all default permissions and grants only what you list. If your job needs other permissions (e.g., contents: read to check out code), you must include them explicitly.

For the full reference, see docs/permissions.md.

Run History, Flaky Tests & Performance Regressions

On by default, with no account and no external service: each run's results are stored in GitHub Actions Cache (last 20 runs, configurable via history-limit). Once history accumulates, the CI summary and PR comment gain:

  • Flaky test detection — a test that flips between pass and fail at least flaky-threshold times (default 2) within the last 10 runs is flagged, with its recent status pattern and flip rate.
  • Performance regressions — a test whose duration exceeds its median across previous runs by more than perf-threshold percent (default 200, i.e. 3× slower) is flagged. Requires at least 3 previous recorded durations for that test.
  • Trends — pass-rate and duration indicators across recent runs, including a duration sparkline. On pull requests these are baselined against the base branch (labeled vs `main`) so you see how the PR moves the needle relative to where it's merging, not just against its own branch history. Override the branch with compare-branch.

History uses Actions Cache under the hood, so it needs no extra permissions and stores nothing outside your repository. Set history: false to turn it off.

HTML Report

Every run also produces a self-contained HTML report and uploads it as a workflow artifact (named testglance-report by default, configurable via artifact-name). Download it from the run's Artifacts section to browse results offline or attach them to a bug report. Set html-report: false to disable.

Supported Formats

JUnit XML (.xml)

Output from most test frameworks:

  • JavaScript/TypeScript: Jest, Vitest, Mocha, Playwright
  • Python: pytest, unittest
  • Go:go test -v with gotestsum
  • Java/Kotlin: JUnit 5, Maven Surefire, Gradle
  • Ruby: RSpec, Minitest
  • C#/.NET: xUnit, NUnit, MSTest

CTRF JSON (.json)

Common Test Report Format — a standardized JSON schema supported by many test frameworks.

Example Output

After each CI run, TestGlance adds a Job Summary:

## TestGlance Results
| Metric | Value |
|-----------|--------|
| Total | 142 |
| Passed | 138 |
| Failed | 3 |
| Skipped | 1 |
| Duration | 12.3s |
### Failed Tests
| Suite | Test | Error |
|--------------|------------------------------|-------------------------------|
| auth.login | should reject expired token | Expected 401 but received 200 |
| api.users | should validate email format | Invalid email was accepted |
### Slowest Tests
| Test | Duration |
|--------------------------------|----------|
| e2e.checkout full flow | 4.2s |
| api.users bulk import | 2.8s |
| auth.login rate limiting | 1.9s |
### Suite Breakdown
| Suite | Passed | Failed | Skipped | Duration |
|-------------|--------|--------|---------|----------|
| auth | 42 | 1 | 0 | 3.1s |
| api | 89 | 2 | 1 | 7.8s |
| utils | 7 | 0 | 0 | 1.4s |

PR Comment

## TestGlance Test Summary
### ci/test (unit tests)
**142 tests** | 12.3s | Health: 94/100
| Signal | Details |
|--------|---------|
| | Health Score: 94 -> 91 |
| | 2 new test(s) added |
View Run ->

Multiple test jobs are merged into a single comment. Subsequent runs update the existing comment.

Org-Wide Adoption

Deploy TestGlance across your organization with a single reusable workflow:

  1. Copy examples/reusable-workflow.yml into your org's shared workflow repo
  2. Each repo calls it with minimal config:
jobs:
report:
uses: your-org/.github/.github/workflows/testglance.yml@mainsecrets:
api-key: ${{ secrets.TESTGLANCE_API_KEY }}

See the examples/ directory for more usage patterns.

Framework Guides

Per-framework install instructions are hosted at https://www.testglance.dev/install/index.md — also served as agent-friendly markdown so any AI coding agent can fetch them directly.

Non-Blocking Guarantee

This Action never fails your CI pipeline. If anything goes wrong — file not found, parse error, API timeout, PR comment failure — the Action logs a warning and exits with code 0. Your builds are safe.

  • No core.setFailed() calls anywhere in the codebase
  • No repository permissions required for core functionality
  • Optional github-token for PR comments and Check Runs only (never affects exit code)
  • Only outbound HTTPS to the TestGlance API and GitHub API

Getting Started

Standalone (No Account Required)

Add a single step to any workflow that produces test reports:

- uses: testglance/action@v1

With TestGlance Platform (coming soon)

The hosted dashboard is in development. Once available, you'll be able to:

  1. Sign up at testglance.dev
  2. Create a project and connect your repository
  3. Copy your project API key
  4. Add it as a repository secret: Settings > Secrets > TESTGLANCE_API_KEY
  5. Add the Action to your workflow (see Quick Start)

Until then, the api-key input is accepted but inactive — all core features (CI summaries, PR comments, annotations) work without it.

Local development

Standard workflow (pnpm):

pnpm install
pnpm test# vitest
pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm build # bundle to dist/index.js (gitignored; CI rebuilds it)

End-to-end smoke test with act

pnpm e2e:act runs the bundled Action (dist/index.js + action.yml) against real report fixtures inside Docker via act, then asserts it parses JUnit/CTRF, handles edge cases (malformed/empty/missing) with a warning, and exits 0. This catches packaging/runtime breakage that unit tests can't, before you push.

pnpm e2e:act

Prerequisites:

  • Docker running (the script skips with exit 0 if the daemon is unavailable).
  • act installed. First run only, seed the runner image: act --pull (subsequent runs use --pull=false).
  • Don't run two act invocations against the same Docker daemon concurrently — act uses host networking and the containers race.

Caveat:act cannot create real GitHub Check Run annotations or PR comments (no live GitHub API). Those are covered by the vitest suite (mocked octokit) and by the authoritative hosted e2e (.github/workflows/e2e.yml). The Check Run code path is still smoke-exercised here — with a dummy token it warns gracefully and exits 0, but no annotation is created.

License

MIT

About

Zero-config test reporting for GitHub Actions. Never breaks your CI.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages