昨天,我們為了讓大家更加了解 Cypress 的語法以及要如何攥寫 E2E 測試,所以開始規劃為 Vue.js • TodoMVC 攥寫 E2E 測試,列出了我們要測試的內容,也實際地為了第一個 case 攥寫測試程式。
大家可以透過連結自由操作一下,會對於接下來的測試例子更佳有感!
詳細完整的內容,就請大家直接查看昨天的文章吧!那我們就馬上開始今天的內容!
在實際攥寫 Case 2 之前,先帶大家看一下程式碼的樣子以及額外宣告的變數
describe('Todo MVC', () => {
const selectors = {
main: '.main',
footer: '.footer',
todoItems: '.todo-list .todo',
newTodo: '.new-todo',
lastOne: '.todo-list .todo:last-child'
}
const TODO_ITEM_ONE = 'Item 1'
const TODO_ITEM_TWO = 'Item 2'
beforeEach(() => {
cy.visit('https://todomvc.com/examples/vue')
})
context('Case 1: Initial State', () => {
it('Case 1-1: start with zero todo item', () => {
cy.get(selectors.todoItems).should('have.length', 0)
})
it('Case 1-2: hide .main and .footer', () => {
cy.get(selectors.main).should('not.be.visible')
cy.get(selectors.footer).should('not.be.visible')
})
})
context('Case 2: New Todo', () => {
// ...
})
context('Case 3: Edit Todo', () => {
// ...
})
})
context('Case 2: New Todo', () => {
it('Case 2-1: create items', () => {
// create first item
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.todoItems)
.eq(0)
.find('label')
.should('contain', TODO_ITEM_ONE)
// create second item
cy.get(selectors.newTodo).type(`${TODO_ITEM_TWO}{enter}`)
cy.get(selectors.todoItems)
.eq(1)
.find('label')
.should('contain', TODO_ITEM_TWO)
cy.get(selectors.todoItems).should('have.length', 2)
})
it('Case 2-2: append new items to the bottom of the list', () => {
const TODO_ITEM_LAST_ONE = 'Item Last One'
for (let i = 0; i < 10; i++) {
cy.get(selectors.newTodo).type(`Item ${i}{enter}`)
}
cy.get(selectors.newTodo).type(`${TODO_ITEM_LAST_ONE}{enter}`)
cy.get(selectors.lastOne)
.find('label')
.should('contain', TODO_ITEM_LAST_ONE)
})
it('Case 2-3: clear input text after an item is added', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.newTodo).should('have.text', '')
})
it('Case 2-4: show .main and .footer when items added', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.main).should('be.visible')
cy.get(selectors.footer).should('be.visible')
})
})
語法說明:
type(): 輸入文字至 DOM 中,不過傳給 type() 的字串可能包含特殊字符,這些特殊字符是用來表示在輸入文字期間發出的事件,例如此處的 {enter} 即表示按下 enter
鍵,又或者是 {selectall} 表示選取輸入的文字。(更完整的列表可參考此文件)
eq(): 取得元素陣列中特定 index 的 DOM 元素,不過特別的是 index 可以為負值,表示從尾巴開始在元素陣列中查找元素。
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
cy.get('li').eq(0).should('contain', '1')
cy.get('li').eq(1).should('contain', '2')
cy.get('li').eq(-1).should('contain', '5')
cy.get('li').eq(-2).should('contain', '4')
find(): 從特定選擇器的元素後代開始尋找特定的元素。
// success
cy.get('.todo-list .todo:last-child').find('label')
// error
cy.find('.todo-list .todo:last-child label')
context('Case 3: Edit Todo', () => {
it('Case 3-1: save edits on blur', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.todoItems)
.eq(0)
.find('label')
.should('contain', TODO_ITEM_ONE)
.dblclick()
cy.get(selectors.todoItems)
.eq(0)
.find('.edit')
.type('{selectall}{backspace}') // same as .clear()
.type(`${TODO_ITEM_TWO}`)
.blur()
cy.get(selectors.todoItems)
.eq(0)
.find('label')
.should('contain', TODO_ITEM_TWO)
})
it('Case 3-2: remove the item if an empty text was entered', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.todoItems)
.eq(0)
.find('label')
.should('contain', TODO_ITEM_ONE)
.dblclick()
cy.get(selectors.todoItems)
.eq(0)
.find('.edit')
.clear() // same as .type('{selectall}{backspace}')
.blur()
cy.get(selectors.todoItems).should('have.length', 0)
})
})
語法說明:
'{selectall}{backspace}'
來達到選取後按下刪除鍵,不過我們也可以直接使用 clear() 來達到同樣的功能。今天的分享就到這邊,如果大家對我分享的內容有興趣歡迎點擊追蹤 & 訂閱系列文章,如果對內容有任何疑問,或是文章內容有錯誤,都非常歡迎留言討論或指教的!
我們明天見!
Hello, 想問一下 2-3 部分
it('Case 2-3: clear input text after an item is added', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}{enter}`)
cy.get(selectors.newTodo).should('have.text', '')
})
我想把它改成『輸入完後不要點擊 Enter,確認我所輸入的值是不是我所輸入的』
it('Case 2-3: clear input text after an item is added', () => {
cy.get(selectors.newTodo).type(`${TODO_ITEM_ONE}`)
cy.get(selectors.newTodo).should('have.text', TODO_ITEM_ONE)
})
會出現錯誤,因為他認為是空值,是不是應該要使用 have.value 來確認值才是呢?