From 774e7d0368a1905e38f39b40134596bd9e8837eb Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 20 Apr 2020 08:54:48 -0400 Subject: [PATCH 1/5] fix: split utils for task from utils for support file --- cypress/integration/filtering.js | 2 +- cypress/integration/spec.js | 4 +- support-utils.js | 48 ++++++++++++++++++ support.js | 2 +- utils.js => task-utils.js | 85 +++++++++----------------------- task.js | 4 +- 6 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 support-utils.js rename utils.js => task-utils.js (80%) diff --git a/cypress/integration/filtering.js b/cypress/integration/filtering.js index 212c8618..76cd3de4 100644 --- a/cypress/integration/filtering.js +++ b/cypress/integration/filtering.js @@ -1,4 +1,4 @@ -const { filterSpecsFromCoverage } = require('../../utils') +const { filterSpecsFromCoverage } = require('../../support-utils') describe('minimatch', () => { it('string matches', () => { diff --git a/cypress/integration/spec.js b/cypress/integration/spec.js index f92f090c..f3c173c3 100644 --- a/cypress/integration/spec.js +++ b/cypress/integration/spec.js @@ -3,7 +3,7 @@ /// import { add } from '../unit' -const { fixSourcePathes } = require('../../utils') +const { fixSourcePaths } = require('../../task-utils') context('Page test', () => { beforeEach(() => { @@ -54,7 +54,7 @@ context('Unit tests', () => { } } - fixSourcePathes(coverage) + fixSourcePaths(coverage) expect(coverage).to.deep.eq({ '/absolute/src/component.vue': { diff --git a/support-utils.js b/support-utils.js new file mode 100644 index 00000000..a984d3fd --- /dev/null +++ b/support-utils.js @@ -0,0 +1,48 @@ +// helper functions that are safe to use in the browser +// from support.js file - no file system access + +/** + * remove coverage for the spec files themselves, + * only keep "external" application source file coverage + */ +const filterSpecsFromCoverage = (totalCoverage, config = Cypress.config) => { + const integrationFolder = config('integrationFolder') + // @ts-ignore + const testFilePattern = config('testFiles') + + // test files chould be: + // wild card string "**/*.*" (default) + // wild card string "**/*spec.js" + // list of wild card strings or names ["**/*spec.js", "spec-one.js"] + const testFilePatterns = Array.isArray(testFilePattern) + ? testFilePattern + : [testFilePattern] + + const isUsingDefaultTestPattern = testFilePattern === '**/*.*' + + const isTestFile = filename => { + const matchedPattern = testFilePatterns.some(specPattern => + Cypress.minimatch(filename, specPattern) + ) + const matchedEndOfPath = testFilePatterns.some(specPattern => + filename.endsWith(specPattern) + ) + return matchedPattern || matchedEndOfPath + } + + const isInIntegrationFolder = filename => + filename.startsWith(integrationFolder) + + const isA = (fileCoverge, filename) => isInIntegrationFolder(filename) + const isB = (fileCoverge, filename) => isTestFile(filename) + + const isTestFileFilter = isUsingDefaultTestPattern ? isA : isB + + const coverage = Cypress._.omitBy(totalCoverage, isTestFileFilter) + return coverage +} + +module.exports = { + fixSourcePaths, + filterSpecsFromCoverage +} diff --git a/support.js b/support.js index b061b6d4..807d338f 100644 --- a/support.js +++ b/support.js @@ -1,7 +1,7 @@ /// // @ts-check -const { filterSpecsFromCoverage } = require('./utils') +const { filterSpecsFromCoverage } = require('./support-utils') /** * Sends collected code coverage object to the backend code diff --git a/utils.js b/task-utils.js similarity index 80% rename from utils.js rename to task-utils.js index be17e815..6c69b53f 100644 --- a/utils.js +++ b/task-utils.js @@ -1,3 +1,6 @@ +// helper functions to use from "task.js" plugins code +// that need access to the file system + // @ts-check /// const { readFileSync, writeFileSync, existsSync } = require('fs') @@ -26,65 +29,6 @@ function checkAllPathsNotFound(nycFilename) { return allFilesAreMissing } -/** - * remove coverage for the spec files themselves, - * only keep "external" application source file coverage - */ -const filterSpecsFromCoverage = (totalCoverage, config = Cypress.config) => { - const integrationFolder = config('integrationFolder') - // @ts-ignore - const testFilePattern = config('testFiles') - - // test files chould be: - // wild card string "**/*.*" (default) - // wild card string "**/*spec.js" - // list of wild card strings or names ["**/*spec.js", "spec-one.js"] - const testFilePatterns = Array.isArray(testFilePattern) - ? testFilePattern - : [testFilePattern] - - const isUsingDefaultTestPattern = testFilePattern === '**/*.*' - - const isTestFile = filename => { - const matchedPattern = testFilePatterns.some(specPattern => - Cypress.minimatch(filename, specPattern) - ) - const matchedEndOfPath = testFilePatterns.some(specPattern => - filename.endsWith(specPattern) - ) - return matchedPattern || matchedEndOfPath - } - - const isInIntegrationFolder = filename => - filename.startsWith(integrationFolder) - - const isA = (fileCoverge, filename) => isInIntegrationFolder(filename) - const isB = (fileCoverge, filename) => isTestFile(filename) - - const isTestFileFilter = isUsingDefaultTestPattern ? isA : isB - - const coverage = Cypress._.omitBy(totalCoverage, isTestFileFilter) - 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 fixSourcePathes(coverage) { - Object.values(coverage).forEach(file => { - const { path: absolutePath, inputSourceMap } = file - 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 - ) - }) -} - /** * A small debug utility to inspect paths saved in NYC output JSON file */ @@ -250,11 +194,28 @@ function tryFindingLocalFiles(nycFilename) { } } +/** + * 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 + 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 + ) + }) +} + module.exports = { - fixSourcePathes, - filterSpecsFromCoverage, showNycInfo, resolveRelativePaths, checkAllPathsNotFound, - tryFindingLocalFiles + tryFindingLocalFiles, + fixSourcePaths } diff --git a/task.js b/task.js index 8d9135ff..6638ef1c 100644 --- a/task.js +++ b/task.js @@ -4,12 +4,12 @@ const { join, resolve } = require('path') const { existsSync, mkdirSync, readFileSync, writeFileSync } = require('fs') const execa = require('execa') const { - fixSourcePathes, + fixSourcePaths, showNycInfo, resolveRelativePaths, checkAllPathsNotFound, tryFindingLocalFiles -} = require('./utils') +} = require('./task-utils') const NYC = require('nyc') const debug = require('debug')('code-coverage') From e0c876f9e77cd7248962639258d040db79c4ba3f Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 20 Apr 2020 08:56:17 -0400 Subject: [PATCH 2/5] fix typo --- task.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task.js b/task.js index 6638ef1c..277b931b 100644 --- a/task.js +++ b/task.js @@ -79,7 +79,7 @@ const tasks = { const coverage = JSON.parse(sentCoverage) debug('parsed sent coverage') - fixSourcePathes(coverage) + fixSourcePaths(coverage) const previous = existsSync(nycFilename) ? JSON.parse(readFileSync(nycFilename, 'utf8')) : istanbul.createCoverageMap({}) From 5fc077b6ef87396a66a93a7561ce1beb582eeff4 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 20 Apr 2020 09:04:27 -0400 Subject: [PATCH 3/5] add TypeScript type check --- .circleci/config.yml | 12 ++++++++++-- package.json | 3 ++- support.js | 10 +++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e5e67f83..a7e548e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,8 +17,16 @@ jobs: - checkout - node/with-cache: steps: - - run: CYPRESS_INSTALL_BINARY=0 npm ci - - run: npm run format:check + - run: + name: Install dependencies 📦 + # installs NPM dependencies but skips Cypress + command: CYPRESS_INSTALL_BINARY=0 npm ci + - run: + name: Code style check 🧹 + command: npm run format:check + - run: + name: Types lint 🧹 + command: npm run types publish: description: Publishes the new version of the plugin to NPM diff --git a/package.json b/package.json index 46973366..0e9c0dae 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "format": "prettier --write '*.js'", "format:check": "prettier --check '*.js'", "check:markdown": "find *.md -exec npx markdown-link-check {} \\;", - "effective:config": "circleci config process .circleci/config.yml | sed /^#/d" + "effective:config": "circleci config process .circleci/config.yml | sed /^#/d", + "types": "tsc --noEmit --allowJs *.js cypress/integration/*.js" }, "peerDependencies": { "cypress": "*" diff --git a/support.js b/support.js index 807d338f..0886db04 100644 --- a/support.js +++ b/support.js @@ -35,6 +35,7 @@ const logMessage = s => { const filterSupportFilesFromCoverage = totalCoverage => { const integrationFolder = Cypress.config('integrationFolder') const supportFile = Cypress.config('supportFile') + // @ts-ignore const supportFolder = Cypress.config('supportFolder') const isSupportFile = filename => filename === supportFile @@ -61,12 +62,14 @@ const registerHooks = () => { const hasE2ECoverage = () => Boolean(windowCoverageObjects.length) + // @ts-ignore const hasUnitTestCoverage = () => Boolean(window.__coverage__) before(() => { // we need to reset the coverage when running // in the interactive mode, otherwise the counters will // keep increasing every time we rerun the tests + // @ts-ignore cy.task('resetCoverage', { isInteractive: Cypress.config('isInteractive') }) }) @@ -133,7 +136,9 @@ const registerHooks = () => { // there might be server-side code coverage information // we should grab it once after all tests finish + // @ts-ignore const baseUrl = Cypress.config('baseUrl') || cy.state('window').origin + // @ts-ignore const runningEndToEndTests = baseUrl !== Cypress.config('proxyUrl') const specType = Cypress._.get(Cypress.spec, 'specType', 'integration') const isIntegrationSpec = specType === 'integration' @@ -152,7 +157,9 @@ const registerHooks = () => { log: false, failOnStatusCode: false }) - .then(r => Cypress._.get(r, 'body.coverage', null), { log: false }) + .then(r => { + return Cypress._.get(r, 'body.coverage', null), { log: false } + }) .then(coverage => { if (!coverage) { // we did not get code coverage - this is the @@ -171,6 +178,7 @@ const registerHooks = () => { // then we will have unit test coverage // NOTE: spec iframe is NOT reset between the tests, so we can grab // the coverage information only once after all tests have finished + // @ts-ignore const unitTestCoverage = window.__coverage__ if (unitTestCoverage) { sendCoverage(unitTestCoverage, 'unit') From 6f064cbcffa58b240f9e3db61d926a3d69572801 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 20 Apr 2020 09:14:53 -0400 Subject: [PATCH 4/5] move function --- cypress/integration/spec.js | 2 +- support-utils.js | 19 +++++++++++++++++++ task-utils.js | 21 +-------------------- task.js | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cypress/integration/spec.js b/cypress/integration/spec.js index f3c173c3..ba1b59d7 100644 --- a/cypress/integration/spec.js +++ b/cypress/integration/spec.js @@ -3,7 +3,7 @@ /// import { add } from '../unit' -const { fixSourcePaths } = require('../../task-utils') +const { fixSourcePaths } = require('../../support-utils') context('Page test', () => { beforeEach(() => { diff --git a/support-utils.js b/support-utils.js index a984d3fd..0a222242 100644 --- a/support-utils.js +++ b/support-utils.js @@ -1,3 +1,4 @@ +// @ts-check // helper functions that are safe to use in the browser // from support.js file - no file system access @@ -42,6 +43,24 @@ const filterSpecsFromCoverage = (totalCoverage, config = Cypress.config) => { 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 + 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 + ) + }) +} + module.exports = { fixSourcePaths, filterSpecsFromCoverage diff --git a/task-utils.js b/task-utils.js index 6c69b53f..1030fceb 100644 --- a/task-utils.js +++ b/task-utils.js @@ -194,28 +194,9 @@ function tryFindingLocalFiles(nycFilename) { } } -/** - * 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 - 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 - ) - }) -} - module.exports = { showNycInfo, resolveRelativePaths, checkAllPathsNotFound, - tryFindingLocalFiles, - fixSourcePaths + tryFindingLocalFiles } diff --git a/task.js b/task.js index 277b931b..898cb28a 100644 --- a/task.js +++ b/task.js @@ -4,12 +4,12 @@ const { join, resolve } = require('path') const { existsSync, mkdirSync, readFileSync, writeFileSync } = require('fs') const execa = require('execa') const { - fixSourcePaths, showNycInfo, resolveRelativePaths, checkAllPathsNotFound, tryFindingLocalFiles } = require('./task-utils') +const { fixSourcePaths } = require('./support-utils') const NYC = require('nyc') const debug = require('debug')('code-coverage') From 8176849af9535d1e18d39569023b9448b7a73366 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Mon, 20 Apr 2020 09:32:26 -0400 Subject: [PATCH 5/5] fix options --- support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support.js b/support.js index 0886db04..d17a3483 100644 --- a/support.js +++ b/support.js @@ -158,7 +158,7 @@ const registerHooks = () => { failOnStatusCode: false }) .then(r => { - return Cypress._.get(r, 'body.coverage', null), { log: false } + return Cypress._.get(r, 'body.coverage', null) }) .then(coverage => { if (!coverage) {