Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 40 additions & 34 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ jobs:
- run:
name: Install deps for code coverage
command: npm ci
- run:
name: Build project
command: npm run build
- run:
name: Install test app deps
command: npm i
working_directory: test-apps/all-files
- cypress/run-tests:
# no-workspace: true
start-command: npm run start:windows --prefix test-apps/all-files
Expand All @@ -68,6 +75,18 @@ jobs:
command: npm i -D check-code-coverage && npm run coverage:check-files
working_directory: test-apps/all-files

build-dist:
docker:
- image: cimg/node:22.14.0
steps:
- attach_workspace:
at: ~/
- run: npm run build
- persist_to_workspace:
paths:
- project/dist
root: ~/

publish:
description: Publishes the new version of the plugin to NPM
docker:
Expand All @@ -85,36 +104,36 @@ jobs:
at: ~/
- run: npm run semantic-release

cyrun:
verify-test-apps:
docker:
- image: cypress/base:22.14.0
parameters:
jobname:
app:
type: string
steps:
- attach_workspace:
at: ~/
- run:
working_directory: test-apps/<< parameters.jobname >>
working_directory: test-apps/<< parameters.app >>
command: npm i
- run:
command: npm run test
working_directory: test-apps/<< parameters.jobname >>
working_directory: test-apps/<< parameters.app >>
- store_artifacts:
path: test-apps/<< parameters.jobname >>/coverage
path: test-apps/<< parameters.app >>/coverage
- run:
name: Verify Code Coverage
command: npm run coverage:verify
working_directory: test-apps/<< parameters.jobname >>
working_directory: test-apps/<< parameters.app >>
- run:
name: Check code coverage files 📈
# we will check the final coverage report
# to make sure it only has files we are interested in
# because there are files covered at 0 in the report
command: npm run coverage:check-files
working_directory: test-apps/<< parameters.jobname >>
working_directory: test-apps/<< parameters.app >>

test-code-coverage-plugin:
unit-test:
docker:
- image: cypress/base:24.11.0
steps:
Expand All @@ -132,23 +151,25 @@ workflows:
- lint:
requires:
- install_and_persist

- test-code-coverage-plugin:
- unit-test:
requires:
- install_and_persist

