Testing Auth0 login on AngularJS with Protractor, Part 1

Getting Auth0 to work with AngularJS is straight forward. It's a matter of adding the auth0-angular dependency in Bower (bower install --save auth0-angular) and including the JavaScript file in your HTML index. There are a few differences between the standard AngularJS routing and angular-ui-router, so I might come with a follow-up post to show you how I got it working.

With the Auth0 service ready, I created an Authentication module where I injected it as a dependency. On the same module I defined a Login Controller:

On the controller, 2 scope methods are defined: one for login and one for logout. (to configure and read more about these you can login to your Auth0 admin account on auth0.com, then go to Apps/APIs from the left menu and then click on Quickstart to the right side of your app)

On a template of your choice, instantiate the controller and add two buttons for login and logout.

Note that each of the buttons has its own id definied. This will come in handy when we'll write our tests.
That's it for the login code (thanks auth0, you are awesome!), now let's write an e2e test with Protractor!

Setting up Protractor is not difficult if you follow the Quick Start. For me the setup had to be done on a Vagrant VM and it was a bit more complicated (perhaps I'll write a post on that later on).
With Protractor ready, be sure to create a config file (I named mine protractor.conf.js). It should look similar to this:

Because I am running my tests on a headless server, my browser of choice is PhantomJS, but you can choose Chrome of Firefox if you wish.
If you want selenium to automatically start and stop each time you run your tests, then comment out

...
seleniumAddress: 'http://localhost:4444/wd/hub',
...

It's just faster for me to start the selenium server manually by running webdriver-manager start, but again it might be so because of my Virtual Machine.

With the config in place, it's finally time to write our test!
Start by creating an auth0.e2e.js file.
If you are familar with Jasmine, the syntax will be the same. We'll create a 'describe' and 'it' block:

First we need to navigate to the page where the template containing the login/logout button is displayed. To make sure we won't get a "Element is not visible" error while using PhantomJS I also set the window size. Notice that to navigate we can use browser.baseUrl, which is defined in the Protractor config file.

For my convenience I've created a user in Auth0 with email test@user.com and password 0000. From this point on it will be a step-by-step interface navigation.
First we will create a wait block and check if the login button is displayed. To make this work we need a [*Exists] variable that will just return true/false if the element exists. (Note that the ids from the template are used)

I prefer checking to see if an element is on the DOM in a wait block. The interface might take some time to load and we don't want our tests to fail when we have a slow internet connection / slow hardware / poor server specs / etc. After we're sure it's displayed, it's safe to click it.

The next step is to wait for the Auth0 pop-up to load (with the email & password fields). Although the same wait block is used, the fields are not displayed at the same time as they are loaded in the DOM. I figured an arbitrary timeout of 2000ms will make sure the email and password fields are visible.

To see if the test works type in the following:
(skip the first command if you removed the seleniumAddress from your Protractor conf)

webdriver-manager start
protractor protractor.conf.js

Final words

You might have noticed that I haven't actually created any assertion. That's because my intention with this test is to transform it into a common method that I can use in any Protractor test with the help of the Page Object pattern. Plus, each wait block would break the test if the watched element won't be in the DOM after the timeout has passed.

I'll show you how to refactor this test and use Page Objects to better organize Protractor tests in my next post!