├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── cypress.json
├── jest.config.js
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ ├── MessageList.vue
│ └── NewMessageForm.vue
└── main.js
├── tests
├── e2e
│ ├── .eslintrc.js
│ ├── plugins
│ │ └── index.js
│ ├── specs
│ │ └── creating_a_message.spec.js
│ └── support
│ │ ├── commands.js
│ │ └── index.js
└── unit
│ └── NewMessageForm.spec.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
7 | parserOptions: {
8 | parser: "babel-eslint"
9 | },
10 | rules: {
11 | "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
12 | "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
13 | },
14 | overrides: [
15 | {
16 | files: [
17 | "**/__tests__/*.{j,t}s?(x)",
18 | "**/tests/unit/**/*.spec.{j,t}s?(x)"
19 | ],
20 | env: {
21 | jest: true
22 | }
23 | }
24 | ]
25 | };
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | /tests/e2e/videos/
6 | /tests/e2e/screenshots/
7 |
8 |
9 | # local env files
10 | .env.local
11 | .env.*.local
12 |
13 | # Log files
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 | pnpm-debug.log*
18 |
19 | # Editor directories and files
20 | .idea
21 | .vscode
22 | *.suo
23 | *.ntvs*
24 | *.njsproj
25 | *.sln
26 | *.sw?
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # learn-tdd-in-vue
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn build
16 | ```
17 |
18 | ### Run your unit tests
19 | ```
20 | yarn test:unit
21 | ```
22 |
23 | ### Run your end-to-end tests
24 | ```
25 | yarn test:e2e
26 | ```
27 |
28 | ### Lints and fixes files
29 | ```
30 | yarn lint
31 | ```
32 |
33 | ### Customize configuration
34 | See [Configuration Reference](https://cli.vuejs.org/config/).
35 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"]
3 | };
4 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "pluginsFile": "tests/e2e/plugins/index.js"
3 | }
4 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "@vue/cli-plugin-unit-jest"
3 | };
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "learn-tdd-in-vue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "test:unit": "vue-cli-service test:unit",
9 | "test:e2e": "vue-cli-service test:e2e",
10 | "lint": "vue-cli-service lint"
11 | },
12 | "dependencies": {
13 | "core-js": "^3.6.5",
14 | "vue": "^2.6.11"
15 | },
16 | "devDependencies": {
17 | "@vue/cli-plugin-babel": "~4.5.0",
18 | "@vue/cli-plugin-e2e-cypress": "~4.5.0",
19 | "@vue/cli-plugin-eslint": "~4.5.0",
20 | "@vue/cli-plugin-unit-jest": "~4.5.0",
21 | "@vue/cli-service": "~4.5.0",
22 | "@vue/eslint-config-prettier": "^6.0.0",
23 | "@vue/test-utils": "^1.0.3",
24 | "babel-eslint": "^10.1.0",
25 | "eslint": "^6.7.2",
26 | "eslint-plugin-prettier": "^3.1.3",
27 | "eslint-plugin-vue": "^6.2.2",
28 | "prettier": "^1.19.1",
29 | "vue-template-compiler": "^2.6.11"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/learn-tdd-in/vue/e6204c59aff040bd7b0604530097f55ec4cc0d5c/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/learn-tdd-in/vue/e6204c59aff040bd7b0604530097f55ec4cc0d5c/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/MessageList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 | {{ message }}
5 |
6 |
7 |
8 |
9 |
15 |
--------------------------------------------------------------------------------
/src/components/NewMessageForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
15 |
16 |
17 |
33 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
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");
9 |
--------------------------------------------------------------------------------
/tests/e2e/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ["cypress"],
3 | env: {
4 | mocha: true,
5 | "cypress/globals": true
6 | },
7 | rules: {
8 | strict: "off"
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/tests/e2e/plugins/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | // https://docs.cypress.io/guides/guides/plugins-guide.html
3 |
4 | // if you need a custom webpack configuration you can uncomment the following import
5 | // and then use the `file:preprocessor` event
6 | // as explained in the cypress docs
7 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples
8 |
9 | // /* eslint-disable import/no-extraneous-dependencies, global-require */
10 | // const webpack = require('@cypress/webpack-preprocessor')
11 |
12 | module.exports = (on, config) => {
13 | // on('file:preprocessor', webpack({
14 | // webpackOptions: require('@vue/cli-service/webpack.config'),
15 | // watchOptions: {}
16 | // }))
17 |
18 | return Object.assign({}, config, {
19 | fixturesFolder: "tests/e2e/fixtures",
20 | integrationFolder: "tests/e2e/specs",
21 | screenshotsFolder: "tests/e2e/screenshots",
22 | videosFolder: "tests/e2e/videos",
23 | supportFile: "tests/e2e/support/index.js"
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/tests/e2e/specs/creating_a_message.spec.js:
--------------------------------------------------------------------------------
1 | describe("Creating a message", () => {
2 | it("Displays the message in the list", () => {
3 | cy.visit("/");
4 |
5 | cy.get("[data-test='messageText']").type("New message");
6 |
7 | cy.get("[data-test='sendButton']").click();
8 |
9 | cy.get("[data-test='messageText']").should("have.value", "");
10 |
11 | cy.contains("New message");
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/tests/e2e/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This is will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/tests/e2e/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import "./commands";
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/tests/unit/NewMessageForm.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from "@vue/test-utils";
2 | import NewMessageForm from "@/components/NewMessageForm";
3 |
4 | describe("NewMessageForm", () => {
5 | let wrapper;
6 |
7 | beforeEach(() => {
8 | wrapper = mount(NewMessageForm);
9 | });
10 |
11 | describe("clicking the send button", () => {
12 | beforeEach(() => {
13 | wrapper.find("[data-test='messageText']").setValue("New message");
14 |
15 | wrapper.find("[data-test='sendButton']").trigger("click");
16 | });
17 |
18 | it("clears the text field", () => {
19 | const { value } = wrapper.find("[data-test='messageText']").element;
20 | expect(value).toEqual("");
21 | });
22 |
23 | it("emits the 'send' event", () => {
24 | expect(wrapper.emitted().send[0]).toEqual(["New message"]);
25 | });
26 | });
27 | });
28 |
--------------------------------------------------------------------------------