Skip to content

fix: filtering against list of specs #182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 7, 2020
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
33 changes: 32 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ workflows:
- run: npx nyc report --check-coverage true --lines 100 --include cypress/unit.js

- cypress/run:
# TODO switch to separate example in "examples/..."
name: backend coverage
requires:
- cypress/install
Expand All @@ -96,7 +97,7 @@ workflows:
path: coverage
# print code coverage summary to the terminal
# and make sure there the coverage is above certain limit
- run: npx nyc report --check-coverage true --lines 85
- run: npx nyc report --check-coverage true --lines 72
# and look at the server index file - should be fully covered
- run: npx nyc report --check-coverage true --lines 100 --include test-backend/index.js

Expand Down Expand Up @@ -280,6 +281,35 @@ workflows:
node ../../scripts/only-covered main.js
working_directory: examples/use-plugins-and-support

- cypress/run:
attach-workspace: true
name: example-one-spec
requires:
- cypress/install
# there are no jobs to follow this one
# so no need to save the workspace files (saves time)
no-workspace: true
command: npx cypress run --project examples/one-spec
# store screenshots and videos
store_artifacts: true
post-steps:
- run: cat examples/one-spec/.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/one-spec/coverage
# make sure the examples captures 100% of code
- run:
command: npx nyc report --check-coverage true --lines 100
working_directory: examples/one-spec
- run:
name: Check code coverage 📈
command: |
node ../../scripts/check-coverage main.js
node ../../scripts/only-covered main.js
working_directory: examples/one-spec

- publish:
filters:
branches:
Expand All @@ -296,3 +326,4 @@ workflows:
- example-same-folder
- example-support-files
- example-use-plugins-and-support
- example-one-spec
84 changes: 84 additions & 0 deletions cypress/integration/filtering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const { filterSpecsFromCoverage } = require('../../utils')

describe('minimatch', () => {
it('string matches', () => {
expect(
Cypress.minimatch('/path/to/specA.js', '/path/to/specA.js'),
'matches full strings'
).to.be.true

expect(
Cypress.minimatch('/path/to/specA.js', 'specA.js'),
'does not match just the end'
).to.be.false

expect(
Cypress.minimatch('/path/to/specA.js', '**/specA.js'),
'matches using **'
).to.be.true
})
})

describe('filtering specs', () => {
it('filters list of specs by single string', () => {
const config = cy.stub()
config.withArgs('testFiles').returns(['specA.js'])
config.withArgs('integrationFolder').returns('/path/to/integration/')

const totalCoverage = {
'/path/to/specA.js': {},
'/path/to/specB.js': {}
}
const result = filterSpecsFromCoverage(totalCoverage, config)
expect(result).to.deep.equal({
'/path/to/specB.js': {}
})
})

it('filters list of specs by pattern', () => {
const config = cy.stub()
config.withArgs('testFiles').returns(['**/*B.js'])
config.withArgs('integrationFolder').returns('/path/to/integration/')

const totalCoverage = {
'/path/to/specA.js': {},
'/path/to/specB.js': {}
}
const result = filterSpecsFromCoverage(totalCoverage, config)
expect(result).to.deep.equal({
'/path/to/specA.js': {}
})
})

it('filters list of specs by pattern and single spec', () => {
const config = cy.stub()
config.withArgs('testFiles').returns(['**/*B.js', 'specA.js'])
config.withArgs('integrationFolder').returns('/path/to/integration/')

const totalCoverage = {
'/path/to/specA.js': {},
'/path/to/specB.js': {}
}
const result = filterSpecsFromCoverage(totalCoverage, config)
expect(result, 'all specs have been filtered out').to.deep.equal({})
})

it('filters list of specs in integration folder', () => {
const config = cy.stub()
config.withArgs('testFiles').returns('**/*.*') // default pattern
config.withArgs('integrationFolder').returns('/path/to/integration/')

const totalCoverage = {
'/path/to/specA.js': {},
'/path/to/specB.js': {},
// these files should be removed
'/path/to/integration/spec1.js': {},
'/path/to/integration/spec2.js': {}
}
const result = filterSpecsFromCoverage(totalCoverage, config)
expect(result).to.deep.equal({
'/path/to/specA.js': {},
'/path/to/specB.js': {}
})
})
})
3 changes: 3 additions & 0 deletions examples/one-spec/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["istanbul"]
}
3 changes: 3 additions & 0 deletions examples/one-spec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# example: one-spec

Only running a single spec
5 changes: 5 additions & 0 deletions examples/one-spec/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"fixturesFolder": false,
"pluginsFile": "cypress/plugins/index.js",
"testFiles": ["spec-a.js"]
}
13 changes: 13 additions & 0 deletions examples/one-spec/cypress/integration/spec-a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// <reference types="cypress" />
it('spec a', () => {
cy.visit('index.html')
cy.contains('Page body')

cy.window()
.invoke('add', 2, 3)
.should('equal', 5)

cy.window()
.invoke('sub', 2, 3)
.should('equal', -1)
})
5 changes: 5 additions & 0 deletions examples/one-spec/cypress/integration/spec-b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="cypress" />
it('spec b', () => {
// should not run
throw new Error('Spec b should not run')
})
5 changes: 5 additions & 0 deletions examples/one-spec/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = (on, config) => {
require('../../../../task')(on, config)
on('file:preprocessor', require('../../../../use-babelrc'))
return config
}
1 change: 1 addition & 0 deletions examples/one-spec/cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '../../../../support'
4 changes: 4 additions & 0 deletions examples/one-spec/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<body>
Page body
<script src="main-instrumented.js"></script>
</body>
146 changes: 146 additions & 0 deletions examples/one-spec/main-instrumented.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions examples/one-spec/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
window.add = (a, b) => a + b

window.sub = (a, b) => a - b
7 changes: 7 additions & 0 deletions examples/one-spec/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "example-one-spec",
"description": "Only running a single spec",
"scripts": {
"cy:open": "../../node_modules/.bin/cypress open"
}
}
25 changes: 3 additions & 22 deletions support.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/// <reference types="cypress" />
// @ts-check

const { filterSpecsFromCoverage } = require('./utils')

/**
* Sends collected code coverage object to the backend code
Expand Down Expand Up @@ -53,28 +56,6 @@ const filterSupportFilesFromCoverage = totalCoverage => {
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 isA = (fileCoverge, filename) => isInIntegrationFolder(filename)
const isB = (fileCoverge, filename) => isTestFile(filename)

const isTestFileFilter = isUsingDefaultTestPattern ? isA : isB

const coverage = Cypress._.omitBy(totalCoverage, isTestFileFilter)
return coverage
}

const registerHooks = () => {
let windowCoverageObjects

Expand Down
Loading