Skip to content

Commit

Permalink
add nightwatch tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-hammant committed Apr 17, 2023
1 parent 8a17b58 commit 90ee74e
Show file tree
Hide file tree
Showing 12 changed files with 1,375 additions and 73 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DS_Store
node_modules
/dist
logs/


# local env files
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint"
},
"dependencies": {
Expand All @@ -16,17 +17,20 @@
"vuex": "^4.0.0-0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.21.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-e2e-nightwatch": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-unit-jest": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"@vue/compiler-sfc": "^3.0.0",
"@vue/test-utils": "^2.0.0-0",
"@babel/eslint-parser": "^7.21.0",
"chromedriver": "112",
"eslint": "^8.38.0",
"eslint-plugin-vue": "^9.11.0",
"geckodriver": "^3.0.1",
"typescript": "~5.0.4",
"vue-jest": "^5.0.0-0",
"vue3-jest": "^27.0.0-alpha.1"
Expand Down
3 changes: 1 addition & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
<button @click="increment">Click</button>
<div v-if="count % 2 === 0">Count: {{ count }}. Count is even.</div>
<div v-if="count % 2 !== 0">Count: {{ count }}. Count is odd.</div>

<div>PostID: {{ postId }}</div>
<div id="pid">PostID: {{ postId }}</div>
</template>

<script>
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
rules: {
'no-unused-expressions': 'off'
}
}
34 changes: 34 additions & 0 deletions tests/e2e/custom-assertions/elementCount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* A custom Nightwatch assertion. The assertion name is the filename.
*
* Example usage:
* browser.assert.elementCount(selector, count)
*
* For more information on custom assertions see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions
*
*
* @param {string|object} selectorOrObject
* @param {number} count
*/

exports.assertion = function elementCount (selectorOrObject, count) {
let selector

// when called from a page object element or section
if (typeof selectorOrObject === 'object' && selectorOrObject.selector) {
// eslint-disable-next-line prefer-destructuring
selector = selectorOrObject.selector
} else {
selector = selectorOrObject
}

this.message = `Testing if element <${selector}> has count: ${count}`
this.expected = count
this.pass = val => val === count
this.value = res => res.value
function evaluator (_selector) {
return document.querySelectorAll(_selector).length
}
this.command = cb => this.api.execute(evaluator, [selector], cb)
}
37 changes: 37 additions & 0 deletions tests/e2e/custom-commands/customExecute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* A very basic Nightwatch custom command. The command name is the filename and the
* exported "command" function is the command.
*
* Example usage:
* browser.customExecute(function() {
* console.log('Hello from the browser window')
* });
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
* @param {*} data
*/
exports.command = function command (data) {
// Other Nightwatch commands are available via "this"

// .execute() inject a snippet of JavaScript into the page for execution.
// the executed script is assumed to be synchronous.
//
// See https://nightwatchjs.org/api/execute.html for more info.
//
this.execute(
// The function argument is converted to a string and sent to the browser
function (argData) { return argData },

// The arguments for the function to be sent to the browser are specified in this array
[data],

function (result) {
// The "result" object contains the result of what we have sent back from the browser window
console.log('custom execute result:', result.value)
}
)

return this
}
23 changes: 23 additions & 0 deletions tests/e2e/custom-commands/openHomepage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* A basic Nightwatch custom command
* which demonstrates usage of ES6 async/await instead of using callbacks.
* The command name is the filename and the exported "command" function is the command.
*
* Example usage:
* browser.openHomepage();
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
*/
module.exports = {
command: async function () {
// Other Nightwatch commands are available via "this"
// .init() simply calls .url() command with the value of the "launch_url" setting
this.init()
this.waitForElementVisible('#app')

const result = await this.elements('css selector', '#app ul')
this.assert.strictEqual(result.length, 3)
}
}
24 changes: 24 additions & 0 deletions tests/e2e/custom-commands/openHomepageClass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* A class-based Nightwatch custom command which is a variation of the openHomepage.js command.
* The command name is the filename and class needs to contain a "command" method.
*
* Example usage:
* browser.openHomepageClass();
*
* For more information on writing custom commands see:
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
*
*/

const assert = require('assert')

