Skip to content
This repository was archived by the owner on Dec 12, 2020. It is now read-only.

Commit 61eb3b0

Browse files
authored
feat: instrument code coverage by default (#339)
1 parent 2d486fc commit 61eb3b0

File tree

19 files changed

+273
-41
lines changed

19 files changed

+273
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ cypress/videos/
77
cypress/screenshots
88
.nyc_output
99
coverage
10+
*.tgz

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
> A little helper to unit test Vue components in the open source [Cypress.io](https://www.cypress.io/) E2E test runner **v4.5.0+**
1111
12-
**Jump to:** [Comparison](#comparison), [Blog posts](#blog-posts), Examples: [basic](#basic-examples), [advanced](#advanced-examples), [external](#external-examples), [Code coverage](#code-coverage)
12+
**Jump to:** [Comparison](#comparison), [Blog posts](#blog-posts), Examples: [basic](#basic-examples), [advanced](#advanced-examples), [full](#full-examples), [external](#external-examples), [Code coverage](#code-coverage)
1313

1414
## TLDR
1515

@@ -598,6 +598,16 @@ Spec | Description
598598
[mocking-imports](cypress/component/advanced/mocking-imports) | Stub ES6 imports from the tests
599599
<!-- prettier-ignore-end -->
600600

601+
### Full examples
602+
603+
We have several subfolders in [examples](examples) folder.
604+
605+
<!-- prettier-ignore-start -->
606+
Folder Name | Description
607+
--- | ---
608+
[cli](examples/cli) | An example app scaffolded using Vue CLI and the component testing added using `vue add cypress-experimental` command.
609+
<!-- prettier-ignore-end -->
610+
601611
### External examples
602612

603613
<!-- prettier-ignore-start -->

circle.yml

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,20 @@ workflows:
1111
- cypress/install:
1212
name: Install
1313
executor: cypress/base-12
14-
build: npm run build
14+
# creates files in "dist" folder
15+
build: |
16+
npm run build
17+
echo ""
18+
echo "Build package archive 📦"
19+
echo ""
20+
# first show the contents to be packed
21+
npm pack --dry
22+
echo ""
23+
echo "packing ..."
24+
echo ""
25+
npm pack
26+
echo ""
27+
ls -la
1528
post-steps:
1629
- run:
1730
name: Show info 📺
@@ -40,6 +53,41 @@ workflows:
4053
echo "Test files for this machine are $TESTFILES"
4154
npx cypress run --spec $TESTFILES
4255
56+
- cypress/run:
57+
name: Example CLI
58+
executor: cypress/base-12
59+
requires:
60+
- Install
61+
install-command: npm install
62+
verify-command: echo 'Already verified'
63+
no-workspace: true
64+
working_directory: examples/cli
65+
command: |
66+
echo "🦶🏻 Scaffolding component tests"
67+
echo ""
68+
# scaffolds Babel + Webpack combo
69+
npx --package @vue/cli vue add cypress-experimental
70+
echo ""
71+
echo "🦶🏻 test scaffolded project, should work"
72+
echo ""
73+
DEBUG=cypress-vue-unit-test npx cypress run --spec 'tests/components/**/*.js'
74+
# let's inspect the scaffolded app
75+
ls -la
76+
echo ""
77+
echo "🦶🏻 install the current cypress-vue-unit-test"
78+
echo ""
79+
npm install ../../cypress-vue-unit-test-0.0.0-development.tgz
80+
echo ""
81+
echo "🦶🏻 run component tests"
82+
echo ""
83+
DEBUG=cypress-vue-unit-test npx cypress run --spec 'tests/components/**/*.js'
84+
echo ""
85+
echo "🦶🏻 look at the generated files, should have coverage"
86+
# (after updating cypress-experimental)
87+
echo ""
88+
ls -la
89+
store_artifacts: true
90+
4391
# this job attaches the workspace left by the install job
4492
# so it is ready to run Cypress tests
4593
# only we will run semantic release script instead
@@ -55,6 +103,7 @@ workflows:
55103
requires:
56104
- Install
57105
- Test
106+
- Example CLI
58107
install-command: echo 'Already installed'
59108
verify-command: echo 'Already verified'
60109
no-workspace: true

cypress/plugins/index.js

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
1-
// default webpack file preprocessor is good for simple cases
2-
const { onFileDefaultPreprocessor } = require('../../preprocessor/webpack')
3-
1+
/// <reference types="cypress" />
2+
const preprocessor = require('../../plugins/webpack')
43
module.exports = (on, config) => {
5-
require('@cypress/code-coverage/task')(on, config)
6-
on('file:preprocessor', onFileDefaultPreprocessor(config))
7-
8-
// IMPORTANT to return the config object
9-
// with the any changed environment variables
4+
preprocessor(on, config)
105
return config
116
}
12-
13-
/*
14-
for more complex cases, when the project already includes webpack.config.js
15-
16-
const {
17-
onFilePreprocessor
18-
} = require('cypress-vue-unit-test/preprocessor/webpack')
19-
module.exports = on => {
20-
on('file:preprocessor', onFilePreprocessor('../path/to/webpack.config'))
21-
}
22-
*/

cypress/support/index.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1 @@
1-
require('@cypress/code-coverage/support')
2-
3-
beforeEach(() => {
4-
const container = document.getElementById('cypress-jsdom')
5-
if (container) {
6-
container.innerHTML = ''
7-
}
8-
})
1+
require('../../dist/support')

docs/manual-install.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@
88
npm install -D cypress cypress-vue-unit-test
99
```
1010

11-
2. Include this plugin `cypress/plugin/index.js`
11+
2. Include this plugin from your project's `cypress/plugin/index.js` file
1212

1313
```js
14-
// default webpack file preprocessor is good for simple cases
15-
// Required to temporarily patch async components, chunking, and inline image loading
16-
import { onFileDefaultPreprocessor } from 'cypress-vue-unit-test/dist/preprocessor/webpack'
17-
18-
module.exports = (on) => {
19-
on('file:preprocessor', onFileDefaultPreprocessor)
14+
const preprocessor = require('cypress-vue-unit-test/dist/plugins/webpack')
15+
module.exports = (on, config) => {
16+
preprocessor(on, config)
17+
// IMPORTANT return the config object
18+
return config
2019
}
2120
```
2221

23-
3. Include the support file `cypress/support/index.js`
22+
3. Include the support file from your project's `cypress/support/index.js` file
2423

2524
```js
2625
import 'cypress-vue-unit-test/dist/support'

examples/cli/.gitignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.DS_Store
2+
node_modules
3+
/dist
4+
5+
# local env files
6+
.env.local
7+
.env.*.local
8+
9+
# Log files
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
pnpm-debug.log*
14+
15+
# Editor directories and files
16+
.idea
17+
.vscode
18+
*.suo
19+
*.ntvs*
20+
*.njsproj
21+
*.sln
22+
*.sw?

examples/cli/.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

examples/cli/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# cli-example
2+
3+
Application scaffolded with Vue CLI v3

examples/cli/babel.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
presets: [
3+
'@vue/cli-plugin-babel/preset'
4+
]
5+
}

examples/cli/package.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "cli-example",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"serve": "vue-cli-service serve",
7+
"build": "vue-cli-service build",
8+
"lint": "vue-cli-service lint"
9+
},
10+
"dependencies": {
11+
"core-js": "^3.6.5",
12+
"vue": "^2.6.11"
13+
},
14+
"devDependencies": {
15+
"@vue/cli-plugin-babel": "~4.4.0",
16+
"@vue/cli-plugin-eslint": "~4.4.0",
17+
"@vue/cli-service": "~4.4.0",
18+
"babel-eslint": "^10.1.0",
19+
"eslint": "^6.7.2",
20+
"eslint-plugin-vue": "^6.2.2",
21+
"vue-template-compiler": "^2.6.11"
22+
},
23+
"eslintConfig": {
24+
"root": true,
25+
"env": {
26+
"node": true
27+
},
28+
"extends": [
29+
"plugin:vue/essential",
30+
"eslint:recommended"
31+
],
32+
"parserOptions": {
33+
"parser": "babel-eslint"
34+
},
35+
"rules": {}
36+
},
37+
"browserslist": [
38+
"> 1%",
39+
"last 2 versions",
40+
"not dead"
41+
]
42+
}

examples/cli/src/App.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<template>
2+
<div id="app">
3+
<img alt="Vue logo" src="./assets/logo.png">
4+
<HelloWorld msg="Welcome to Your Vue.js App"/>
5+
</div>
6+
</template>
7+
8+
<script>
9+
import HelloWorld from './components/HelloWorld.vue'
10+
11+
export default {
12+
name: 'App',
13+
components: {
14+
HelloWorld
15+
}
16+
}
17+
</script>
18+
19+
<style>
20+
#app {
21+
font-family: Avenir, Helvetica, Arial, sans-serif;
22+
-webkit-font-smoothing: antialiased;
23+
-moz-osx-font-smoothing: grayscale;
24+
text-align: center;
25+
color: #2c3e50;
26+
margin-top: 60px;
27+
}
28+
</style>

examples/cli/src/assets/logo.png

6.69 KB
Loading
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<template>
2+
<div class="hello">
3+
<h1>{{ msg }}</h1>
4+
<p>
5+
For a guide and recipes on how to configure / customize this project,<br>
6+
check out the
7+
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
8+
</p>
9+
<h3>Installed CLI Plugins</h3>
10+
<ul>
11+
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
12+
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
13+
</ul>
14+
<h3>Essential Links</h3>
15+
<ul>
16+
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
17+
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
18+
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
19+
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
20+
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
21+
</ul>
22+
<h3>Ecosystem</h3>
23+
<ul>
24+
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
25+
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
26+
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
27+
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
28+
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
29+
</ul>
30+
</div>
31+
</template>
32+
33+
<script>
34+
export default {
35+
name: 'HelloWorld',
36+
props: {
37+
msg: String
38+
}
39+
}
40+
</script>
41+
42+
<!-- Add "scoped" attribute to limit CSS to this component only -->
43+
<style scoped>
44+
h3 {
45+
margin: 40px 0 0;
46+
}
47+
ul {
48+
list-style-type: none;
49+
padding: 0;
50+
}
51+
li {
52+
display: inline-block;
53+
margin: 0 10px;
54+
}
55+
a {
56+
color: #42b983;
57+
}
58+
</style>

examples/cli/src/main.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Vue from 'vue'
2+
import App from './App.vue'
3+
4+
Vue.config.productionTip = false
5+
6+
new Vue({
7+
render: h => h(App),
8+
}).$mount('#app')

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
"url": "https://github.com/bahmutov/cypress-vue-unit-test.git"
2626
},
2727
"scripts": {
28-
"build": "babel src --ignore src/*spec.js --out-dir dist && babel preprocessor --out-dir dist/preprocessor",
28+
"build": "babel src --ignore src/*spec.js --out-dir dist && babel preprocessor --out-dir dist/preprocessor && babel plugins --out-dir dist/plugins",
2929
"ban": "ban",
3030
"deps": "echo skip deps-ok && dependency-check --no-dev .",
3131
"issues": "git-issues",
3232
"license": "license-checker --production --onlyunknown --csv",
33-
"lint": "prettier --check '*.js' 'cypress/**/*.js' 'src/**/*.js' 'preprocessor/**/*.js'",
33+
"lint": "prettier --check '*.js' 'cypress/**/*.js' 'src/**/*.js' 'preprocessor/**/*.js' 'plugins/**/*.js'",
3434
"prelint": "npm run pretty",
3535
"pretest": "npm run lint && npm run build",
36-
"pretty": "prettier --write '*.js' 'cypress/**/*.js' 'src/**/*.js' 'preprocessor/**/*.js'",
36+
"pretty": "prettier --write '*.js' 'cypress/**/*.js' 'src/**/*.js' 'preprocessor/**/*.js' 'plugins/**/*.js'",
3737
"size": "npm pack --dry",
3838
"test": "npm run cy:run",
3939
"unit": "mocha src/*-spec.js",

plugins/webpack/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// <reference types="cypress" />
2+
const { onFileDefaultPreprocessor } = require('../../preprocessor/webpack')
3+
4+
/**
5+
* Registers Cypress preprocessor for Vue component testing.
6+
* IMPORTANT to return the config object with
7+
* with the any changed environment variables.
8+
*
9+
* @param {Cypress.PluginConfigOptions} config Cypress config object.
10+
* @example
11+
* // in your project's plugins/index.js file
12+
* const preprocessor = require('cypress-vue-unit-test/dist/plugins/webpack')
13+
* module.exports = (on, config) => {
14+
* preprocessor(on, config)
15+
* // IMPORTANT return the config object
16+
* return config
17+
* }
18+
*/
19+
const cypressPluginsFn = (on, config) => {
20+
require('@cypress/code-coverage/task')(on, config)
21+
on('file:preprocessor', onFileDefaultPreprocessor(config))
22+
return config
23+
}
24+
25+
module.exports = cypressPluginsFn

src/support.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/* eslint-env mocha */
2+
require('@cypress/code-coverage/support')
3+
24
/** Initialize an empty document with root element */
35
function renderTestingPlatform() {
46
const document = cy.state('document')
57
const el = document.getElementById('cypress-jsdom')
68
if (el) {
9+
// clean the element before each test
710
while (el.hasChildNodes()) {
811
el.removeChild(el.lastChild)
912
}

0 commit comments

Comments
 (0)