撰寫 End-to-End Testing 測試程式的第一步就是抓到網頁的元素,而定位網頁元素有兩種方法「CSS Selector」和「Xpath」,以下使用 CSS Selector。
本系列文章皆使用這個專案,可以拉下來玩玩;有什麼問題都可以提出 issue。
本專案檔案結構如下所示。
nightwatch101
├── custom_assertions(客製化斷言)
├── custom_commands(客製化指令)
├── page_objects(網頁物件)
├── reports(測試報告)
├── test/e2e(測試程式碼放置的位置)
| ├── class/testSubCategory.js
| └── ...
├── globals.js(外部全域設定)
├── nightwatch.conf.js(設定檔)
└── package.json
待之後的篇章會詳述專案中的各個功能設定,在這裡我們先關注 testSubCategory.js 這隻檔案,它用來檢測露天拍賣的子分類頁,來看看下面這個範例吧。
這個範例在展示露天拍賣的子分類頁使用 CSS Selector 定位網頁元素,然後斷言,動作列舉如下
http://class.ruten.com.tw/category/sub00.php?c=00080001
。<body>
這個元素是否出現。.rt-header-not-loaded
是否可見。.rt-category-menu:first-child
的右上方 5px 位置。.rt-category-menu-list-wrap
是否可見。.rt-subcategory-list-item
個數為 24 個。.count()
是一個客製化斷言指令,之後會再說明。#search_input
的屬性 name 的資料,並比對其值是否為「k」。#search_input
的 tag name 的資料,並比對其值是否為「input」。.rt-site-search-button-name
的文字,並比對其值是否為「搜尋」。#search_input
的 CSS line-height 的值,並比對其值是否為「27px」。.rt-site-search-submit
的寬高,並比對其寬是否為「75px」,其高是否為「27px」。.search_input
內的值。#search_input
欄位輸入字串「Pusheen」。#search_input
欄位值,並比對其值是否為「Pusheen」。.rt-site-search-submit
這個送出按鈕。http://find.ruten.com.tw/
。範例程式碼如下。
module.exports = {
'Demo Ruten SubCategory Page': browser => {
browser
// 打開網頁
.url('http://class.ruten.com.tw/category/sub00.php?c=00080001')
// 等待 1 秒,確認 <body> 這個元素是否出現
.waitForElementVisible('body', 1000)
// 取得網頁標題
.getTitle(function(title) {
// 確認取得的資料型別是否為字串
this.assert.equal(typeof title, 'string');
// 確認內容是否為"DC數位相機 - 露天拍賣"
this.assert.equal(title, 'DC數位相機 - 露天拍賣');
})
// 確認元素 ".rt-header-not-loaded" 是否可見
.isVisible('.rt-header-not-loaded', result => {
browser.assert.equal(result.value, true);
})
// 移動到 ".rt-category-menu:first-child" 的右上方 5px 位置
.moveToElement('.rt-category-menu:first-child', 5, 5)
// 確認元素 ".rt-category-menu-list-wrap" 是否可見
.isVisible('.rt-category-menu-list-wrap')
// 確認元素 ".rt-subcategory-list-item" 個數為 24 個
.assert.count('.rt-subcategory-list-item', 24)
// 取得元素 "#search_input" 的屬性 name 的資料,並比對其值是否為 "k"
.getAttribute('#search_input', 'name', function(result) {
this.assert.equal(result.value, 'k');
})
// 取得元素 "#search_input" 的 tag name 是否為 "input"
.getTagName('#search_input', function(result) {
this.assert.equal(result.value, 'input');
})
// 取得元素 ".rt-site-search-button-name" 的文字,並比對是否為 "搜尋"
.getText('.rt-site-search-button-name', result => {
browser.assert.equal(result.value, '搜尋')
})
// 取得元素 "#search_input" 的 CSS line-height 的值,並比對是否為 "27px"
.getCssProperty("#search_input", "line-height", function(result) {
this.assert.equal(result.value, '27px');
})
// 取得元素 ".rt-site-search-submit" 的寬高,並比對其寬是否為 75px,其高是否為 27px
.getElementSize('.rt-site-search-submit', result => {
browser.assert.equal(result.value.width, 75);
browser.assert.equal(result.value.height, 27);
})
// 清除元素 ".search_input" 的值
.clearValue('#search_input')
// 在元素 "#search_input" 欄位輸入字串 "Pusheen"
.setValue('#search_input', 'Pusheen')
// 取得元素 "#search_input" 欄位值,並比對其值是否為 "Pusheen"
.getValue("#search_input", function(result) {
this.assert.equal(result.value, 'Pusheen');
})
// 點擊送出按鈕
.click('.rt-site-search-submit')
// 確定網址是否包含 "http://find.ruten.com.tw/"
.assert.urlContains('http://find.ruten.com.tw/')
// 結束 session,關閉瀏覽器
.end()
}
}
完整測試程式碼請見這裡。
執行測試程式。
nightwatch ./test/e2e/class/testSubCategory.js
左上角會看到瀏覽器被 webdriver 控制的提示訊息。
顯示測試報告-通過所有的項目。
下一篇來看 使用 Xpath 定位網頁元素。
網誌版。