A Chrome extension and Coverage Bridge Server for measuring code coverage during manual testing of web applications.
- Backend Coverage (JaCoCo): Measure Java/Spring backend code coverage via JaCoCo agent
- Frontend Coverage (V8/CDP): Measure JavaScript frontend code coverage via Chrome DevTools Protocol
- Real-time Control: Start/Stop coverage measurement through Chrome extension popup
- Report Generation: Generate HTML, JSON, XML reports for both backend and frontend
- One-Click Report Viewing: Click report links to open HTML reports directly in browser
┌─────────────────────────────────────────────────────────────┐
│ Chrome Extension │
│ ┌─────────┐ ┌─────────────────────────────────────────┐ │
│ │ Popup │ │ Background Service Worker │ │
│ │ (UI) │──│ - CDP control (chrome.debugger API) │ │
│ └─────────┘ │ - HTTP API calls to Coverage Bridge │ │
│ └─────────────────────────────────────────┘ │
└───────────────────────────┬─────────────────────────────────┘
│ HTTP API
▼
┌─────────────────────────────────────────────────────────────┐
│ Coverage Bridge Server (localhost:9528) │
│ - JaCoCo CLI execution (dump, report) │
│ - V8 coverage report generation (monocart-coverage-reports)│
└─────────────────────────────────────────────────────────────┘
- Node.js: v18.0.0 or higher
- Java: JRE/JDK 8 or higher (for JaCoCo CLI)
- Chrome Browser: Latest version recommended
cd server
npm install
npm startThe server will start at http://localhost:9528
- Open Chrome and navigate to
chrome://extensions/ - Enable "Developer mode" (toggle in top right)
- Click "Load unpacked"
- Select the
extensionfolder from this project
- Click the extension icon in Chrome toolbar to open the popup
- Go to Server tab and click Load Server Defaults to auto-fill paths
- Navigate to your web application
- Click Start Coverage (page will reload automatically)
- Perform manual testing
- Click Stop & Report
- Click the report links to view coverage in browser
The main control panel for starting and stopping coverage measurement.
Initial State:
- Backend (JaCoCo): Toggle to enable/disable backend coverage
- Frontend (V8/CDP): Toggle to enable/disable frontend coverage
- Start Coverage: Begin collecting coverage data
- Stop & Report: Stop collection and generate HTML reports
After Stop & Report:
- Backend HTML Report: Click to open JaCoCo HTML report in new tab
- Backend XML Report: Click to copy XML file path
- Frontend V8 Report: Click to open V8 HTML report in new tab (green background indicates clickable)
- Frontend Output Dir: Click to copy output directory path
Configure JaCoCo settings for Java/Spring backend coverage:
| Setting | Description | Example |
|---|---|---|
| Address | JaCoCo agent host | localhost |
| Port | JaCoCo agent port | 6300 |
| CLI Path | Path to jacococli.jar | /path/to/jacococli.jar |
| Class Files Path | Compiled classes location | /project/target/classes |
| Source Files Path | Java source files (for HTML report) | /project/src/main/java |
| Output Directory | Where to save reports | /path/to/coverage-output |
Configure V8 settings for JavaScript frontend coverage:
| Setting | Description | Example |
|---|---|---|
| Output Directory | Where to save reports | /path/to/coverage-output |
| Report Name | Name for the report | Manual Test Coverage |
| Report Types | Which reports to generate | v8, html, json, lcov |
| Entry Filter | Filter for entry files (JSON) | {"**/node_modules/**": false} |
| Source Filter | Filter for source files (JSON) | {"**/src/**": true} |
Configure the Coverage Bridge Server connection:
| Setting | Description | Default |
|---|---|---|
| Server URL | Coverage Bridge Server address | http://localhost:9528 |
Buttons:
- Test Connection: Verify the server is running
- Load Server Defaults: Auto-fill output directories with server's default paths
Important: Click "Load Server Defaults" to automatically configure output directories. Reports will be saved on the machine where the Coverage Bridge Server is running, not on remote backend/frontend servers.
After clicking Stop & Report, HTML reports are generated and saved on the Coverage Bridge Server machine.
New Feature: Report links with a green background and ↗ icon can be clicked to open the report directly in a new browser tab:
- Backend HTML Report → Opens JaCoCo HTML report
- Frontend V8 Report → Opens V8 HTML report
The Coverage Bridge Server automatically serves these reports via HTTP, so you don't need to manually start a file server.
When using server defaults, reports are saved in the server/reports/ directory:
server/reports/
├── backend/ # JaCoCo HTML reports
│ └── html/
│ └── index.html
└── frontend/ # V8 HTML reports
└── index.html
You can also access reports via HTTP:
- Backend:
http://localhost:9528/reports/backend/html/index.html - Frontend:
http://localhost:9528/reports/frontend/index.html
If you specify custom paths in Backend/Frontend settings, reports will be saved to those locations. The extension will still provide clickable links that open via the server's dynamic file serving endpoint.
Frontend V8 Coverage Report (monocart-coverage-reports):
Backend JaCoCo Coverage Report:
In real-world scenarios, your backend and frontend may be running on different machines or remote servers. The Coverage Bridge Server collects coverage data from these sources and generates reports locally, ensuring you always have access to the reports regardless of where your applications are deployed.
Your Spring/Java application must be running with JaCoCo agent in tcpserver output mode.
This is the most reliable method:
# 1. Build the JAR (skip tests for faster build)
./mvnw package -DskipTests
# 2. Run with JaCoCo agent
java -javaagent:/path/to/jacocoagent.jar=output=tcpserver,port=6300 \
-jar target/your-app.jarWhen using ./mvnw spring-boot:run, the JaCoCo agent may not be properly attached because Spring Boot Maven Plugin forks a separate JVM. The following methods DO NOT WORK reliably:
# ❌ Does NOT work - MAVEN_OPTS is not passed to forked process
MAVEN_OPTS="-javaagent:jacocoagent.jar=..." ./mvnw spring-boot:run
# ❌ Does NOT work - jvmArguments may not be applied
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="..."If you must use spring-boot:run, configure it in pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>
-javaagent:${project.basedir}/jacocoagent.jar=output=tcpserver,port=6300
</jvmArguments>
</configuration>
</plugin>Check if the TCP server is listening:
lsof -i :6300
# Should show a java process listening on port 6300Here's a complete example using the Spring PetClinic application:
cd spring-petclinic
./mvnw package -DskipTests
java -javaagent:jacocoagent.jar=output=tcpserver,port=6300 \
-jar target/spring-petclinic-*.jarcd frontend-petclinic
npm install
npm run devcd coverage-measurement-tool/server
npm startBackend Tab:
| Setting | Value |
|---|---|
| Address | localhost |
| Port | 6300 |
| CLI Path | /path/to/server/jacococli.jar |
| Class Files | /path/to/spring-petclinic/target/classes |
| Source Files | /path/to/spring-petclinic/src/main/java |
| Output Directory | /path/to/spring-petclinic/coverage-output |
Frontend Tab:
| Setting | Value |
|---|---|
| Output Directory | /path/to/frontend-petclinic/coverage-output |
| Report Name | Frontend Manual Test Coverage |
Server Tab:
| Setting | Value |
|---|---|
| Server URL | http://localhost:9528 |
- Navigate to
http://localhost:5173/in Chrome - Click Start Coverage in the extension (page will reload automatically)
- Perform manual testing (click buttons, navigate pages, etc.)
- Click Stop & Report
- View reports by clicking the links in "Reports Generated" section:
- Backend HTML Report → Opens JaCoCo report in new tab
- Frontend V8 Report → Opens V8 report in new tab
The Coverage Bridge Server provides the following endpoints:
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Server health check |
| GET | /config |
Get server default configuration |
| GET | /reports/* |
Static file serving for default reports directory |
| GET | /serve-report/* |
Dynamic file serving for any report path |
| POST | /get-report-url |
Get HTTP URL for a local report path |
| Method | Endpoint | Description |
|---|---|---|
| POST | /jacoco/reset |
Reset JaCoCo coverage buffer |
| POST | /jacoco/dump |
Dump coverage data to exec file |
| POST | /jacoco/report |
Generate JaCoCo report |
| POST | /jacoco/dump-and-report |
Dump and generate report in one step (returns reportUrl) |
| Method | Endpoint | Description |
|---|---|---|
| POST | /v8/report |
Generate V8 coverage report from coverage data |
| POST | /v8/save-raw |
Save raw coverage data to file |
| POST | /v8/save-and-report |
Save and generate report in one step (returns reportUrl) |
| POST | /v8/generate-from-file |
Generate report from saved raw file |
| POST | /v8/merge |
Merge multiple coverage reports |
You can use Playwright to automate coverage collection during E2E tests:
// Start JS coverage before navigation
await page.coverage.startJSCoverage();
// Navigate and perform actions
await page.goto('http://localhost:5173/');
await page.getByRole('button', { name: 'Search' }).click();
// ... more actions
// Stop and collect coverage
const coverage = await page.coverage.stopJSCoverage();
// Filter source files only
const srcCoverage = coverage.filter(e => e.url.includes('/src/'));
// Send to Coverage Bridge Server for report generation
await fetch('http://localhost:9528/v8/save-and-report', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
coverageData: srcCoverage,
outputDir: '/path/to/coverage-output',
name: 'E2E Test Coverage',
reports: ['v8', 'html', 'console-summary']
})
});This project includes an automated E2E test that demonstrates the full coverage measurement workflow using Playwright.
Before running the test, start all required servers:
# Terminal 1: Start Coverage Bridge Server
cd server && npm start
# Terminal 2: Build and start Backend with JaCoCo
cd spring-petclinic
./mvnw package -DskipTests -Dcheckstyle.skip=true
java -javaagent:jacocoagent.jar=output=tcpserver,port=6300 -jar target/spring-petclinic-*.jar
# Terminal 3: Start Frontend
cd frontend-petclinic && npm run dev# Install dependencies (first time only)
cd e2e-test
npm install
npx playwright install chromium
# Run the test
npm test- Checks that all servers are running
- Resets JaCoCo coverage buffer
- Launches a browser and starts V8 coverage collection
- Performs various UI actions:
- Loads the Vets table
- Searches for owners
- Creates a new owner
- Opens owner details
- Creates a new pet
- Creates a new visit
- Stops coverage collection
- Generates both backend (JaCoCo) and frontend (V8) HTML reports
After successful execution, you can view the coverage reports:
Via HTTP (recommended):
- Backend Report:
http://localhost:9528/reports/backend/html/index.html - Frontend Report:
http://localhost:9528/reports/frontend/index.html
Local File Paths:
- Backend Report:
server/reports/backend/html/index.html - Frontend Report:
server/reports/frontend/index.html
- Ensure the server is running:
cd server && npm start - Check the server URL in extension settings (default:
http://localhost:9528) - Test connection using the "Test Connection" button in Server tab
- Verify your Java application is running with JaCoCo agent
- Check the agent is configured with
output=tcpserver - Verify the address and port match your JaCoCo agent configuration
- Ensure no firewall is blocking the connection
This usually means the JaCoCo agent was not properly attached:
-
Verify agent attachment:
ps aux | grep java | grep jacocoagent
-
Check port binding:
lsof -i :6300
-
Use JAR execution instead of Maven spring-boot:run:
./mvnw package -DskipTests java -javaagent:jacocoagent.jar=output=tcpserver,port=6300 -jar target/*.jar
The Chrome extension uses Chrome's built-in Debugger API (CDP) to collect V8 coverage. This has some limitations:
Problem: Only one debugger can be attached to a tab at a time. If DevTools (F12) is open, the extension cannot attach.
Solution:
- Close DevTools before clicking "Start Coverage"
- Press F12 to close DevTools, then try again
Error message: "DevTools is open on this tab. Please close DevTools (F12) and try again."
Problem: Coverage cannot be collected on Chrome internal pages.
Solution:
- Navigate to your web application (http:// or https://)
- Coverage does NOT work on:
chrome://,chrome-extension://,about:blank
How it works: When you click "Start Coverage", the extension automatically reloads the page. This is necessary because V8 coverage only tracks JavaScript executed after profiling starts.
What to expect:
- Click "Start Coverage"
- Page automatically reloads (this is normal!)
- Perform your test actions
- Click "Stop & Report"
If coverage is still empty: Check the Service Worker console (chrome://extensions/ → "Service worker") for debugging logs showing which URLs were captured.
The extension filters coverage to only include source files (URLs containing /src/). If your source files are in a different path:
- Check the console logs in Service Worker for "All coverage URLs"
- The extension will try a relaxed filter if no
/src/files are found
- Verify the source/class file paths are correct
- Check the entry/source filters aren't too restrictive
- Ensure you actually executed code during the test session
Problem: Opening the frontend HTML report directly via file:// protocol shows an empty report, but coverage-raw.json has data.
Cause: Modern coverage report libraries (like monocart-coverage-reports) load data dynamically via JavaScript. Browsers block these requests due to CORS when using file:// protocol.
Solution: Always access reports via HTTP:
- Click the report link in the extension (recommended) - opens report via Coverage Bridge Server
- Manual HTTP access:
http://localhost:9528/reports/frontend/index.html - Custom paths: Use
http://localhost:9528/serve-report/{encoded-path}endpoint
coverage-tool/
├── extension/ # Chrome Extension
│ ├── manifest.json # Extension manifest (V3)
│ ├── background.js # Service worker
│ ├── popup/ # Popup UI
│ │ ├── popup.html
│ │ ├── popup.css
│ │ └── popup.js
│ └── icons/ # Extension icons
├── server/ # Coverage Bridge Server
│ ├── package.json
│ ├── server.js # Express server
│ ├── jacococli.jar # JaCoCo CLI (included)
│ ├── routes/
│ │ ├── jacoco.js # JaCoCo endpoints
│ │ └── coverage.js # V8 coverage endpoints
│ └── lib/
│ ├── jacoco-executor.js # JaCoCo CLI wrapper
│ └── mcr-reporter.js # MCR wrapper
├── e2e-test/ # Automated E2E Test
│ ├── package.json
│ └── coverage-test.js # Playwright-based test
├── spring-petclinic/ # Example: Spring Backend
├── frontend-petclinic/ # Example: React Frontend
├── docs/
│ └── images/ # Documentation images
└── README.md
# Server with auto-reload
cd server
npm run devFor extension changes, reload the extension in chrome://extensions/
- JaCoCo Documentation
- JaCoCo CLI
- JaCoCo Agent
- Monocart Coverage Reports
- Chrome Debugger API
- V8 Coverage
MIT