module.exports = class {
async command () {
// Other Nightwatch commands are available via "this.api"
this.api.init()
this.api.waitForElementVisible('#app')

const result = await this.api.elements('css selector', '#app ul')
assert.strictEqual(result.value.length, 3)
}
}
104 changes: 104 additions & 0 deletions tests/e2e/globals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
///////////////////////////////////////////////////////////////////////////////////
// Refer to the entire list of global config settings here:
// https://github.com/nightwatchjs/nightwatch/blob/master/lib/settings/defaults.js#L16
//
// More info on test globals:
// https://nightwatchjs.org/gettingstarted/configuration/#test-globals
//
///////////////////////////////////////////////////////////////////////////////////

module.exports = {
// this controls whether to abort the test execution when an assertion failed and skip the rest
// it's being used in waitFor commands and expect assertions
abortOnAssertionFailure: true,

// this will overwrite the default polling interval (currently 500ms) for waitFor commands
// and expect assertions that use retry
waitForConditionPollInterval: 500,

// default timeout value in milliseconds for waitFor commands and implicit waitFor value for
// expect assertions
waitForConditionTimeout: 5000,

'default': {
/*
The globals defined here are available everywhere in any test env
*/

/*
myGlobal: function() {
return 'I\'m a method';
}
*/
},

'firefox': {
/*
The globals defined here are available only when the chrome testing env is being used
i.e. when running with --env firefox
*/
/*
* myGlobal: function() {
* return 'Firefox specific global';
* }
*/
},

/////////////////////////////////////////////////////////////////
// Global hooks
// - simple functions which are executed as part of the test run
// - take a callback argument which can be called when an async
// async operation is finished
/////////////////////////////////////////////////////////////////
/**
* executed before the test run has started, so before a session is created
*/
/*
before(cb) {
//console.log('global before')
cb();
},
*/

/**
* executed before every test suite has started
*/
/*
beforeEach(browser, cb) {
//console.log('global beforeEach')
cb();
},
*/

/**
* executed after every test suite has ended
*/
/*
afterEach(browser, cb) {
browser.perform(function() {
//console.log('global afterEach')
cb();
});
},
*/

/**
* executed after the test run has finished
*/
/*
after(cb) {
//console.log('global after')
cb();
},
*/

/////////////////////////////////////////////////////////////////
// Global reporter
// - define your own custom reporter
/////////////////////////////////////////////////////////////////
/*
reporter(results, cb) {
cb();
}
*/
}
52 changes: 52 additions & 0 deletions tests/e2e/page-objects/homepage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* A Nightwatch page object. The page object name is the filename.
*
* Example usage:
* browser.page.homepage.navigate()
*
* For more information on working with page objects see:
* https://nightwatchjs.org/guide/working-with-page-objects/
*
*/

module.exports = {
url: '/',
commands: [],

// A page object can have elements
elements: {
appContainer: '#app'
},

// Or a page objects can also have sections
sections: {
app: {
selector: '#app',

elements: {
logo: 'img'
},

// - a page object section can also have sub-sections
// - elements or sub-sections located here are retrieved using the "app" section as the base
sections: {
headline: {
selector: 'h1'
},

welcome: {
// the equivalent css selector for the "welcome" sub-section would be:
// '#app div.hello'
selector: 'div.hello',

elements: {
cliPluginLinks: {
selector: 'ul',
index: 0
}
}
}
}
}
}
}
19 changes: 19 additions & 0 deletions tests/e2e/specs/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// For authoring Nightwatch tests, see
// https://nightwatchjs.org/guide

module.exports = {
'default e2e tests': browser => {
browser
.init()
.waitForElementVisible('#app')
.useXpath()
.assert.textContains('//div', 'Count: 0. Count is even')
.click("//button[text()='Click']")
.assert.textContains('//div', 'Count: 1. Count is odd')
.assert.textContains("//div[@id='pid']", "PostID: 1")
.click("//button[text()='Click']")
.assert.textContains('//div', 'Count: 2. Count is even')
.assert.textContains("//div[@id='pid']", "PostID: 2")
.end()
},
}
Loading

0 comments on commit 90ee74e

Please sign in to comment.