Nightwatch JS doesn’t provide any out of the box solution for API testing. Hence we would need some external node packages and then use them in our tests.
Although there are a number of ways to implement API Tests in Nightwatch, the steps mentioned in this Github thread are very simple and straight-forward. Hence for this tutorial, we will be referencing this. Also, in this tutorial, we will only cover GET and POST requests, but you can always modify the existing code and implement other request types.
Step 1: Install the request node package.
1 | npm install request -D |
Once installed, this should be reflected in your package.json file.
Step 2: Now, create a commands folder in the root of your project and create two files inside it – apiGet.js & apiPost.js.
Step 3: The two files apiGet.js and apiPost.js will be used as custom commands, hence we will update our Nightwatch.conf.js file with the location of these files.
1 | custom_commands_path: "./commands", |
Step 4: In apiGet.js file copy the below code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var util = require('util'); var events = require('events'); function apiGet () {} util.inherits(apiGet, events.EventEmitter); apiGet.prototype.command = function(apiUrl, success) { var request = require("request"); request.get(apiUrl, function (error, response) { if (error) { console.log(error); return; } success(response); this.emit('complete'); }.bind(this)); }; module.exports = apiGet; |
In the apiPost.js file, copy the below code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var util = require('util'); var events = require('events'); function apiPost () {} util.inherits(apiPost, events.EventEmitter); apiPost.prototype.command = function (apiUrl, postBody, postHeaders, postAuth, success) { var request = require("request"); var options = { uri: apiUrl, method: "POST", json: postBody }; if (postHeaders !== undefined) { options.headers = postHeaders; } if (postAuth !== undefined) { options.auth = postAuth; } request(options, function (error, response) { if (error) { console.log(error); return; } success(response); this.emit('complete'); }.bind(this)); }; module.exports = apiPost; |
Step 5: Now, we will write our API test containing both GET and POST requests to different endpoints and then validating the status codes along with the response body.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | module.exports = { before: function (browser) { //Declaring Global Timeout browser.globals.waitForConditionTimeout = 7000 }, 'API Testing - GET': function (browser) { var apiUrl = 'https://dog.ceo/api/breeds/list/all' browser.apiGet(apiUrl, function (response) { var data = JSON.parse(response.body) browser.assert.equal(response.statusCode, '200') browser.assert.equal(data.message.australian, 'shepherd') }) }, 'API Testing - POST': function (browser) { var apiUrl = 'https://reqres.in/api/users' var postData = {'name':'Testersdock'} browser.apiPost(apiUrl, postData, null, null, function (response) { browser.assert.equal(response.statusCode, '201') browser.assert.equal(response.body.name, 'Testersdock') }) }, after: function (browser) { browser.end() } } |
Let’s deep dive into the code further –
1 2 3 4 5 6 7 8 | 'API Testing - GET': function (browser) { var apiUrl = 'https://dog.ceo/api/breeds/list/all' browser.apiGet(apiUrl, function (response) { var data = JSON.parse(response.body) browser.assert.equal(response.statusCode, '200') browser.assert.equal(data.message.australian, 'shepherd') }) } |
We are passing the api url to the apiGet function and then asserting the status code as ‘200’ and checking that the response body has the text ‘shepherd’. Before checking the presence of text in the response body, we have to make sure that the response body is parsed using JSON.parse().
1 2 3 4 5 6 7 8 | 'API Testing - POST': function (browser) { var apiUrl = 'https://reqres.in/api/users' var postData = { 'name': 'Testersdock' } browser.apiPost(apiUrl, postData, null, null, function (response) { browser.assert.equal(response.statusCode, '201') browser.assert.equal(response.body.name, 'Testersdock') }) }, |
The apiPost function takes up four parameters – API url, the request body, request headers and Oauth. Since for our request we don’t have headers and OAuth we are passing them as null from our test. After hitting the request endpoint we are asserting that the response status code is ‘201’ and the response body contains the text ‘Testersdock’.
Step 6: After Execution:
Do check out 🙂
Github:Â https://github.com/alapanme/NightwatchJS
All Nightwatch JS Articles: https://testersdock.com/nightwatch-js-tutorial/
Can we put UI tests, API tests in the tests folder or can we create two differ folder one for UI automation and one for API, if yes can you pls tell me how can we can collaborate?
You can write the tests as you like. But a good practice would be to always maintain different folders for UI and API tests.
How can we use a json inside our “postData” to send it in a POST request?
This worked incredibly well, thank you!