Smooth out the Sharp Angles of Protractor Testing

Helping failed assertions make a little bit more sense

Jan Molak
Jan Molak

--

One of the most common activities of a Protractor test is to verify the state of various web elements. For example, a test might need to ensure that an element is, or becomes present as a result of our interaction with the system — did a confirmation dialog appear as expected? Or Perhaps we need to wait for some element to appear before we can proceed — is the dialog present for us to confirm the action?

Protractor provides several convenience methods that we can use to assess the state of web elements and they work very well as long as everything goes according to plan. If it doesn’t we might sometimes see this:

AssertionError: expected false to be true
https://en.wikipedia.org/wiki/The_IT_Crowd

This particularly unhelpful message is not caused by some deficiency in Protractor, however. It’s caused by how we use it.

In this article, I’ll show you how we can help failed assertions make a little bit more sense and save us some precious debugging time.

The (Missing) Context

Consider the following example, in which we’d like to find out if the below HTML element is displayed:

<h1 id="title">Chai Smoothie is delicious!</h1>

If we’re using the excellent Chai and Chai as Promised libraries, we might try to solve the problem using the following statement:

expect(element(by.id('title')).isDisplayed()).to.eventually.be.true

When the element identified by the id of “title” is displayed, the assertion works fine and won’t bother us with any error messages. However, should the element suddenly decide to not appear, we’d get the dreaded:

AssertionError: expected false to be true

Although Chai is doing its best to tell us the reason of the failure, the only information it has available at this stage is the boolean state of the element’s visibility. This lack of context is what causes the error message to seem a bit unhelpful.

Additionally, since assertion errors are also often accompanied with a long stack trace, not necessarily directly related to the problem — the process of analysing and understanding the failure becomes a long and frustrating endeavour.

Smooth out the sharp angles of Protractor testing

Let’s take a step back then.

One of the amazing things that Chai allows us to do is to expand its already rich assertion vocabulary with custom plugins, which we can either implement ourselves or choose from a vast array of existing ones.

Chai Smoothie is my take at helping failures in Protractor tests become a bit more meaningful, so let me show you how you can use it.

Smoothie expands Chai’s vocabulary to add the following properties:

  • displayed — which verifies if an element exists in the DOM and is visible
  • enabled — which can tell you if a form element, such as an input box, is not disabled
  • present — which checks if an element exists in the DOM (even though it might not be visible)
  • selected — which can help you check if a form control, such as an input checkbox is checked

With Smoothie, we could improve our original solution to look like this:

expect(element(by.id('title'))).to.eventually.be.displayed;

Now, should the title decide to not appear, we’d get a more informative error:

AssertionError: Expected the element located By(css selector, *[id="title"]) to be displayed, but it's not.

At least now we know what element we’re talking about!

Take it further

Knowing a bit more about the context of a test failure goes a long way, so could we take it even further then?

Of course we could, and this is where Serenity/JS comes into play!

Since Serenity/JS builds on the shoulders of Protractor to allow for easy integration with Angular.js and other popular web frameworks, you can further improve your Protractor tests to use Smoothie together with Serenity/JS Questions:

expect(actor.toSee(WebElement.of(Article.Title))).displayed

Serenity/JS is a next generation acceptance testing library, which implements the Screenplay Pattern and produces in-depth reports that the Serenity BDD community has long benefited from in the Java land. This means that should our assertion fail again, we’d not only get a more meaningful error message, we’d also get a descriptive report, together with screenshots depicting the state of the system when the failure occurred.

If you’d like to learn how you can improve your Protractor tests to produce more meaningful information, check out our article “Introducing Serenity/JS: Next generation acceptance testing in JavaScript” and give the tutorials a go.

Looking forward to hearing your thoughts!

Jan Molak — is a trainer, consultant and full-stack developer who spent last 12 years building and shipping software ranging from AAA video games through high-traffic websites to complex event processing and financial systems. Jan is the author of Serenity/JS, Chai Smoothie as well as the Jenkins Build Monitor and many other open-source projects.

Enjoyed the reading? Please hit the💚 below so other people will see this article here on Medium. You might like my other articles and tutorials too!

--

--

Consulting software engineer and trainer specialising in enhancing team collaboration and optimising software development processes for global organisations.