Several years ago, I had the chance to work with Protractor. Our team had a project to re-implement the frontend of the company’s mobile app (obviously, we kept the old, legacy backend engine, because “why not?”), and they chose AngularJS for it. It was in 2015/2016. The Angular framework gained immense popularity back then, it was a desirable and fast-growing framework, so it was very trendy to work with it and add it to the CV.
When I re-joined EPAM in 2019, my boss introduced me to some guys who are active contributors of Community-Z. Never heard about it, right? You’re not alone, don’t worry if you haven’t. I haven’t heard about this community either till then. It’s a great community, a platform, which you can join for completely free. You can organize meetups, call for speakers, build networks, or share knowledge.
There’s this relatively new initiative, called “Idea Pool,” in which we try to introduce different testing frameworks to the audience. The purpose of these webinars is to gain more knowledge about these frameworks, to see what is currently available on the market, so you can compare them, and select the best fit for your needs. I was curious to know how the Protractor framework had evolved since 2016 when I last touched it. I wanted to see the improvements in this framework, so we organized a webinar for it. But let’s start from scratch and let me take you through my Protractor adventure 🙂
If you’ve implemented some autotests before, you most probably know that sometimes it is challenging to capture web elements on the page, especially in AngularJS applications using WebDriver/Selenium.
The idea of the framework came from a Senior Test Developer at Google, from Julie Ralph. She wasn’t happy with the existing testing frameworks for AngularJS, so she started to implement a new one; in fact, she was the most active contributor of Protractor.
Angular JS applications have some extra HTML attributes like ng-repeater, ng-controller, ng-model.., etc. which are not included in Selenium locators. Sometimes these Angular components can be difficult to locate with CSS or Xpath. Still, fortunately, Protractor on the top of Selenium can handle and access these elements without any issue because it has some powerful Angular specific locator strategies.
Another massive benefit of using Protractor is that it also has automatic waits, which means you’ll no longer need to add waits and sleeps to your tests explicitly.
It automatically knows when an Angular app is done loading and executes the next step in your test the moment the Web page finishes any pending tasks.
How does Protractor work?
So, let’s see now how this excellent framework works.
We already mentioned that it was built on top of the Selenium Webdriver API, but apart from this, it’s using other libraries too…
When working with Protractor, it’s essential to keep the following in mind:
- WebDriver commands are asynchronous. They are scheduled on control flow and return promises, not primitive values. Hence you might use async/await commands to fulfill these promises.
- Your test scripts send commands to the Selenium Server, which in turn communicates with the browser driver.
The Selenium Server takes care of interpreting commands from the test and forwarding them to one or more browsers. The command is interpreted by the Browser Driver.
Protractor runs an extra command before performing any action on the browser to ensure that the application being tested has stabilized.
- Most of the AngularJS applications are extended with HTML attributes like ng-controller and ng-model. Selenium locators cannot find these elements with the pure Selenium code. At the same time, Protractor can easily find and control Angular-specific locators.
- It performs faster than Selenium because there is no need for any additional waits to use since Protractor can track the network, router changes, and execute the testing scripts accordingly.
- Also, it does multi-browser testing on popular browsers such as Firefox, Chrome, Edge, IE11 in quicker time, and in a natural way.
- Protractor has a parallel execution feature, thus making it easier for testers to run test cases in numerous instances of any browser simultaneously so that they can reduce the test execution time.
- You can run multiple specs simultaneously.
- OR: you can run the same spec against different browsers/devices in parallel.
- Protractor has multiple assertion libraries to work with. However, it’s easy to use with Mocha, Jasmine, and chai too.
- Testers can deploy their Protractor code in the cloud quickly. It supports Sauce Labs and Cross Browser Testing along with other cloud platforms.
- Protractor is much faster as it improves and manages synchronization to a greater extent. Also, it works equally well with headless and real browsers.
NG Locators in Protractor
So, what are these NG locators, how do they look like, and how can we use them?
They added accessors to angular models, bindings, ng-options – and finding elements inside ng-repeat. These additions make access to web elements much more straightforward.
Like you see on the web page, we have a Select box with some options in it. And although this select element doesn’t have an ID, we can use it’s “ng-model” attribute in our Page object so that we can manipulate it later on in our tests.
And how to do that?
this.exampleSelect = element(by.model('data.singleSelect'));
Protractor exports three global variables to your spec (test) file.
browser – A wrapper around an instance of WebDriver, used for navigation and page-wide information. For example, the browser.get method loads the page, and with the browser.takeScreenshot method, you can capture the actual screen.
element – A helper function for finding and interacting with DOM elements on the page you are testing. The element function searches for an element on the page. It requires one parameter, a locator strategy for locating the element.
by – A collection of element locator strategies. For example, elements can be found by CSS selector, by ID, or by the attribute they are bound to with ng-model.
protractor – The Protractor namespace, which wraps the WebDriver namespace. Contains static variables and classes, such as protractor.Key which enumerates the codes for unique keyboard signals.
Expected Conditions represents a library of canned expected conditions that are useful for Protractor, especially when dealing with non-angular apps.
Each condition returns a function that evaluates to a promise. You can mix multiple conditions using and, or, and/or not. You may also combine these conditions with any other conditions that you write. And what’s even better! You can define your expected condition too.
Protractor has been a super popular framework back in time, so no wonder that lots of guys wanted to improve it, to extend it, and created lots of helper packages for it.
The most famous and popular one is Protractor Helper. Many of the helper functions in this library use the already mentioned protractor.ExpectedConditions to ensure that the elements we want to interact with are in the correct state before interacting with them or running expectations on them.
- fillFieldWithText – will wait for the field to be present and active on the page
Protractor Screenshot Reporter (obsolete)
Protractor provides the ability to take a screenshot via the browser.takeScreenshot() function. After you’ve taken a screenshot, though, you probably want to save it. The easiest way is to create a helper function that will save it for you. One thing you’ll probably want to do is set up a way to capture screenshots whenever there is a test failure automatically. You can write this yourself, or simply use the npm module protractor-html-screenshot-reporter. That module has the added benefit of outputting a pretty HTML report.
Protractor Perf (not maintained)
Protractor-perf can be used just like Protractor, just that the test-cases need to be instrumented to indicated when to start and stop measuring performance. protractor-perf is based on browser-perf. browser-perf measures the metrics that can be tested for regressions.
Most popular metrics which are measured:
- The time spent decoding images.
- The total time for all actions to render the page
- The time spent doing garbage collection during script execution
Although I tried to do proper marketing for this framework, I have to mention now some –not-as-good-news too, when it comes to the releases.
Protractor was created at Google, and the company invested lots of time to improve it, to make it stable, but after a few years, they made it fully OPEN_SOURCE…
And maybe that wasn’t the best and most bright future for this tool. It doesn’t have frequent releases at all, in fact, the last big release, in which they introduced the Protractor 7.0, was just a security improvement, they updated some dependencies and switched to the recent NodeJS, but no significant improvements, no new methods were added, at all.
(1) And you can see it on their Activity page on GitHub too
(2) they’re not active on Twitter anymore,
(3) And even Angie Jones, one of the most popular speakers at QA conferences, and now the principal QA Advocate at Applitools doesn’t recommend using protractor; instead, she suggests to use WebDriverIO, Cypress or Test Café.
Oh, and by the way, we had webinar sessions earlier this year, and there we evaluated these frameworks already, so feel free to check them on the Community Z portal 😉
Let’s try to sum up the pros and cons of this dying framework now.
Pros and Cons
Although I tried to focus on the impressive features of this framework, like all the other things in our life, it has pros and cons too.
For the Pros
- As we mentioned in the beginning, Protractor brings some additional methods to locate the angularJS components more quickly, so you don’t need to stick to IDs, Xpaths, or CSS selectors only.
- It’s fast, mainly on the Angular pages.
- Simple Cross-Browser Support, you can run your Tests on Firefox, Chrome, Edge, and even in Safari.
- Stable Execution. Thanks for the built-in waits for the Angular calls and modules, Protractor recognizes when is the page or element ready, so you need to add the custom waits only in rear scenarios
As for the Cons
- Although for Angular pages, it seems to be the right decision, for non-angular pages, the execution is not stable at all. You simply need to hack the system, use the waits for the elements to appear, etc.
- Also, for the non-angular apps, you can’t use the ng locators, you need to stick to the standard selenium ones (like. Id, XPath, CSS), so you can forget the by.model, by.binding, etc. locators.
- Unfortunately, By.Model and By.Binding locators are available for AngularJS applications only; from Angular 2.0 these locators are not supported anymore.
Maybe it’s just my wrong impression of the framework, but when we used this tool for testing an Angular app for our client, Protractor didn’t convince us as much.
The tests were not stable and we were faced with random timeouts, so we had to switch to CodeceptJS, and thankfully our tests are now super durable, without any timeouts.
Also, here at EPAM, guys are using Protractor on different projects for several years now, without any issues, so we have some happy stories too.
Do you have experience with this framework? How did it work on your project? Do you see Protractor dying too? Let us know so that we can have a constructive discussion about it! 😉
PS. During the evaluation of this framework, I implemented seven test cases, to demonstrate the features of Protractor. You can find them on Idea Pool’s GitHub page.
Quality Assurance and Testing Advocate with 10+ years of experience, passionate about quality and education.