
撰寫 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 定位網頁元素。
網誌版。