Skip to content

Commit

Permalink
fix: code coverage incomplete on redirect (#660)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Schile <[email protected]>
Co-authored-by: Cacie Prins <[email protected]>
Co-authored-by: Matthew Schile <[email protected]>
  • Loading branch information
4 people authored Oct 25, 2023
1 parent 3fc4872 commit 443029b
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 8 deletions.
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
docker:
- image: cimg/node:20.8.0
environment:
# we don't need Cypress to check code styl
# we don't need Cypress to check code style
CYPRESS_INSTALL_BINARY: '0'
steps:
- attach_workspace:
Expand Down Expand Up @@ -158,6 +158,7 @@ workflows:
- ts-example
- unit-tests-js
- use-webpack
- redirect
- windows_test
- publish:
filters:
Expand All @@ -184,4 +185,5 @@ workflows:
- test-ts-example
- test-unit-tests-js
- test-use-webpack
- test-redirect
- windows_test
2 changes: 1 addition & 1 deletion .nycrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"exclude": [
"support-utils.js",
"support.js",
"task-utils.js"
]
}
14 changes: 8 additions & 6 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
// which can happen when combining `window:load` and `before` callbacks,
// it can also happen when the user navigates away and then returns to the page
// in which case we need to use new applicationSourceCoverage, because the old will not be updated anymore.
existingCoverage.coverage = applicationSourceCoverage
return
}

Expand Down
3 changes: 3 additions & 0 deletions test-apps/redirect/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["istanbul"]
}
5 changes: 5 additions & 0 deletions test-apps/redirect/.nycrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"exclude": [
"app.js"
]
}
3 changes: 3 additions & 0 deletions test-apps/redirect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# example: redirect

Tests a frontend app that redirects, through un-instrumented code, back to itself.
28 changes: 28 additions & 0 deletions test-apps/redirect/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This redirect code needs to be un-instrumented (excluded in .nycrc.json)
// - If the redirect code is instrumented, Cypress would then treat them as different coverage objects and merge the code coverage (not testing what we want).
// - If the redirect code is un-instrumented, Cypress can't tell them apart and will update the existing coverage object to point to the correct one (testing what we want).

import { returnToApp } from './utils'

// Timeouts are necessary to allow cypress to pick up the "initial" coverage object and compare it to the existing coverage objects.
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(() => {
returnToApp()
})
18 changes: 18 additions & 0 deletions test-apps/redirect/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { defineConfig } = require('cypress')

module.exports = defineConfig({
fixturesFolder: false,
e2e: {
setupNodeEvents(on, config) {
require('@cypress/code-coverage/task')(on, config)
return config
},
baseUrl: 'http://localhost:1234',
env: {
codeCoverage: {
exclude: ['cypress/**/*.*']
}
},
chromeWebSecurity: false
}
})
11 changes: 11 additions & 0 deletions test-apps/redirect/cypress/e2e/spec.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
/// <reference types="Cypress" />

context('Page test', () => {
it('redirects back to the app', function() {
cy.clearLocalStorage()
cy.visit("http://localhost:1234")
cy.contains("Returned to app")
})
})
1 change: 1 addition & 0 deletions test-apps/redirect/cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@cypress/code-coverage/support'
4 changes: 4 additions & 0 deletions test-apps/redirect/index.html
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>
16 changes: 16 additions & 0 deletions test-apps/redirect/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "example-redirect",
"description": "Tests a frontend app that redirects, through un-instrumented code, back to itself.",
"devDependencies": {
"@babel/core": "^7.12.0"
},
"scripts": {
"cy:run": "cypress run",
"start:app": "parcel serve -p 1234 index.html",
"start:other-app": "parcel serve -p 1235 index.html",
"pretest": "rimraf .nyc_output .cache coverage dist",
"test": "start-test start:app http://localhost:1234 start:other-app http://localhost:1235 cy:run",
"coverage:verify": "npx nyc report --check-coverage true --lines 100",
"coverage:check-files": "check-coverage utils.js && only-covered utils.js"
}
}
4 changes: 4 additions & 0 deletions test-apps/redirect/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const returnToApp = () => {
document.body
.appendChild(document.createTextNode('Returned to app'))
}

0 comments on commit 443029b

Please sign in to comment.