Skip to content

Commit f933e9d

Browse files
grantbdevbahmutov
andcommitted
Save coverage for each page in a test (cypress-io#70)
Save coverage for each page visited in a test by keeping a reference to the coverage for each app window loaded and then saving the coverage at the end after coverage is calculated. An additional page is added to the example test app and the page test navigates to the new page. Without this coverage change, coverage is lost for `app.js` due to the last page not loading it. With this coverage change, coverage is kept for `app.js` along with coverage for `about.js`. Co-authored-by: Gleb Bahmutov <[email protected]>
1 parent 6103751 commit f933e9d

File tree

5 files changed

+29
-6
lines changed

5 files changed

+29
-6
lines changed

cypress/about.html

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<body>
2+
<h2>About</h2>
3+
<main id="content"></main>
4+
<script src="about.js"></script>
5+
</body>

cypress/about.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
document
2+
.getElementById('content')
3+
.appendChild(document.createTextNode('Est. 2019'))

cypress/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<body>
2+
<nav>
3+
<a href="/about.html">About</a>
4+
</nav>
25
<h2>Test page</h2>
36
<p>Open the DevTools to see console messages</p>
47
<script src="app.js"></script>

cypress/integration/spec.js

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ context('Page test', () => {
1212
cy.spy(win.console, 'log').as('log')
1313
}
1414
})
15+
16+
cy.contains('About').click()
1517
})
1618

1719
it('logs names', function () {

support.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,37 @@ const sendCoverage = coverage => {
1919
if (Cypress.env('coverage') === false) {
2020
console.log('Skipping code coverage hooks')
2121
} else {
22+
let windowCoverageObjects
23+
2224
before(() => {
2325
// we need to reset the coverage when running
2426
// in the interactive mode, otherwise the counters will
2527
// keep increasing every time we rerun the tests
2628
cy.task('resetCoverage', { isInteractive: Cypress.config('isInteractive') })
2729
})
2830

29-
afterEach(() => {
30-
// save coverage after each test
31-
// because the entire "window" object is about
32-
// to be recycled by Cypress before next test
33-
cy.window().then(win => {
31+
beforeEach(() => {
32+
windowCoverageObjects = []
33+
34+
// save reference to coverage for each app window loaded in the test
35+
cy.on('window:load', win => {
3436
// if application code has been instrumented, the app iframe "window" has an object
3537
const applicationSourceCoverage = win.__coverage__
3638

3739
if (applicationSourceCoverage) {
38-
sendCoverage(applicationSourceCoverage)
40+
windowCoverageObjects.push(applicationSourceCoverage)
3941
}
4042
})
4143
})
4244

45+
afterEach(() => {
46+
// save coverage after the test
47+
// because now the window coverage objects have been updated
48+
windowCoverageObjects.forEach(coverage => {
49+
sendCoverage(coverage)
50+
})
51+
})
52+
4353
after(() => {
4454
// there might be server-side code coverage information
4555
// we should grab it once after all tests finish

0 commit comments

Comments
 (0)