Last active
October 14, 2020 13:15
-
-
Save padcom/759565f374f08b45e02065e789e6806b to your computer and use it in GitHub Desktop.
Testing with Cypress (https://youtu.be/NJpB047yp9s)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Todo</title> | |
<script src="https://unpkg.com/vue"></script> | |
<style> | |
.todo { | |
cursor: pointer; | |
} | |
.completed { | |
text-decoration: line-through; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<h1>Todos</h1> | |
<add-todo-form @add-todo="addTodo"></add-todo-form> | |
<todo-list :todos="todos" @toggle="toggle" @remove="remove"></todo-list> | |
</div> | |
<template id="add-todo-form"> | |
<div class="add-todo-form"> | |
<label> | |
Todo | |
<input v-model="text"> | |
<button @click="addTodo">Add</button> | |
</label> | |
</div> | |
</template> | |
<script> | |
Vue.component('add-todo-form', { | |
template: '#add-todo-form', | |
data() { | |
return { | |
text: '' | |
} | |
}, | |
methods: { | |
addTodo() { | |
this.$emit('add-todo', this.text) | |
this.text = '' | |
} | |
} | |
}) | |
</script> | |
<template id="todo-list"> | |
<ul class="todos"> | |
<todo-item v-for="todo in todos" :key="todo.id" :todo="todo" v-on="$listeners"> | |
</todo-item> | |
</ul> | |
</template> | |
<script> | |
Vue.component('todo-list', { | |
template: '#todo-list', | |
props: { | |
todos: { type: Array, required: true } | |
} | |
}) | |
</script> | |
<template id="todo-item"> | |
<li :class="{ todo: true, completed: todo.completed }" @click="$emit('toggle', todo)"> | |
<span class="todo-text">{{ todo.text }}</span> | |
<button @click="$emit('remove', todo)" data-test="remove-todo">X</button> | |
</li> | |
</template> | |
<script> | |
Vue.component('todo-item', { | |
template: '#todo-item', | |
props: { | |
todo: { type: Object, required: true } | |
} | |
}) | |
</script> | |
<script> | |
new Vue({ | |
el: '#app', | |
data: { | |
todos: [{ | |
id: 1, text: 'Create cypress tests', completed: false | |
}] | |
}, | |
methods: { | |
addTodo(text) { | |
this.todos.push({ | |
id: this.todos.reduce((acc, item) => acc <= item.id ? item.id + 1 : acc, 0), | |
text, | |
completed: false | |
}) | |
}, | |
toggle(todo) { | |
todo.completed = !todo.completed | |
}, | |
remove(todo) { | |
this.todos = this.todos.filter(item => item.id !== todo.id) | |
} | |
} | |
}) | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "tests", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"cypress:open": "cypress open" | |
}, | |
"keywords": [], | |
"author": "", | |
"license": "ISC", | |
"devDependencies": { | |
"cypress": "^4.7.0", | |
"uuid": "^8.1.0" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference types="cypress" /> | |
import { v4 as uuid } from 'uuid' | |
class Wrapper { | |
/** | |
* @param {Cypress.Chainable<JQuery<HTMLElement>>} root | |
*/ | |
constructor(root) { | |
this.id = uuid() | |
root.as(this.id) | |
} | |
get root() { | |
return cy.get(`@${this.id}`) | |
} | |
} | |
class AddTodoFormWrapper extends Wrapper { | |
get input() { | |
return this.root.find('input') | |
} | |
get button() { | |
return this.root.find('button') | |
} | |
addTodo(text) { | |
this.input.clear().type(text) | |
this.button.click() | |
} | |
} | |
class TodoItemWrapper extends Wrapper { | |
get text() { | |
return this.root.find('.todo-text') | |
} | |
get removeButton() { | |
return this.root.find('[data-test="remove-todo"]') | |
} | |
remove() { | |
this.removeButton.click() | |
} | |
toggle() { | |
this.text.click() | |
return this | |
} | |
shouldBeCompleted() { | |
this.root.should('have.class', 'completed') | |
return this | |
} | |
shouldNotBeCompleted() { | |
this.root.should('not.have.class', 'completed') | |
return this | |
} | |
} | |
class TodoListWrapper extends Wrapper { | |
get todos() { | |
return this.root.find('.todo') | |
} | |
getLastTodo() { | |
return new TodoItemWrapper(this.todos.last()) | |
} | |
} | |
describe('Todo list', () => { | |
/** @type {TodoListWrapper} */ | |
let todoList | |
/** @type {AddTodoFormWrapper} */ | |
let addTodoForm | |
beforeEach(() => { | |
cy.visit('http://localhost:8080') | |
todoList = new TodoListWrapper(cy.get('.todos')) | |
addTodoForm = new AddTodoFormWrapper(cy.get('.add-todo-form')) | |
}) | |
it('will create a new todo', () => { | |
todoList.todos.should('have.length', 1) | |
addTodoForm.addTodo('Hello, world!') | |
todoList.todos.should('have.length', 2) | |
}) | |
it('will remove a todo', () => { | |
addTodoForm.addTodo('Hello, world!') | |
todoList.todos.should('have.length', 2) | |
todoList.getLastTodo().remove() | |
todoList.todos.should('have.length', 1) | |
}) | |
it('will toggle a todo', () => { | |
addTodoForm.addTodo('Hello, world!') | |
todoList.getLastTodo() | |
.shouldNotBeCompleted() | |
.toggle() | |
.shouldBeCompleted() | |
.toggle() | |
.shouldNotBeCompleted() | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment