cypress-io / cypress-io/code-coverage

[Bug Found + Fix] Full Stack Code Coverage

Open
#129 12 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
445
Forks
115
PR merge metrics
No merged PRs in 30d

Description

# I'm submitting a ...
Bug report plus solution for improvement.

# Context
I've decided to implement the fullstack code coverage on my project which is a front Angular with back Nestjs. It's quite a big project, both in the front and the back side.
Implementation with Angular was really straightforward thank's to https://github.com/skylock/cypress-angular-coverage-example

Fullstack Implementation was simple too, but led me to some bugs. The cy.request() made during the afterAll hook which is supposed to get the __coverage__ json was failing like 9 out of 10 times (timeout error).
I quickly deduced that the size of the json sent was the problem, it's about 5mb.

I tried multiple things like, changing the response timeout to 5 minutes, sending the result compressed as gzip, or sending the json as a string, then parsing it in the front, but none of these solutions worked.

And then I saw that under the hood cy.request which is used to communicate with the backend to get the coverage json, was used with HTTP1 which is super slow.
So I found this workaround which now gets the json, in like 1 sec instead of 20sec (when it worked).

# Current implementation
> // node_modules/@cypress/code-coverage/support.js

```js
after(() => {
// there might be server-side code coverage information
// we should grab it once after all tests finish
const baseUrl = Cypress.config('baseUrl') || cy.state('window').origin
const runningEndToEndTests = baseUrl !== Cypress.config('proxyUrl')
if (runningEndToEndTests) {
// we can only request server-side code coverage
// if we are running end-to-end tests,
// otherwise where do we send the request?
const url = Cypress._.get(
Cypress.env('codeCoverage'),
'url',
'/__coverage__'
)
cy.request({
url,
log: false,
failOnStatusCode: false
})
.then(r => Cypress._.get(r, 'body.coverage', null), { log: false })
.then(coverage => {
if (!coverage) {
// we did not get code coverage - this is the
// original failed request
return
}
sendCoverage(coverage, 'backend')
})
}
...
```

# Workaround
> // node_modules/@cypress/code-coverage/support.js
```js
after(() => {
// there might be server-side code coverage information
// we should grab it once after all tests finish
const baseUrl = Cypress.config("baseUrl") || cy.state("window").origin;
const runningEndToEndTests = baseUrl !== Cypress.config("proxyUrl");
if (runningEndToEndTests) {
// we can only request server-side code coverage
// if we are running end-to-end tests,
// otherwise where do we send the request?
const url = Cypress._.get(Cypress.env("codeCoverage"), "url", "/__coverage__");
/* HERE IS THE FIX */
cy.exec(`curl ${url}`).then(r => {
if (!r || !r.stdout) {
// we did not get code coverage - this is the
// original failed request
return;
}
const coverage = JSON.parse(r.stdout).coverage;
sendCoverage(coverage, "backend");
});
/* END OF FIX */
}
....
```
I wasn't sure about the coding style that you have, that's why I'm opening an issue first and not a PR. Let me know if you want me to try something :)

By the way you are doing an amazing job at cypress ! 👏

# PS

Actually, before implementing the full stack code coverage on my big project, I've first made a minimal working repository with angular nestjs and cypress, to figure out how the implementation could be done.

Here is the link : https://github.com/flogh/cypress-angular-nestjs-code-coverage-fullstack

Maybe you'll want to add it to with the other implementation examples.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.