- cyrun:
name: test-<< matrix.jobname>>
- build-dist:
requires:
- install_and_persist
- lint
- unit-test
- verify-test-apps:
requires:
- build-dist
matrix:
parameters:
jobname:
app:
- all-files
- backend
- batch-send-coverage
- before-all-visit
- before-each-visit
- esm-example
- exclude-files
- frontend
- fullstack
Expand All @@ -160,7 +181,9 @@ workflows:
- unit-tests-js
- use-webpack
- redirect
- windows_test
- windows_test:
requires:
- build-dist
- publish:
context: org-npm-credentials
filters:
Expand All @@ -171,22 +194,5 @@ workflows:
- next
- dev
requires:
- lint
- test-code-coverage-plugin
- test-all-files
- test-backend
- test-batch-send-coverage
- test-before-all-visit
- test-before-each-visit
- test-exclude-files
- test-frontend
- test-fullstack
- test-multiple-backends
- test-one-spec
- test-same-folder
- test-support-files
- test-ts-example
- test-unit-tests-js
- test-use-webpack
- test-redirect
- verify-test-apps
- windows_test
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ Full examples we use for testing in this repository:
- [test-apps/before-each-visit](test-apps/before-each-visit) checks if code coverage correctly keeps track of code when doing `cy.visit` before each test
- [test-apps/one-spec](test-apps/one-spec) confirms that coverage is collected and filtered correctly if the user only executes a single Cypress test
- [test-apps/ts-example](test-apps/ts-example) uses Babel + Parcel to instrument and serve TypeScript file
- [test-apps/esm-example](test-apps/esm-example) demonstrates using ES module syntax (`import`/`export`) with the plugin
- [test-apps/use-webpack](test-apps/use-webpack) shows Webpack build with source maps and Babel
- [test-apps/unit-tests-js](test-apps/unit-tests-js) runs just the unit tests and reports code coverage (JavaScript source code)
- [test-apps/unit-tests-ts](test-apps/ts-example) runs just the unit tests and reports code coverage (TypeScript source code)
Expand Down
53 changes: 36 additions & 17 deletions lib/common-utils.js → lib/common-utils.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
// @ts-check
function stringToArray(prop, obj) {
/// <reference types="node" />

export interface NycOptions {
'report-dir'?: string
reporter?: string | string[]
extension?: string | string[]
exclude?: string | string[]
excludeAfterRemap?: boolean
all?: boolean
include?: string | string[]
[key: string]: unknown
}

function stringToArray(prop: string, obj: Record<string, unknown>): void {
if (typeof obj[prop] === 'string') {
obj[prop] = [obj[prop]]
}

return obj
}

function combineNycOptions(...options) {
export function combineNycOptions(...options: NycOptions[]): NycOptions {
// last option wins
const nycOptions = Object.assign({}, ...options)

Expand All @@ -19,20 +29,32 @@ function combineNycOptions(...options) {
return nycOptions
}

const defaultNycOptions = {
export const defaultNycOptions: NycOptions = {
'report-dir': './coverage',
reporter: ['lcov', 'clover', 'json', 'json-summary'],
extension: ['.js', '.cjs', '.mjs', '.ts', '.tsx', '.jsx'],
excludeAfterRemap: false
}

export interface FileCoveragePlaceholder {
path: string
statementMap: Record<string, unknown>
fnMap: Record<string, unknown>
branchMap: Record<string, unknown>
s: Record<string, unknown>
f: Record<string, unknown>
b: Record<string, unknown>
}

/**
* Returns an object with placeholder properties for files we
* do not have coverage yet. The result can go into the coverage object
*
* @param {string} fullPath Filename
* @param fullPath Filename
*/
const fileCoveragePlaceholder = (fullPath) => {
export function fileCoveragePlaceholder(
fullPath: string
): FileCoveragePlaceholder {
return {
path: fullPath,
statementMap: {},
Expand All @@ -44,7 +66,9 @@ const fileCoveragePlaceholder = (fullPath) => {
}
}

const isPlaceholder = (entry) => {
function isPlaceholder(
entry: FileCoveragePlaceholder | { hash?: string }
): boolean {
// when the file has been instrumented, its entry has "hash" property
return !('hash' in entry)
}
Expand All @@ -53,17 +77,12 @@ const isPlaceholder = (entry) => {
* Given a coverage object with potential placeholder entries
* inserted instead of covered files, removes them. Modifies the object in place
*/
const removePlaceholders = (coverage) => {
export function removePlaceholders(
coverage: Record<string, FileCoveragePlaceholder | { hash?: string }>
): void {
Object.keys(coverage).forEach((key) => {
if (isPlaceholder(coverage[key])) {
delete coverage[key]
}
})
}

module.exports = {
combineNycOptions,
defaultNycOptions,
fileCoveragePlaceholder,
removePlaceholders
}
11 changes: 9 additions & 2 deletions lib/plugins.js → lib/plugins.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
/// <reference types="node" />
/// <reference types="cypress" />
import registerCodeCoverageTasks = require('./task')

// common Cypress plugin file you can point at to have the
// code coverage tasks registered correctly. From your "cypress.json" file
// {
// "pluginsFile": "@cypress/code-coverage/plugins",
// "supportFile": "@cypress/code-coverage/support"
// }
//
module.exports = (on, config) => {
require('./task')(on, config)
export = function plugins(
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
): Cypress.PluginConfigOptions {
registerCodeCoverageTasks(on, config)
// IMPORTANT to return the config object with any changes
return config
}
Loading