In this chapter, we'll be talking about debugging and reporting. Nightwatch gives us the .pause()
method to help us when we need to debug our tests.
This pause
method suspends the test for a given number of milliseconds. If we do not specify how long we want it to pause for, then the test will suspend indefinitely.
I've gone ahead and created two additional page objects, ComplicatedPage.js
and SearchPage.js
.
ComplicatedPage.js
const elements = {
txtSearch: '#s',
btnSearch: '#searchsubmit'
};
const commands = [
{
/**
* Enters the searchTerm into the search feild and then clicks on the search button
*
* @param {String} searchTerm - Term that will be searched for
*/
search(searchTerm){
return this
.setValue('@txtSearch', searchTerm)
.click('@btnSearch')
}
}
];
module.exports = {
elements: elements,
commands: commands,
url: function() {
return `${this.api.launchUrl}/complicated-page/`
}
}
SearchPage.js
const elements = {
post: 'article'
};
const commands = [
];
module.exports = {
elements: elements,
commands: commands,
url: function() {
return `${this.api.launchUrl}/?s`
}
}
Let's review what we'll be doing.
With this test, we'll have some failures because we want to go through how we can debug our tests.
We create our debugging file - debugging.test.js
.
Our test would be "Should find results when searching for 'applitools'". We will ensure that we define our Nightwatch instance. In this case, it's client
. We'll get our two page objects, ComplicatedPage
and SearchPage
.
What we'd want to do first is to navigate to our ComplicatedPage. In our page object, we have defined the url
function that will evaluate our ComplicatedPage, so it's using the base URL and the path to the page, so I can simply say, ComplicatedPage.navigate()
.
Then I'll be on the page and I can use our .search()
method to search for a term.
It accepts our search term, it enters the value into the search field, and then clicks on the search button.
So let's say .search()
and pass in the text that we would like to search for, in this case applitools
.
Then we want to verify
that we're on the search page once it has navigated.
We can simply do so by just verifying we're seeing this /?s
in the url, which would signify that we're on the search results page.
module.exports = {
"Should find results when searching for 'applitools'": (client) => {
const ComplicatedPage = client.page.ComplicatedPage();
const SearchPage = client.page.SearchPage();
ComplicatedPage
.navigate()
.search('applitools')
.verify.urlContains('/?s')
}
};
Once that's verified, let us use SearchPage
to get the text of the articles on that page.
We have an element called post
and it's using "article" as a selector, so we'll call getText()
on @post
to get the results.
Now we'll be able to assert the result
in the callback.
Since we will be asserting two strings, we don't have to access Nightwatch element commands.
We can use the assert native command like equal()
. We want to verify that result.value
equals the article name - "Applitools Bugs and Test Steps".
module.exports = {
"Should find results when searching for 'applitools'": (client) => {
const ComplicatedPage = client.page.ComplicatedPage();
const SearchPage = client.page.SearchPage();
ComplicatedPage
.navigate()
.search('applitools')
.verify.urlContains('/?s')
SearchPage
.getText('@post', (result) => {
client.pause()
client.assert.equal(result.value, 'Applitools Bugs and Test Steps')
});
}
};
Now that we have our test set up, let's go ahead and run this.
npm test -- -t ./tests/debugging.test.js
Let's see if we have any errors.
It failed to evaluate the actual text. Instead, it was expecting "Applitools Bugs and Test Steps" but we got "Applitools Conclusions by Nikolay."
A good way to debug this or to see what's happening - Nightwatch shows where we see the error in the configuration.
We could press command
+ click
to go back to where the error was thrown.
We see that the issue is with this evaluation (client.assert.equal(result.value, 'Applitools Bugs and Test Steps')
) which means our result.value
is not correct.
So - possibly - we need to update our selector.
What we can do - we can say, client.pause()
, and run our test again.
Now our test is paused and we can interact with the page.
When we look at this, we realize that the automation is getting the first article in our list.
But, we are actually verifying the second article. So let's look in HTML to see what we can do to differentiate the second article.
The article has an ID so we will update our page object with the article ID.
That will look like this in SearchPage.js
.
const elements = {
post: '#post-6917'
};
Let us remember to remove the pause or comment it out so we can test again.
We're still getting an error.
As we can see, we did retrieve the second element, but the issue is that because we're using equal
and it's very strict compared to using contains
, it will be looking for the exact value.
So, we're getting a much longer string than what we were expecting.
So what we'd need to do is see how we can narrow down the element to only get the title since you want to verify the title.
Now that the test is paused, we can go ahead and inspect our element again.
This time we'll see how we can target just the title.
So we use the ID of the article, then we see that it has an h2
, or we see that the title is written in h2
, and that is more than good enough for us to only target the title.
We can go back to our test, update our page object in SearchPage.js
.
const elements = {
postTitle: '#post-6917 h2'
};
We will update our test to use @postTitle
instead of @post
now, comment out our pause, kill the session, and try our test again.
module.exports = {
"Should find results when searching for 'applitools'": (client) => {
const ComplicatedPage = client.page.ComplicatedPage();
const SearchPage = client.page.SearchPage();
ComplicatedPage
.navigate()
.search('applitools')
.verify.urlContains('/?s')
SearchPage
.getText('@postTitle', (result) => {
//client.pause()
client.assert.equal(result.value, 'Applitools Bugs and Test Steps')
});
}
};
Now our test passed as expected.
Another good way for us to add debugging capabilities to our Nightwatch suite is that we can go to our configuration - nightwatch.json
- and we can enable screenshots.
So what this will do is tell Nightwatch to take a screenshot when we have failures.
This way, rather than us having to use the pause
function, we can easily go into the screenshots to evaluate what had taken place in the moment of failure.
Let's go ahead and see how we can define that.
Under test_settings
in default
, we can add screenshots
as a key.
Within that, we can specify options. We have enabled
, which is by default disabled - so we'll change that to true.
Also we'll specify on_failure
- we'd like the screenshots to be taken on failure.
Also, there's another field on_error
- we'll leave this one false, but you can set yours to true if you want.
And finally, we'll define the path
in which we'd like to store our screenshots, and this will be relative to the root of our folder - so let's call it screenshots
.
Now test_settings
in nightwatch.json
looks like:
"test_settings": {
"default": {
"screenshots": {
"enabled": true,
"on_failure": true,
"on_error": false,
"path": "screenshots"
},
"launch_url": "https://ultimateqa.com",
"desiredCapabilities": {
"browserName": "chrome"
}
}
}
So what we could do now is remove the 's' in "Applitools Bugs and Test Steps" to break the test. Let's run our test and see what happens.
As you can see, we now have a folder. It's telling you where the screenshot came from - in this case, it came from our debugging test file.
Quiz
The quiz for this chapter can be found in section 8.2