-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsupport-utils.js
143 lines (124 loc) · 4.65 KB
/
support-utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/// <reference types="cypress" />
// @ts-check
// helper functions that are safe to use in the browser
// from support.js file - no file system access
const debug = require('debug')('code-coverage')
/**
* remove coverage for the spec files themselves,
* only keep "external" application source file coverage.
* Config has keys with absolute path names for each source file
*/
const filterSpecsFromCoverage = (totalCoverage, config = Cypress.config) => {
/** @type {string|string[]} Cypress run-time config has test files string pattern */
const specPattern = config('specPattern')
const configFilename = config('configFile')
// test files could be:
// wild card string "**/*.*" (default)
// wild card string "**/*spec.js"
// list of wild card strings or names ["**/*spec.js", "spec-one.js"]
const rootFolder = config('projectRoot')
if (typeof rootFolder === 'undefined') {
throw new Error('Cypress projectRoot folder cannot be undefined')
}
const testFilePatterns = (
Array.isArray(specPattern) ? specPattern : [specPattern]
).map((pattern) => {
// we want absolute paths
return rootFolder + '/' + pattern
})
debug({ specPattern, testFilePatterns, configFilename })
const isTestFile = (filename) => {
debug('testing filename', filename)
const matchedPattern = testFilePatterns.some((specPattern) => {
debug('minimatch %s against %s', filename, specPattern)
return Cypress.minimatch(filename, specPattern)
})
const matchedEndOfPath = testFilePatterns.some((specPattern) =>
filename.endsWith(specPattern),
)
const matchedConfig = configFilename.endsWith(filename)
debug({ matchedPattern, matchedEndOfPath, matchedConfig })
return matchedPattern || matchedEndOfPath || matchedConfig
}
const coverage = Cypress._.omitBy(totalCoverage, (fileCoverage, filename) =>
isTestFile(filename),
)
// debug(Object.keys(coverage))
return coverage
}
/**
* Replace source-map's path by the corresponding absolute file path
* (coverage report wouldn't work with source-map path being relative
* or containing Webpack loaders and query parameters)
*/
function fixSourcePaths(coverage) {
Object.values(coverage).forEach((file) => {
const { path: absolutePath, inputSourceMap } = file
// @ts-ignore
const fileName = /([^\/\\]+)$/.exec(absolutePath)[1]
if (!inputSourceMap || !fileName) return
if (inputSourceMap.sourceRoot) inputSourceMap.sourceRoot = ''
inputSourceMap.sources = inputSourceMap.sources.map((source) =>
source.includes(fileName) ? absolutePath : source,
)
})
}
/**
* by default we do not filter anything from the code coverage object
* if the user gives a list of patters to filter, we filter the coverage object.
* @param {boolean|string|string[]} exclude What to exclude (default files or specific list)
* @param {object} coverage Each key is an absolute filepath
*/
function excludeByUser(exclude, coverage) {
if (!exclude) {
return coverage
}
debug('excludeByUser config exclude', exclude)
debug(Object.keys(coverage))
if (exclude === true) {
// try excluding spec and support files
const withoutSpecs = filterSpecsFromCoverage(coverage)
debug('exclude specs', Object.keys(withoutSpecs))
const filteredCoverage = filterSupportFilesFromCoverage(withoutSpecs)
debug('exclude true filtered', Object.keys(filteredCoverage))
return filteredCoverage
}
const filterOut = Cypress._.isString(exclude) ? [exclude] : exclude
// debug({ filterOut })
const filteredCoverage = Cypress._.omitBy(
coverage,
(fileCoverage, filename) => {
return filterOut.some((pattern) => {
if (pattern.includes('*')) {
return Cypress.minimatch(filename, pattern)
}
return filename.endsWith(pattern)
})
},
)
debug('exclude masks filtered', Object.keys(filteredCoverage))
return filteredCoverage
}
/**
* Removes support file from the coverage object.
* If there are more files loaded from support folder, also removes them
*/
const filterSupportFilesFromCoverage = (totalCoverage) => {
const supportFile = Cypress.config('supportFile')
/** @type {string} Cypress run-time config has the support folder string */
const supportFolder = Cypress.config('supportFolder')
const isSupportFile = (filename) => filename === supportFile
const isInSupportFolder = (filename) => filename.startsWith(supportFolder)
const coverage = Cypress._.omitBy(
totalCoverage,
(fileCoverage, filename) =>
isSupportFile(filename) || isInSupportFolder(filename),
)
return coverage
}
module.exports = {
fixSourcePaths,
filterSpecsFromCoverage,
filterSupportFilesFromCoverage,
excludeByUser,
}