Skip to content

fix: code coverage incomplete on redirect #660

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
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ workflows:
- new-cypress-config/ts-example
- new-cypress-config/unit-tests-js
- new-cypress-config/use-webpack
- new-cypress-config/returning-to-application
- windows_test
- publish:
filters:
Expand Down
3 changes: 2 additions & 1 deletion .nycrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"exclude": [
"support-utils.js",
"task-utils.js"
"task-utils.js",
"support.js"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being excluded?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you run the unit-tests, support.js is reported as having too little coverage, but support.js is not even being tested (only support-utils.js). I thought that this is an issue with my code, but I get the same result on the main branch.

]
}
12 changes: 7 additions & 5 deletions support.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ const registerHooks = () => {
return
}

if (
Cypress._.find(windowCoverageObjects, {
coverage: applicationSourceCoverage
})
) {
const existingCoverage = Cypress._.find(windowCoverageObjects, {
coverage: applicationSourceCoverage
})
if (existingCoverage) {
// this application code coverage object is already known
// which can happen when combining `window:load` and `before` callbacks
// it can also happen when the user leaves and returns to the application under test
// in which case we need to use new applicationSourceCoverage, because the old will not be updated anymore.
existingCoverage.coverage = applicationSourceCoverage
return
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["istanbul"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# example: frontend

Tests a frontend app that redirects, through un-instrumented code, back to itself.
34 changes: 34 additions & 0 deletions test-apps/new-cypress-config/returning-to-application/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { map } from 'lodash'

// The redirect code needs to be un-instrumented, otherwise the statement map will be different
// depending on which code path the redirect took.
// Cypress will then correctly treat them as different coverage objects and merge the code coverage.
// If the redirect code is un-instrumented, Cypress can't tell them apart and will keep referencing to the (stale) first coverage object.
// Timeouts are necessary to allow cypress to pick up the "initial" coverage object
// and compare it to the existing coverage objects.
eval(`
new Promise((resolve) => {
if (window.location.port === "1234" && !localStorage.getItem("visited")) {
localStorage.setItem("visited", true);
console.log("Not visited. Redirecting");
setTimeout(() => {
window.location.href = "http://localhost:1235";
}, 500);
} else if (window.location.port === "1235") {
console.log("Redirecting back.");
setTimeout(() => {
window.location.href = "http://localhost:1234";
}, 500);
} else {
console.log("Visited");
setTimeout(() => {
resolve();
}, 500)
}
})
`).then(() => {
document.body
.appendChild(document.createTextNode('Returned to app'))
});


Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { defineConfig } = require('cypress')

module.exports = defineConfig({
fixturesFolder: false,
e2e: {
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:1234',
env: {
codeCoverage: {
exclude: ['cypress/**/*.*']
}
},
chromeWebSecurity: false
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
/// <reference types="Cypress" />

context('Page test', () => {

it('logs names', function() {
cy.clearLocalStorage();
cy.visit("http://localhost:1234")
cy.contains("Returned to app")
})

})
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = (on, config) => {
require('@cypress/code-coverage/task')(on, config)
return config
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '@cypress/code-coverage/support'
console.log('this is commands file')
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('./commands')
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<body>
<h2>Test page</h2>
<script src="app.js"></script>
</body>
Loading