お疲れ様です。@naokiurです。
Selenideを使ってPageObjectをやったことはありましたが、
Vue.jsを使っている兼ね合いで、
Nightwatch.jsでPageObject
を試しました。
環境
- MacBook Pro (Retina 13-inch、Early 2015)
- OS X El Capitan 10.13.6
- node v8.12.0
- npm 6.4.1
実施したこと
簡単な、 入力して内容を表示する
みたいな画面を用意して、
それに対してテストコードを書きました。
上のテキストボックスに値を入れて、
send
をクリックすると、
下のテキストボックスに反映される、というものです。
自分で言うのもアレですが、
なんとも陳腐な画面です。
画面とテストコードは以下です。
テスト対象画面
TestTarget.vue
<template>
<div>
<section>
<input type="text" name="inputData" v-model="inputData" placeholder="please enter some test!" />
</section>
<section>
<input type="button" value="send" @click="send" />
</section>
<section>
<input type="text" name="resultData" :value="result" />
</section>
</div>
</template>
<script>
export default {
name: 'testTarget',
data () {
return {
inputData: '',
result: 'before'
}
},
methods: {
send: function () {
this.result = this.inputData
}
}
}
</script>
<style scoped>
</style>
テストコード
test.js
module.exports = {
'input test': function (browser) {
const targetPage = browser.page.testTargetPage()
targetPage.navigate()
.assert.visible('@inputData')
.setValue('@inputData', 'test')
.send()
.assert.value('@resultData', 'test')
browser.end()
}
}
testTargetPage.js
const pageCommands = {
send: function () {
return this.waitForElementVisible('@sendButton', 1000)
.click('@sendButton')
}
}
module.exports = {
commands: [pageCommands],
url: function () {
return this.api.globals.devServerURL
},
elements: {
inputData: {
selector: 'input[name=inputData]'
},
sendButton: {
selector: 'input[type=button]'
},
resultData: {
selector: 'input[name=resultData]'
}
}
}
nightwatch.conf.js
require('babel-register')
var config = require('../../config')
module.exports = {
src_folders: ['test/e2e/specs'],
output_folder: 'test/e2e/reports',
custom_assertions_path: ['test/e2e/custom-assertions'],
page_objects_path: ['test/e2e/pageObjects'],
selenium: {
start_process: true,
server_path: require('selenium-server').path,
host: '127.0.0.1',
port: 4444,
cli_args: {
'webdriver.chrome.driver': require('chromedriver').path
}
},
test_settings: {
default: {
selenium_port: 4444,
selenium_host: 'localhost',
silent: true,
globals: {
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
}
},
chrome: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true
}
},
firefox: {
desiredCapabilities: {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
}
}
}
}
ディレクトリ構成
project_root
|- src
|- page
|- TestTarget.vue
|- test
|- e2e
|- pageObjects
|- testTargetPage.js
|- specs
|- test.js
|- nightwatch.conf.js
ハマったところ
-
.assert.visible('@inputData')
が失敗する!-
navigate()
を忘れていて、そもそもアクセスしていなかった
-
- 公式の通りに、
testTargetPage.js
にcommandを書いたけれど、this.waitForElementVisible is not function
が発生する!- https://github.com/nightwatchjs/nightwatch/issues/1629 と同事象でした。ディレクトリ構成がいかんかったです。
結果
- PageObjectパターンを反映させることにより、テストコードをたくさん書いたあと、DOMの構成が変わっても、PageObjectだけ書き換えればよくなりました。
- Commandを作成して置くことにより、テストコードがスッキリしました。
- サンプルの画面だと、シンプルすぎて良さがわかりにくいかもしれませんが、もっと色々やる画面ならば、良さが分かる、と期待しています。