You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP →
Socket
Sign inDemoInstall
Socket

@bahmutov/cypress-code-coverage

Package Overview
Dependencies
Maintainers
0
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bahmutov/cypress-code-coverage - npm Package Compare versions

Comparing version

to
2.7.0

10

package.json
{
"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 ![cypress version](https://img.shields.io/badge/cypress-12.8.1-brightgreen) [![CircleCI](https://circleci.com/gh/bahmutov/cypress-code-coverage/tree/main.svg?style=svg)](https://circleci.com/gh/bahmutov/cypress-code-coverage/tree/main) [![ci](https://github.com/bahmutov/cypress-code-coverage/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bahmutov/cypress-code-coverage/actions/workflows/ci.yml)
# @bahmutov/cypress-code-coverage ![cypress version](https://img.shields.io/badge/cypress-13.15.2-brightgreen) [![ci](https://github.com/bahmutov/cypress-code-coverage/actions/workflows/ci.yml/badge.svg?branch=main)](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 @@

@@ -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 @@ })