Server middleware components enable collection of backend code coverage from instrumented applications running alongside Cypress tests. These middleware functions expose coverage endpoints that the Cypress plugin can query to gather server-side coverage data.
Middleware for Express.js applications that exposes a coverage endpoint.
/**
* Express.js middleware that adds /__coverage__ endpoint
* @param app - Express application instance
*/
function expressMiddleware(app: Express): void;Usage:
const express = require('express')
const app = express()
// Add coverage endpoint
require('@cypress/code-coverage/middleware/express')(app)
// Endpoint available at: GET /__coverage__
// Returns: { coverage: global.__coverage__ || null }The middleware:
/__coverage__Middleware for Hapi.js applications that adds coverage route configuration.
/**
* Hapi.js middleware that registers /__coverage__ route
* @param server - Hapi server instance
*/
function hapiMiddleware(server: Hapi.Server): void;Usage:
const Hapi = require('@hapi/hapi')
const server = Hapi.server({ port: 3000 })
// Add coverage route
require('@cypress/code-coverage/middleware/hapi')(server)
// Route available at: GET /__coverage__
// Returns: { coverage: global.__coverage__ }Route configuration:
/__coverage__API route handler for Next.js applications using the API routes feature.
/**
* Next.js API route handler for coverage endpoint
* @param req - Next.js API request object
* @param res - Next.js API response object
*/
function nextjsHandler(req: NextApiRequest, res: NextApiResponse): void;Usage:
// Create file: pages/api/coverage.js
module.exports = require('@cypress/code-coverage/middleware/nextjs')
// Configure Cypress to use the endpoint:
// cypress.config.js
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
env: {
codeCoverage: {
url: '/api/coverage'
}
}
}
})Handler behavior:
{ coverage: global.__coverage__ || null }All middleware implementations follow a consistent protocol for coverage data exchange:
// HTTP Request
GET /__coverage__
Accept: application/json// HTTP Response
{
"coverage": Coverage | null
}
interface Coverage {
[filepath: string]: {
path: string;
statementMap: object;
fnMap: object;
branchMap: object;
s: { [key: string]: number };
f: { [key: string]: number };
b: { [key: string]: number[] };
hash?: string;
}
}// Cypress configuration for multiple backends
module.exports = defineConfig({
e2e: {
env: {
codeCoverage: {
url: [
'http://api-service:3001/__coverage__',
'http://auth-service:3002/__coverage__',
'http://payment-service:3003/__coverage__'
]
}
}
}
})# docker-compose.yml
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=test
# Ensure babel-plugin-istanbul is active
cypress:
image: cypress/included
depends_on:
- web
environment:
- CYPRESS_baseUrl=http://web:3000
volumes:
- ./cypress:/cypressFor middleware to return coverage data, the application must be instrumented:
// .babelrc
{
"presets": ["@babel/preset-env"],
"plugins": ["istanbul"]
}// .babelrc
{
"presets": ["@babel/preset-env"],
"env": {
"test": {
"plugins": ["istanbul"]
}
}
}// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: process.env.NODE_ENV === 'test' ? ['istanbul'] : []
}
}
}
]
}
}Production Safety:
Network Security:
Example Protection:
// Only add coverage middleware in test environment
if (process.env.NODE_ENV === 'test') {
require('@cypress/code-coverage/middleware/express')(app)
}