Skip to content

Commit

Permalink
feat: [CSR-213] Support Code Coverage (#174)
Browse files Browse the repository at this point in the history
* wip

* feat: handle coverage

* fix: use cypress-cloud for test script in frontend app

* feat: add experimentalCoverageRecording plugin option

* fix: change the script that tests frontend example app

* feat: add coverageEnabled flag to CreateRunPayload

* chore: rename from examples/frontend to examples/coverage

* chore: wip

* chore: ..

---------

Co-authored-by: Andrew Goldis <agoldis@gmail.com>
  • Loading branch information
vCaisim and agoldis committed Aug 25, 2023
1 parent b382c33 commit b29d738
Show file tree
Hide file tree
Showing 31 changed files with 19,260 additions and 10,550 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ node_modules
.yarn

# testing
coverage
examples/coverage/coverage/*
.nyc_output

# next.js
.next/
Expand Down Expand Up @@ -39,3 +40,7 @@ yarn-error.log*

# ENV file
.env

# parcel
.parcel-cache
dist
3 changes: 3 additions & 0 deletions examples/coverage/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["istanbul"]
}
37 changes: 37 additions & 0 deletions examples/coverage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Recording Cypress Tests Coverage to Currents

Tests `--experimental-coverage-recording` option.

## Setup

See the example configuration file ['cypress.config.ts]('cypress.config.ts) and [examples/coverage/cypress/support/commands.js](examples/coverage/cypress/support/commands.js)

### Install @cypress/code-coverage plugin

Install the official [@cypress/code-coverage](https://www.npmjs.com/package/@cypress/code-coverage) plugin together with the `@cypress/code-coverage/support` support file.

Add [code instrumentation](https://github.com/cypress-io/code-coverage#instrument-your-application) and optionally add `@cypress/code-coverage/use-babelrc` for on-the-fly preprocessing.

### Install `cypress-cloud`

Install `cypress-cloud` plugin **after** `@cypress/code-coverage`.

Provide `coverageFile` cypress environment property in `cypress.config.{jt}s` file for a custom location of the coverage files. The default value is `./.nyc_output/out.json`

### Start Example Server

```sh
npm run start
```

### Start `cypress-cloud` execution

```sh
npx cypress-cloud run --parallel --record --key currents_key --ci-build-id `date +%s` --experimental-coverage-recording
```

## Development

```bash
npm run cy2
```
5 changes: 5 additions & 0 deletions examples/coverage/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<body>
<h2>About</h2>
<main id="content"></main>
<script src="about.js"></script>
</body>
3 changes: 3 additions & 0 deletions examples/coverage/about.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
document
.getElementById('content')
.appendChild(document.createTextNode('Est. 2019'))
5 changes: 5 additions & 0 deletions examples/coverage/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { map } from 'lodash'

const list = [{ name: 'joe' }, { name: 'mary' }]
const names = map(list, 'name')
console.log('just names', names)
8 changes: 8 additions & 0 deletions examples/coverage/currents.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const isCI = !!(process.env.GITHUB_ACTION || process.env.CIRCLE_BRANCH);

module.exports = {
projectId: isCI ? "Ij0RfK" : "VGLEa1",
cloudServiceUrl: !isCI ? "http://localhost:1234" : undefined,
recordKey: process.env.CURRENTS_RECORD_KEY || "DsDpjPk0ITxBLTmn",
userAgent: "custom",
};
29 changes: 29 additions & 0 deletions examples/coverage/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import coveragePlugin from "@cypress/code-coverage/task";
import coverageInstrumenter from "@cypress/code-coverage/use-babelrc";

import { defineConfig } from "cypress";

import { cloudPlugin } from "cypress-cloud/plugin";

export default defineConfig({
fixturesFolder: false,
e2e: {
async setupNodeEvents(on, config) {
on("file:preprocessor", coverageInstrumenter);
const tempConfig = coveragePlugin(on, config);
return await cloudPlugin(on, tempConfig);
},
baseUrl: "http://localhost:8888",
videoUploadOnPasses: false,
supportFile: "cypress/support/e2e.js",
specPattern: "cypress/*/**/*.cy.js",
env: {
// @cypress/code-coverage config
codeCoverage: {
exclude: ["cypress/**/*.*"],
},
// set custom coverage file for cypress-cloud
coverageFile: "./.nyc_output/out.json",
},
},
});
26 changes: 26 additions & 0 deletions examples/coverage/cypress/e2e/spec_1.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
/// <reference types="Cypress" />

context("Page test", () => {
beforeEach(() => {
cy.visit("/", {
onBeforeLoad(win) {
cy.spy(win.console, "log").as("log");
},
});
});

it("logs names", function () {
cy.get("@log")
.should("have.been.calledOnce")
.should("have.been.calledWith", "just names", ["joe", "mary"]);
});

it("loads About page", () => {
cy.contains("About").click();
cy.url().should("match", /\/about/);
cy.contains("h2", "About");
cy.contains("Est. 2019");
});
});
15 changes: 15 additions & 0 deletions examples/coverage/cypress/e2e/spec_2.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
/// <reference types="Cypress" />

import { add } from "../../unit";

context("Unit tests", () => {
it("adds numbers", () => {
expect(add(2, 3)).to.equal(5);
});

it("concatenates strings", () => {
expect(add("foo", "Bar")).to.equal("fooBar");
});
});
2 changes: 2 additions & 0 deletions examples/coverage/cypress/support/commands.js
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')
1 change: 1 addition & 0 deletions examples/coverage/cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require("./commands");
8 changes: 8 additions & 0 deletions examples/coverage/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<body>
<nav>
<a href="./about.html">About</a>
</nav>
<h2>Test page</h2>
<p>Open the DevTools to see console messages</p>
<script src="app.js" type="module"></script>
</body>
27 changes: 27 additions & 0 deletions examples/coverage/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "example-frontend",
"description": "Tests a frontend app",
"devDependencies": {
"@babel/core": "^7.22.9",
"@cypress/code-coverage": "^3.11.0",
"babel-plugin-istanbul": "^6.1.1",
"check-code-coverage": "^1.10.5",
"nyc": "^15.1.0",
"parcel": "^2.9.3",
"start-server-and-test": "^2.0.0"
},
"scripts": {
"cy:run": "../../node_modules/.bin/cypress run",
"cy:open": "../../node_modules/.bin/cypress open",
"start": "../../node_modules/.bin/parcel serve --port 8888 --cache-dir ./.parcel-cache index.html",
"pretest": "rimraf .nyc_output .parcel-cache coverage dist",
"cy2": "../../node_modules/.bin/start-test 8888 cli",
"coverage:verify": "npx nyc report --check-coverage true --lines 100",
"coverage:check-files": "../../node_modules/.bin/check-coverage app.js && ../../node_modules/.bin/check-coverage about.js && ../../node_modules/.bin/check-coverage unit.js && ../../node_modules/.bin/only-covered app.js about.js unit.js",
"cli": "npx cypress-cloud run --ci-build-id $(date \"+%s\") --parallel --record --experimental-coverage-recording"
},
"dependencies": {
"cypress-cloud": "^1.9.2",
"lodash": "^4.17.21"
}
}
35 changes: 35 additions & 0 deletions examples/coverage/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Next.js",
"compilerOptions": {
"baseUrl": ".",
"composite": false,
"declaration": true,
"declarationMap": true,
"inlineSources": false,
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
},
"include": ["next-env.d.ts"],
"exclude": ["node_modules"]
}
1 change: 1 addition & 0 deletions examples/coverage/unit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const add = (a, b) => a + b
Loading

0 comments on commit b29d738

Please sign in to comment.