Skip to content

Commit 90ee74e

Browse files
committed
add nightwatch tests
1 parent 8a17b58 commit 90ee74e

File tree

12 files changed

+1375
-73
lines changed

12 files changed

+1375
-73
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.DS_Store
22
node_modules
33
/dist
4+
logs/
45

56

67
# local env files

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"serve": "vue-cli-service serve",
77
"build": "vue-cli-service build",
88
"test:unit": "vue-cli-service test:unit",
9+
"test:e2e": "vue-cli-service test:e2e",
910
"lint": "vue-cli-service lint"
1011
},
1112
"dependencies": {
@@ -16,17 +17,20 @@
1617
"vuex": "^4.0.0-0"
1718
},
1819
"devDependencies": {
20+
"@babel/eslint-parser": "^7.21.0",
1921
"@vue/cli-plugin-babel": "~5.0.8",
22+
"@vue/cli-plugin-e2e-nightwatch": "~5.0.0",
2023
"@vue/cli-plugin-eslint": "~5.0.8",
2124
"@vue/cli-plugin-router": "~5.0.8",
2225
"@vue/cli-plugin-unit-jest": "~5.0.8",
2326
"@vue/cli-plugin-vuex": "~5.0.8",
2427
"@vue/cli-service": "~5.0.8",
2528
"@vue/compiler-sfc": "^3.0.0",
2629
"@vue/test-utils": "^2.0.0-0",
27-
"@babel/eslint-parser": "^7.21.0",
30+
"chromedriver": "112",
2831
"eslint": "^8.38.0",
2932
"eslint-plugin-vue": "^9.11.0",
33+
"geckodriver": "^3.0.1",
3034
"typescript": "~5.0.4",
3135
"vue-jest": "^5.0.0-0",
3236
"vue3-jest": "^27.0.0-alpha.1"

src/App.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<button @click="increment">Click</button>
33
<div v-if="count % 2 === 0">Count: {{ count }}. Count is even.</div>
44
<div v-if="count % 2 !== 0">Count: {{ count }}. Count is odd.</div>
5-
6-
<div>PostID: {{ postId }}</div>
5+
<div id="pid">PostID: {{ postId }}</div>
76
</template>
87

98
<script>

tests/e2e/.eslintrc.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
rules: {
3+
'no-unused-expressions': 'off'
4+
}
5+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* A custom Nightwatch assertion. The assertion name is the filename.
3+
*
4+
* Example usage:
5+
* browser.assert.elementCount(selector, count)
6+
*
7+
* For more information on custom assertions see:
8+
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions
9+
*
10+
*
11+
* @param {string|object} selectorOrObject
12+
* @param {number} count
13+
*/
14+
15+
exports.assertion = function elementCount (selectorOrObject, count) {
16+
let selector
17+
18+
// when called from a page object element or section
19+
if (typeof selectorOrObject === 'object' && selectorOrObject.selector) {
20+
// eslint-disable-next-line prefer-destructuring
21+
selector = selectorOrObject.selector
22+
} else {
23+
selector = selectorOrObject
24+
}
25+
26+
this.message = `Testing if element <${selector}> has count: ${count}`
27+
this.expected = count
28+
this.pass = val => val === count
29+
this.value = res => res.value
30+
function evaluator (_selector) {
31+
return document.querySelectorAll(_selector).length
32+
}
33+
this.command = cb => this.api.execute(evaluator, [selector], cb)
34+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* A very basic Nightwatch custom command. The command name is the filename and the
3+
* exported "command" function is the command.
4+
*
5+
* Example usage:
6+
* browser.customExecute(function() {
7+
* console.log('Hello from the browser window')
8+
* });
9+
*
10+
* For more information on writing custom commands see:
11+
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
12+
*
13+
* @param {*} data
14+
*/
15+
exports.command = function command (data) {
16+
// Other Nightwatch commands are available via "this"
17+
18+
// .execute() inject a snippet of JavaScript into the page for execution.
19+
// the executed script is assumed to be synchronous.
20+
//
21+
// See https://nightwatchjs.org/api/execute.html for more info.
22+
//
23+
this.execute(
24+
// The function argument is converted to a string and sent to the browser
25+
function (argData) { return argData },
26+
27+
// The arguments for the function to be sent to the browser are specified in this array
28+
[data],
29+
30+
function (result) {
31+
// The "result" object contains the result of what we have sent back from the browser window
32+
console.log('custom execute result:', result.value)
33+
}
34+
)
35+
36+
return this
37+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* A basic Nightwatch custom command
3+
* which demonstrates usage of ES6 async/await instead of using callbacks.
4+
* The command name is the filename and the exported "command" function is the command.
5+
*
6+
* Example usage:
7+
* browser.openHomepage();
8+
*
9+
* For more information on writing custom commands see:
10+
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
11+
*
12+
*/
13+
module.exports = {
14+
command: async function () {
15+
// Other Nightwatch commands are available via "this"
16+
// .init() simply calls .url() command with the value of the "launch_url" setting
17+
this.init()
18+
this.waitForElementVisible('#app')
19+
20+
const result = await this.elements('css selector', '#app ul')
21+
this.assert.strictEqual(result.length, 3)
22+
}
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* A class-based Nightwatch custom command which is a variation of the openHomepage.js command.
3+
* The command name is the filename and class needs to contain a "command" method.
4+
*
5+
* Example usage:
6+
* browser.openHomepageClass();
7+
*
8+
* For more information on writing custom commands see:
9+
* https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
10+
*
11+
*/
12+
13+
const assert = require('assert')
14+
15+
module.exports = class {
16+
async command () {
17+
// Other Nightwatch commands are available via "this.api"
18+
this.api.init()
19+
this.api.waitForElementVisible('#app')
20+
21+
const result = await this.api.elements('css selector', '#app ul')
22+
assert.strictEqual(result.value.length, 3)
23+
}
24+
}

tests/e2e/globals.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
///////////////////////////////////////////////////////////////////////////////////
2+
// Refer to the entire list of global config settings here:
3+
// https://github.com/nightwatchjs/nightwatch/blob/master/lib/settings/defaults.js#L16
4+
//
5+
// More info on test globals:
6+
// https://nightwatchjs.org/gettingstarted/configuration/#test-globals
7+
//
8+
///////////////////////////////////////////////////////////////////////////////////
9+
10+
module.exports = {
11+
// this controls whether to abort the test execution when an assertion failed and skip the rest
12+
// it's being used in waitFor commands and expect assertions
13+
abortOnAssertionFailure: true,
14+
15+
// this will overwrite the default polling interval (currently 500ms) for waitFor commands
16+
// and expect assertions that use retry
17+
waitForConditionPollInterval: 500,
18+
19+
// default timeout value in milliseconds for waitFor commands and implicit waitFor value for
20+
// expect assertions
21+
waitForConditionTimeout: 5000,
22+
23+
'default': {
24+
/*
25+
The globals defined here are available everywhere in any test env
26+
*/
27+
28+
/*
29+
myGlobal: function() {
30+
return 'I\'m a method';
31+
}
32+
*/
33+
},
34+
35+
'firefox': {
36+
/*
37+
The globals defined here are available only when the chrome testing env is being used
38+
i.e. when running with --env firefox
39+
*/
40+
/*
41+
* myGlobal: function() {
42+
* return 'Firefox specific global';
43+
* }
44+
*/
45+
},
46+
47+
/////////////////////////////////////////////////////////////////
48+
// Global hooks
49+
// - simple functions which are executed as part of the test run
50+
// - take a callback argument which can be called when an async
51+
// async operation is finished
52+
/////////////////////////////////////////////////////////////////
53+
/**
54+
* executed before the test run has started, so before a session is created
55+
*/
56+
/*
57+
before(cb) {
58+
//console.log('global before')
59+
cb();
60+
},
61+
*/
62+
63+
/**
64+
* executed before every test suite has started
65+
*/
66+
/*
67+
beforeEach(browser, cb) {
68+
//console.log('global beforeEach')
69+
cb();
70+
},
71+
*/
72+
73+
/**
74+
* executed after every test suite has ended
75+
*/
76+
/*
77+
afterEach(browser, cb) {
78+
browser.perform(function() {
79+
//console.log('global afterEach')
80+
cb();
81+
});
82+
},
83+
*/
84+
85+
/**
86+
* executed after the test run has finished
87+
*/
88+
/*
89+
after(cb) {
90+
//console.log('global after')
91+
cb();
92+
},
93+
*/
94+
95+
/////////////////////////////////////////////////////////////////
96+
// Global reporter
97+
// - define your own custom reporter
98+
/////////////////////////////////////////////////////////////////
99+
/*
100+
reporter(results, cb) {
101+
cb();
102+
}
103+
*/
104+
}

tests/e2e/page-objects/homepage.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* A Nightwatch page object. The page object name is the filename.
3+
*
4+
* Example usage:
5+
* browser.page.homepage.navigate()
6+
*
7+
* For more information on working with page objects see:
8+
* https://nightwatchjs.org/guide/working-with-page-objects/
9+
*
10+
*/
11+
12+
module.exports = {
13+
url: '/',
14+
commands: [],
15+
16+
// A page object can have elements
17+
elements: {
18+
appContainer: '#app'
19+
},
20+
21+
// Or a page objects can also have sections
22+
sections: {
23+
app: {
24+
selector: '#app',
25+
26+
elements: {
27+
logo: 'img'
28+
},
29+
30+
// - a page object section can also have sub-sections
31+
// - elements or sub-sections located here are retrieved using the "app" section as the base
32+
sections: {
33+
headline: {
34+
selector: 'h1'
35+
},
36+
37+
welcome: {
38+
// the equivalent css selector for the "welcome" sub-section would be:
39+
// '#app div.hello'
40+
selector: 'div.hello',
41+
42+
elements: {
43+
cliPluginLinks: {
44+
selector: 'ul',
45+
index: 0
46+
}
47+
}
48+
}
49+
}
50+
}
51+
}
52+
}

tests/e2e/specs/test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// For authoring Nightwatch tests, see
2+
// https://nightwatchjs.org/guide
3+
4+
module.exports = {
5+
'default e2e tests': browser => {
6+
browser
7+
.init()
8+
.waitForElementVisible('#app')
9+
.useXpath()
10+
.assert.textContains('//div', 'Count: 0. Count is even')
11+
.click("//button[text()='Click']")
12+
.assert.textContains('//div', 'Count: 1. Count is odd')
13+
.assert.textContains("//div[@id='pid']", "PostID: 1")
14+
.click("//button[text()='Click']")
15+
.assert.textContains('//div', 'Count: 2. Count is even')
16+
.assert.textContains("//div[@id='pid']", "PostID: 2")
17+
.end()
18+
},
19+
}

0 commit comments

Comments
 (0)