├── commands ├── dblClick.js ├── enterValue.js ├── trigger.js └── waitFor.js ├── assertions ├── evaluate.js ├── notVisible.js ├── count.js ├── hasHTML.js ├── checked.js ├── focused.js └── attributePresent.js ├── package.json └── README.md /commands/dblClick.js: -------------------------------------------------------------------------------- 1 | exports.command = function (selector) { 2 | return this.moveToElement(selector, 5, 5).doubleClick() 3 | } 4 | -------------------------------------------------------------------------------- /commands/enterValue.js: -------------------------------------------------------------------------------- 1 | exports.command = function (selector, value) { 2 | return this 3 | .clearValue(selector) 4 | .setValue(selector, value) 5 | .trigger(selector, 'keyup', 13) 6 | } 7 | -------------------------------------------------------------------------------- /commands/trigger.js: -------------------------------------------------------------------------------- 1 | exports.command = function (selector, event, keyCode) { 2 | return this.execute(function (selector, event, keyCode) { 3 | var e = document.createEvent('HTMLEvents') 4 | e.initEvent(event, true, true) 5 | if (keyCode) { 6 | e.keyCode = keyCode 7 | } 8 | document.querySelector(selector).dispatchEvent(e) 9 | }, [selector, event, keyCode]) 10 | } 11 | -------------------------------------------------------------------------------- /assertions/evaluate.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (fn, args, msg) { 2 | this.message = 'Testing custom eval' + (msg ? ': ' + msg : '...') 3 | this.expected = true 4 | this.value = function (res) { 5 | return res.value 6 | } 7 | this.pass = function (val) { 8 | return val === this.expected 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(fn, args || [], function (res) { 13 | cb.call(self, res) 14 | }) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assertions/notVisible.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector) { 2 | this.message = 'Testing if element <' + selector + '> is not visible.' 3 | this.expected = false 4 | this.pass = function (val) { 5 | return val === this.expected 6 | } 7 | this.value = function (res) { 8 | return res.value 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.isVisible(selector, function (res) { 13 | cb.call(self, res) 14 | }) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assertions/count.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector, count) { 2 | this.message = 'Testing if element <' + selector + '> has count: ' + count 3 | this.expected = count 4 | this.pass = function (val) { 5 | return val === this.expected 6 | } 7 | this.value = function (res) { 8 | return res.value 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(function (selector) { 13 | return document.querySelectorAll(selector).length 14 | }, [selector], function (res) { 15 | cb.call(self, res) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /assertions/hasHTML.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector, html) { 2 | this.message = 'Testing if element <' + selector + '> has HTML: ' + html 3 | this.expected = html 4 | this.value = function (res) { 5 | return res.value 6 | } 7 | this.pass = function (val) { 8 | return val.indexOf(html) > -1 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(function (selector) { 13 | return document.querySelector(selector).innerHTML 14 | }, [selector], function (res) { 15 | cb.call(self, res) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /assertions/checked.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector, expected) { 2 | this.message = 'Testing if element <' + selector + '> is checked.' 3 | this.expected = expected !== false 4 | this.value = function (res) { 5 | return res.value 6 | } 7 | this.pass = function (val) { 8 | return val === this.expected 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(function (selector) { 13 | return document.querySelector(selector).checked 14 | }, [selector], function (res) { 15 | cb.call(self, res) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /commands/waitFor.js: -------------------------------------------------------------------------------- 1 | var util = require('util') 2 | var events = require('events') 3 | 4 | var waitFor = function () { 5 | events.EventEmitter.call(this) 6 | } 7 | 8 | util.inherits(waitFor, events.EventEmitter) 9 | 10 | waitFor.prototype.command = function (ms, cb) { 11 | var self = this 12 | 13 | ms = ms || 1000 14 | 15 | setTimeout(function () { 16 | // if we have a callback, call it right before the complete event 17 | if (cb) { 18 | cb.call(self.client.api) 19 | } 20 | 21 | self.emit('complete') 22 | }, ms) 23 | 24 | return this 25 | } 26 | 27 | module.exports = waitFor 28 | -------------------------------------------------------------------------------- /assertions/focused.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector, expected) { 2 | this.message = 'Testing if element <' + selector + '> is focused.' 3 | this.expected = expected !== false 4 | this.value = function (res) { 5 | return res.value 6 | } 7 | this.pass = function (val) { 8 | return val === this.expected 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(function (selector) { 13 | return document.querySelector(selector) === document.activeElement 14 | }, [selector], function (res) { 15 | cb.call(self, res) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nightwatch-helpers", 3 | "version": "1.2.0", 4 | "description": "custom assertions and commands for easier nightwatch tests", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/yyx990803/nightwatch-helpers.git" 9 | }, 10 | "keywords": [ 11 | "nightwatch", 12 | "e2e", 13 | "testing" 14 | ], 15 | "author": "Evan You", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/yyx990803/nightwatch-helpers/issues" 19 | }, 20 | "homepage": "https://github.com/yyx990803/nightwatch-helpers#readme" 21 | } 22 | -------------------------------------------------------------------------------- /assertions/attributePresent.js: -------------------------------------------------------------------------------- 1 | exports.assertion = function (selector, attr) { 2 | this.message = 'Testing if element <' + selector + '> has attribute ' + attr + '.' 3 | this.expected = true 4 | this.value = function (res) { 5 | return res.value 6 | } 7 | this.pass = function (val) { 8 | return val === this.expected 9 | } 10 | this.command = function (cb) { 11 | var self = this 12 | return this.api.execute(function (selector, attr) { 13 | return document.querySelector(selector).hasAttribute(attr) 14 | }, [selector, attr], function (res) { 15 | cb.call(self, res) 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nightwatch-helpers 2 | 3 | Custom assertions and commands for easier Nightwatch tests. 4 | 5 | ## Usage 6 | 7 | ``` bash 8 | npm install nightwatch-helpers --save-dev 9 | ``` 10 | 11 | In your Nightwatch config: 12 | 13 | ``` json 14 | { 15 | "custom_commands_path": ["node_modules/nightwatch-helpers/commands"], 16 | "custom_assertions_path": ["node_modules/nightwatch-helpers/assertions"] 17 | } 18 | ``` 19 | 20 | ## What's Included 21 | 22 | ### Assertions 23 | 24 | - count(selector, count) 25 | 26 | - attributePresent(selector, attr) 27 | 28 | - evaluate(fn, [args], [message]) 29 | 30 | - checked(selector, expected) 31 | 32 | - focused(selector, expected) 33 | 34 | - hasHTML(selector, html) 35 | 36 | - notVisible(selector) 37 | 38 | ### Commands 39 | 40 | - dblClick(selector) 41 | 42 | - waitFor(duration) 43 | 44 | - trigger(selector, event, [keyCode]) 45 | 46 | - enterValue(selector, value) 47 | --------------------------------------------------------------------------------