Transcripted Summary

Nightwatch provides us with two built-in Assertion libraries. We have Assert and Expect.

Expect library is based on the Chai Assertion Library, which provides a lot of flexibility and capabilities that the Assertion library does not.

How? Because it only extends the Node.js assert module, which only has limited assertion.

One of the benefits of using the Expect API is the fact that we can use language chains, which will make our assertions much easier to read.

So these are some of the chains that we can use:

  • to
  • be
  • been
  • is
  • that
  • which
  • and
  • has
  • have
  • with
  • at
  • does
  • of

This chained language does not affect our assertions, but it does make it much easier for us to read our assertions.

For example, we see browser.expect.element('#main').text.to.equal and we have the value that we want it to equal to. It's much easier to read, but even if we leave out to and just say text.equal, it will still pass.

Let's dive into our editor, so we can see an example of how this chained language can be used. Let's create a new file, let's call it expect.assertion.js.

We'll create a module.exports and we'll define our tests.

Let's call this "Expect Library demo tests". We need to define our client and then we should navigate to our URL.

Let's use the Ultimate QA URL .

We'll navigate to the URL and then we make an assertion using the Expect library.


module.exports = {
    "Expect Library demo tests" : (client) => {
        client
        .url('https://ultimateqa.com/filling-out-forms/')
    }
};

Let us assert the text of this submit button.



Let's get the button by the name.

The two buttons have the same name, so we can differentiate them by using nth-child(1), and this selector button[name="et_builder_submit_button"]:nth-child(1) should be good enough.

Now we can say expect.element and specify the element that we want to interact with.

We'll say that we expect the text to equal "Submit".


module.exports = {
    "Expect Library demo tests" : (client) => {
        client
        .url('https://ultimateqa.com/filling-out-forms/')        
        .expect.element('button[name="et_builder_submit_button"]:nth-child(1)').text.equal('Submit')
    }
};

Let's go ahead to our terminal and run this with ./node_modules/.bin/nightwatch and we'll specify our tests with -t. So let's run this and see what happens:


./node_modules/.bin/nightwatch -t ./tests/expect.assertion.js



As you can see our assertion worked as expected because the text was "Submit".

Now, as we mentioned before, using the language chains does not affect our assertion.

Based on the list of the different chains that we can use and I could say, text.with.equal - the with makes no sense but if I run the test, it should still pass because the assertion library will ignore the with.

It's just something that we can use for reading and I could also not add any chain language right there and will work just the same.

Let's talk a bit more about the assert library.

The assert library actually has two namespaces. You can either use .assert or .verify.


.assert vs .verify

The two of them are interchangeable. But there's one difference: if an assertion fails while using the assert, it will stop the test case and ignore all other assertions. When you're using verify, on the other hand, it will log the failed assertion and execute the others.


I personally prefer verify if my test has multiple assertions.

So let us see what that looks like.

Let me just create a new file and we'll call that assert.assertion.js. I'll just copy this from our expect.assertion.js and make some small modifications.

Now, we still want to use this button element, but I'll just go ahead and say assert.visible - we'll be verifying that this element is visible.


module.exports = {
    "Assert Library demo tests" : (client) => {
        client
        .url('https://ultimateqa.com/filling-out-forms/')
        .assert.visible('button[name="et_builder_submit_button"]:nth-child(1)')
    }
};

As a matter of fact, let's do something more interesting. So we can always use the negate function .not if we want something to be false instead of true.

.not

Since version 1.3, all assertions, including the custom ones that we might create, can have the counterpart of .not, which would be basically used to assert the opposite.


So let's use .not, even though the element is visible. So we're expecting that to fail, but I also want to show that we have two assertions for these tests, but only one will be executed because we're using the assert keyword.


module.exports = {
    "Assert Library demo tests" : (client) => {
        client
        .url('https://ultimateqa.com/filling-out-forms/')
        .assert.not.visible('button[name="et_builder_submit_button"]:nth-child(1)')
        .assert.visible('button[name="et_builder_submit_button"]:nth-child(1)')
    }
};

Let's go ahead and run our new test file.


./node_modules/.bin/nightwatch -t ./tests/assert.assertion.js



Now as you can see, we're getting an error that the element is expected to be not visible but it is visible.

And we only had one assertion that was ran. Now, suppose I change our first assert to verify - now we'll expect that, yes, it will fail, but also it will continue to assert this other assertion.


module.exports = {
    "Assert Library demo tests" : (client) => {
        client
        .url('https://ultimateqa.com/filling-out-forms/')
        .verify.not.visible('button[name="et_builder_submit_button"]:nth-child(1)')
        .assert.visible('button[name="et_builder_submit_button"]:nth-child(1)')
    }
};

Let's see if that works as expected.



Now we have two tests executing: the first one failed as expected, but then we're also seeing another assertion that actually passes. And that's the difference between using assert and verify.



Resources



Quiz

The quiz for this chapter can be found in section 5.4

© 2021 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR