In this chapter, we'll be writing and running tests. Since you have gone through the Nightwatch APIs, now we can put everything together.
Let's start off by creating our test file - let's call it forms.test.js
.
We'll begin by defining our module. In this case, it's actually our test suite.
So let's talk about the tests that we will be executing.
We're going to use this same form page that we've been using.
We are going to enter some name - say the name is "John Doe".
We're going to enter some text.
We're going to click Submit, and then we're going to assert that we see a success message and that will be our test.
Let's write our test named "Should successfully fill out the left form".
Always remember to define our client
in our tests.
So our first line of code will be client.url()
because we want to navigate to the form page.
What we can do - we can access the base URL that we had defined in our nightwatch.json
config - so that launch_url
is the base URL and we don't necessarily have to write out the entire URL.
We can use a JavaScript string literal to say ${client.launch_url}
and because this maps back to what we had defined in our configuration file, we can just append the last part of our URL and this will navigate to that page as expected.
module.exports = {
"Should successfully fill out the left form": (client) =>{
client
.url(`${client.launch_url}/filling-out-forms/`)
}
};
The first thing that we're going to do is get the element for the "Name" field - so we can use this ID #et_pb_contact_name_0
- we can do a search for it in the HTML to verify it's an actual ID.
Then we'll use setValue
- pass our ID and we'll enter the name that we want to enter - in this case, it's "John Doe".
We'll set the value for our Message field with ID selector #et_pb_contact_message_0
as well with some dummy text.
module.exports = {
"Should successfully fill out the left form": (client) =>{
client
.url(`${client.launch_url}/filling-out-forms/`)
.setValue('#et_pb_contact_name_0', 'John Doe')
.setValue('#et_pb_contact_message_0', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
}
};
Now that we have our name and we have our message, the next thing to do is to submit the form and we can use the Nightwatch .submitForm()
method.
We could do it two ways - we could either click on the Submit button or we could use the Nightwatch .submitForm()
method.
We know that this is a form, so the method can be used because the .submitForm()
method only works on an actual form element.
So we'll get the ID of the parent for this form #et_pb_contact_form_0
, and then specify form
and that would give us the selector for the form and we can go ahead and use that to submit it.
module.exports = {
"Should successfully fill out the left form": (client) =>{
client
.url(`${client.launch_url}/filling-out-forms/`)
.setValue('#et_pb_contact_name_0', 'John Doe')
.setValue('#et_pb_contact_message_0', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
.submitForm('#et_pb_contact_form_0 form')
}
};
The next thing I would like to do is to assert the success message that we get once we have submitted the form.
So let's go ahead and submit the form manually and see the success message that we get.
We can go ahead and inspect this element and use the ID of the parent div.
Then we should be able to get that text and verify that it says "Form filled out successfully".
We'll do so by using expect.element()
on the ID and using text.to.be.equal
to check that the text says "Form filled out successfully". So we have that assertion.
Let's add one more assertion and that is just to verify page title once we have navigated there.
module.exports = {
"Should successfully fill out the left form": (client) =>{
client
.url(`${client.launch_url}/filling-out-forms/`)
.verify.title('Filling Out Forms - Ultimate QA')
.setValue('#et_pb_contact_name_0', 'John Doe')
.setValue('#et_pb_contact_message_0', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
.submitForm('#et_pb_contact_form_0 form')
.expect.element('#et_pb_contact_form_0').text.to.be.equal('Form filled out successfully')
}
};
We can go ahead and run this and see what happens. But before we do that, let us update our package.json
so we can execute the test using a shorter command.
So within this script, we can specify a command - in this case, test
- and we can say nightwatch
.
Where I'm going to node_modules
and going into the .bin
folder to find the nightwatch
binary, we can do so by just specifying nightwatch
in our package.json
and Node.js will automatically know that it should search in the build folder for this binary.
Now, we can execute our tests by saying npm test
.
We'll need to escape this npm
script command and then we can pass in our nightwatch arguments. In this case, we have specified the test case with -t
.
We'll go to our test file, which is under tests
and then the file is forms.test.js
. So it looks like this:
npm test -- -t ./tests/forms.test.js
And this is a much shorter command compared to what we were using before. Let's execute this and see what we get.
We were able to successfully test for the title and assert that we're seeing the correct text once the form is submitted. This is a very basic test so we can do a few improvements.
Let us also create one more test.
This test will be to check the error message if we submit the form without filling it out.
We'll call it "Should verify error message when the left form is not filled out and submitted".
We can say client.url()
- same thing we did before, because we'll have to refresh the page. Actually, we could use .refresh()
.
Let's use .refresh()
rather than url()
- so let's refresh the page and then let's submit the form using the same selector and then we'll do some verification.
We'll use the verify.containsText()
method and we want to get the label.
Let's submit the form without filling it out and see what happens.
These two boxes are activated, highlighted in red, and we also get this error message.
To get our error message, we can use the ID as we had done before and use the div below it.
We can specify what it should contain - in this case, it should say "Please, fill in the following fields:\nName\nMessage".
We specify a new line by saying \n
. So we have our selector and we have our error message that we want to verify.
module.exports = {
"Should successfully fill out the left form": (client) =>{
client
.url(`${client.launch_url}/filling-out-forms/`)
.verify.title('Filling Out Forms - Ultimate QA')
.setValue('#et_pb_contact_name_0', 'John Doe')
.setValue('#et_pb_contact_message_0', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
.submitForm('#et_pb_contact_form_0 form')
.expect.element('#et_pb_contact_form_0').text.to.be.equal('Form filled out successfully')
},
"Should verify error message when the left form is not filled out and submitted": (client) => {
client
.refresh
.submitForm('#et_pb_contact_form_0 form')
.verify.containsText('#et_pb_contact_form_0 > div:nth-child(1)',
'Please, fill in the following fields:\nName\nMessage')
}
};
Let us run these tests.
The page refreshed and everything passed as expected.
What we could do to make this a little bit better - we could use our beforeEach
hook to call client.url()
.
So what will happen now, we can remove client.url()
from the test, we can also remove the .refresh()
and then we can also add an after
hook.
We can enter client.end()
after we're done with our tests.
beforeEach: (client) => {
client
.url(`${client.launch_url}/filling-out-forms/`)
},
"Should successfully fill out the left form": (client) =>{
client
.verify.title('Filling Out Forms - Ultimate QA')
.setValue('#et_pb_contact_name_0', 'John Doe')
.setValue('#et_pb_contact_message_0', 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
.submitForm('#et_pb_contact_form_0 form')
.expect.element('#et_pb_contact_form_0').text.to.be.equal('Form filled out successfully')
},
"Should verify error message when the left form is not filled out and submitted": (client) => {
client
.submitForm('#et_pb_contact_form_0 form')
.verify.containsText('#et_pb_contact_form_0 > div:nth-child(1)',
'Please, fill in the following fields:\nName\nMessage')
},
after: (client) => {
client.end();
}
Let us run our tests and see if it still works as expected. And everything passes.
Quiz
The quiz for this chapter can be found in section 7.4