@bahmutov/cypress-code-coverage
Advanced tools
Comparing version
{ | ||
"name": "@bahmutov/cypress-code-coverage", | ||
"version": "2.6.1", | ||
"version": "2.7.0", | ||
"description": "My version of Cypress code coverage plugin", | ||
@@ -62,3 +62,3 @@ "main": "index.js", | ||
"dayjs": "1.10.7", | ||
"debug": "4.3.3", | ||
"debug": "4.3.7", | ||
"execa": "4.1.0", | ||
@@ -68,4 +68,4 @@ "globby": "11.1.0", | ||
"js-yaml": "3.14.1", | ||
"nyc": "15.1.0", | ||
"rimraf": "^4.4.1", | ||
"nyc": "17.1.0", | ||
"rimraf": "6.0.1", | ||
"sort-array": "^4.1.5" | ||
@@ -82,3 +82,3 @@ }, | ||
"console-log-div": "0.6.3", | ||
"cypress": "12.8.1", | ||
"cypress": "13.15.2", | ||
"express": "4.17.1", | ||
@@ -85,0 +85,0 @@ "lodash": "4.17.21", |
@@ -1,2 +0,2 @@ | ||
# @bahmutov/cypress-code-coverage  [](https://circleci.com/gh/bahmutov/cypress-code-coverage/tree/main) [](https://github.com/bahmutov/cypress-code-coverage/actions/workflows/ci.yml) | ||
# @bahmutov/cypress-code-coverage  [](https://github.com/bahmutov/cypress-code-coverage/actions/workflows/ci.yml) | ||
@@ -102,2 +102,25 @@ > My version of [Cypress code coverage plugin](https://github.com/cypress-io/code-coverage) | ||
## Instrument on the fly | ||
You can instrument the JavaScript specs the application is loading by using [cy.intercept](https://on.cypress.io/intercept) callbacks. Simply tell this plugin which JS resources to instrument using the `coverage` env object: | ||
```js | ||
// cypress.config.js | ||
export default defineConfig({ | ||
e2e: { | ||
env: { | ||
coverage: { | ||
// intercept and instrument scripts matching these URLs | ||
instrument: '**/calculator/**/*.js', | ||
}, | ||
}, | ||
}, | ||
}) | ||
``` | ||
This plugin will spy on the scripts requested by the application and will instrument all scripts with the URL matching the `**/calculator/**/*.js` pattern. | ||
**Note on caching:** the browser might cache the scripts. You would see 304 status response code. This should be ok, since the browser would cache _the instrumented_ source code returned after the first test run. | ||
### More information | ||
@@ -104,0 +127,0 @@ |
124
support.js
@@ -12,2 +12,12 @@ /// <reference types="cypress" /> | ||
// https://github.com/istanbuljs/istanbuljs | ||
// @ts-ignore | ||
const { createInstrumenter } = require('istanbul-lib-instrument') | ||
const instrumenter = createInstrumenter({ | ||
esModules: true, | ||
compact: false, | ||
preserveComments: true, | ||
}) | ||
dayjs.extend(duration) | ||
@@ -99,2 +109,39 @@ | ||
beforeEach(() => { | ||
const instrumentScripts = Cypress.env('coverage')?.instrument | ||
if (instrumentScripts) { | ||
// the user wants Cypress to instrument the application code | ||
// by intercepting the script requests and instrumenting them on the fly | ||
const baseUrl = Cypress.config('baseUrl') | ||
// @ts-ignore | ||
const proxyServer = Cypress.config('proxyServer') + '/' | ||
cy.intercept( | ||
{ | ||
method: 'GET', | ||
resourceType: 'script', | ||
url: instrumentScripts, | ||
}, | ||
(req) => { | ||
// TODO: remove caching headers for now | ||
// @ts-ignore | ||
req.continue((res) => { | ||
const relativeUrl = req.url | ||
// @ts-ignore | ||
.replace(baseUrl, '') | ||
.replace(proxyServer, '') | ||
// console.log('instrumenting', relativeUrl) | ||
// @ts-ignore | ||
const instrumented = instrumenter.instrumentSync( | ||
res.body, | ||
relativeUrl, | ||
) | ||
res.body = instrumented | ||
return res | ||
}) | ||
}, | ||
) | ||
} | ||
// each object will have the coverage and url pathname | ||
@@ -158,6 +205,6 @@ // to let the user know the coverage has been collected | ||
const config = getCoverageConfig() | ||
const taskLogOptions = { | ||
log: !config.quiet, | ||
if (!config.quiet) { | ||
cy.log(`**Reporting coverage for** ${Cypress.spec.relative}`) | ||
} | ||
cy.task('reportSpecCovers', taskOptions, taskLogOptions) | ||
cy.task('reportSpecCovers', taskOptions, { log: false }) | ||
@@ -209,38 +256,43 @@ if (!hasE2ECoverage()) { | ||
if (runningEndToEndTests && isIntegrationSpec) { | ||
// we can only request server-side code coverage | ||
// if we are running end-to-end tests, | ||
// otherwise where do we send the request? | ||
const url = Cypress._.get( | ||
Cypress.env('codeCoverage'), | ||
'url', | ||
'/__coverage__', | ||
) | ||
cy.request({ | ||
url, | ||
log: false, | ||
failOnStatusCode: false, | ||
}) | ||
.then((r) => { | ||
return Cypress._.get(r, 'body.coverage', null) | ||
const baseUrl = Cypress.config('baseUrl') | ||
if (baseUrl) { | ||
// can only fetch server-side code coverage if we have a baseUrl | ||
// we can only request server-side code coverage | ||
// if we are running end-to-end tests, | ||
// otherwise where do we send the request? | ||
const url = Cypress._.get( | ||
Cypress.env('codeCoverage'), | ||
'url', | ||
'/__coverage__', | ||
) | ||
cy.request({ | ||
url, | ||
log: false, | ||
failOnStatusCode: false, | ||
}) | ||
.then((coverage) => { | ||
if (!coverage) { | ||
// we did not get code coverage - this is the | ||
// original failed request | ||
const expectBackendCoverageOnly = Cypress._.get( | ||
Cypress.env('codeCoverage'), | ||
'expectBackendCoverageOnly', | ||
false, | ||
) | ||
if (expectBackendCoverageOnly) { | ||
throw new Error( | ||
`Expected to collect backend code coverage from ${url}`, | ||
.then((r) => { | ||
return Cypress._.get(r, 'body.coverage', null) | ||
}) | ||
.then((coverage) => { | ||
if (!coverage) { | ||
// we did not get code coverage - this is the | ||
// original failed request | ||
const expectBackendCoverageOnly = Cypress._.get( | ||
Cypress.env('codeCoverage'), | ||
'expectBackendCoverageOnly', | ||
false, | ||
) | ||
} else { | ||
// we did not really expect to collect the backend code coverage | ||
return | ||
if (expectBackendCoverageOnly) { | ||
throw new Error( | ||
`Expected to collect backend code coverage from ${url}`, | ||
) | ||
} else { | ||
// we did not really expect to collect the backend code coverage | ||
return | ||
} | ||
} | ||
} | ||
sendCoverage(coverage, 'backend') | ||
}) | ||
sendCoverage(coverage, 'backend') | ||
}) | ||
} | ||
} | ||
@@ -247,0 +299,0 @@ }) |
82461
2.84%1464
3.17%716
3.32%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated