diff --git a/.circleci/config.yml b/.circleci/config.yml index d4182b2e..c2a1fa2a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -209,7 +209,6 @@ workflows: - run: command: npx nyc report --check-coverage true --lines 100 working_directory: examples/same-folder - # how to fail if the specific file coverage is not found?! - run: command: npx nyc report --check-coverage true --lines 100 --include unit-utils.js working_directory: examples/same-folder @@ -221,6 +220,37 @@ workflows: node ../../scripts/only-covered main.js unit-utils.js working_directory: examples/same-folder + - cypress/run: + attach-workspace: true + name: example-support-files + requires: + - cypress/install + # there are no jobs to follow this one + # so no need to save the workspace files (saves time) + no-workspace: true + start: npm start --prefix examples/support-files + wait-on: 'http://localhost:1234' + command: npx cypress run --project examples/support-files + # store screenshots and videos + store_artifacts: true + post-steps: + - run: cat examples/support-files/.nyc_output/out.json + # store the created coverage report folder + # you can click on it in the CircleCI UI + # to see live static HTML site + - store_artifacts: + path: examples/support-files/coverage + # make sure the examples captures 100% of code + - run: + command: npx nyc report --check-coverage true --lines 100 + working_directory: examples/support-files + - run: + name: Check code coverage 📈 + command: | + node ../../scripts/check-coverage main.js + node ../../scripts/only-covered main.js + working_directory: examples/support-files + - publish: filters: branches: @@ -235,3 +265,4 @@ workflows: - example-before-all-visit - example-ts-example - example-same-folder + - example-support-files diff --git a/examples/support-files/.babelrc b/examples/support-files/.babelrc new file mode 100644 index 00000000..7a016cf8 --- /dev/null +++ b/examples/support-files/.babelrc @@ -0,0 +1,3 @@ +{ + "plugins": ["istanbul"] +} diff --git a/examples/support-files/README.md b/examples/support-files/README.md new file mode 100644 index 00000000..da3beaa0 --- /dev/null +++ b/examples/support-files/README.md @@ -0,0 +1,3 @@ +# example: support-files + +Filtering out support files diff --git a/examples/support-files/cypress.json b/examples/support-files/cypress.json new file mode 100644 index 00000000..c7994dc6 --- /dev/null +++ b/examples/support-files/cypress.json @@ -0,0 +1,5 @@ +{ + "fixturesFolder": false, + "pluginsFile": "cypress/plugins/index.js", + "baseUrl": "http://localhost:1234" +} diff --git a/examples/support-files/cypress/integration/spec.js b/examples/support-files/cypress/integration/spec.js new file mode 100644 index 00000000..6736cc66 --- /dev/null +++ b/examples/support-files/cypress/integration/spec.js @@ -0,0 +1,5 @@ +/// +it('works', () => { + cy.visit('/') + cy.contains('Page body') +}) diff --git a/examples/support-files/cypress/plugins/index.js b/examples/support-files/cypress/plugins/index.js new file mode 100644 index 00000000..42aa38ea --- /dev/null +++ b/examples/support-files/cypress/plugins/index.js @@ -0,0 +1,4 @@ +module.exports = (on, config) => { + on('task', require('../../../../task')) + on('file:preprocessor', require('../../../../use-babelrc')) +} diff --git a/examples/support-files/cypress/support/commands.js b/examples/support-files/cypress/support/commands.js new file mode 100644 index 00000000..219920ee --- /dev/null +++ b/examples/support-files/cypress/support/commands.js @@ -0,0 +1,2 @@ +import '../../../../support' +console.log('this is commands file') diff --git a/examples/support-files/cypress/support/index.js b/examples/support-files/cypress/support/index.js new file mode 100644 index 00000000..b5c578c9 --- /dev/null +++ b/examples/support-files/cypress/support/index.js @@ -0,0 +1 @@ +require('./commands') diff --git a/examples/support-files/index.html b/examples/support-files/index.html new file mode 100644 index 00000000..47d050a3 --- /dev/null +++ b/examples/support-files/index.html @@ -0,0 +1,13 @@ + + Page body + + + diff --git a/examples/support-files/main.js b/examples/support-files/main.js new file mode 100644 index 00000000..5dd69be2 --- /dev/null +++ b/examples/support-files/main.js @@ -0,0 +1,3 @@ +window.add = (a, b) => a + b + +window.sub = (a, b) => a - b diff --git a/examples/support-files/package.json b/examples/support-files/package.json new file mode 100644 index 00000000..9092eca7 --- /dev/null +++ b/examples/support-files/package.json @@ -0,0 +1,12 @@ +{ + "name": "example-support-files", + "description": "Filtering out support files", + "devDependencies": { + "@babel/core": "7.9.0" + }, + "scripts": { + "start": "../../node_modules/.bin/parcel serve index.html", + "cy:open": "../../node_modules/.bin/cypress open", + "dev": "../../node_modules/.bin/start-test 1234 cy:open" + } +} diff --git a/support.js b/support.js index 5d6cda23..0f71ca4f 100644 --- a/support.js +++ b/support.js @@ -7,7 +7,9 @@ const sendCoverage = (coverage, pathname = '/') => { logMessage(`Saving code coverage for **${pathname}**`) - const appCoverageOnly = filterSpecsFromCoverage(coverage) + const withoutSpecs = filterSpecsFromCoverage(coverage) + const appCoverageOnly = filterSupportFilesFromCoverage(withoutSpecs) + // stringify coverage object for speed cy.task('combineCoverage', JSON.stringify(appCoverageOnly), { log: false @@ -23,23 +25,49 @@ const logMessage = s => { cy.log(`${s} \`[@cypress/code-coverage]\``) } -const filterSpecsFromCoverage = totalCoverage => { - // remove coverage for the spec files themselves, - // only keep "external" application source file coverage +/** + * Removes support file from the coverage object. + * If there are more files loaded from support folder, also removes them + */ +const filterSupportFilesFromCoverage = totalCoverage => { const integrationFolder = Cypress.config('integrationFolder') const supportFile = Cypress.config('supportFile') + const supportFolder = Cypress.config('supportFolder') + + const isSupportFile = filename => filename === supportFile + + let coverage = Cypress._.omitBy(totalCoverage, (fileCoverage, filename) => + isSupportFile(filename) + ) + + // check the edge case + // if we have files from support folder AND the support folder is not same + // as the integration, or its prefix (this might remove all app source files) + // then remove all files from the support folder + if (!integrationFolder.startsWith(supportFolder)) { + // remove all covered files from support folder + coverage = Cypress._.omitBy(totalCoverage, (fileCoverage, filename) => + filename.startsWith(supportFolder) + ) + } + return coverage +} + +/** + * remove coverage for the spec files themselves, + * only keep "external" application source file coverage + */ +const filterSpecsFromCoverage = totalCoverage => { + const integrationFolder = Cypress.config('integrationFolder') const testFilePattern = Cypress.config('testFiles') const isUsingDefaultTestPattern = testFilePattern === '**/*.*' const isInIntegrationFolder = filename => filename.startsWith(integrationFolder) const isTestFile = filename => Cypress.minimatch(filename, testFilePattern) - const isSupportFile = filename => filename === supportFile - const isA = (fileCoverge, filename) => - isInIntegrationFolder(filename) || isSupportFile(filename) - const isB = (fileCoverge, filename) => - isTestFile(filename) || isSupportFile(filename) + const isA = (fileCoverge, filename) => isInIntegrationFolder(filename) + const isB = (fileCoverge, filename) => isTestFile(filename) const isTestFileFilter = isUsingDefaultTestPattern ? isA : isB