 Hi everyone, I'm Anisha Narang, and I work at Red Hat. I've been in the QE job role for almost five years now. I worked with a couple of test automation tools, including Selenium, Python, Cucumber, Water, and off lately I started working with Protractor. Other than that, I like traveling and meeting new people. So before I get started, I would quickly like to know that how many of you are QE's in the room? Okay, that's a good number. How many of you have already worked with Protractor or know what Protractor is? Okay, that's interesting. So I'll quickly run you through the agenda of the talk today. So we'll quickly see how to get started with Protractor. We'll have a look at Jasmine, which is a web application testing framework that Protractor uses by default. Next, we'll have a look at the global variables and how to use the element locators. Understanding promises and control flow. Next, we'll also have a look at page object pattern, how that helps in maintaining the test better. Protractor browser logs, generating HTML reports, and a demo at the end. What is Protractor? Protractor is an end-to-end test framework for Angular and AngularJS applications. It is a NodeJS application built on top of WebDriverJS. It is a wrapper around WebDriverJS to control browsers. It is specific to Angular and understands the internals of the application. It knows when Angular is done processing and the application is ready for the automated test to run against. One of the advantages of Protractor is that it supports Angular specific locator strategies. Now, what do we mean by Angular specific locator strategies? We will have a look at it in the further slides. It's pretty simple to get started with Protractor. Assuming that we have NodeJS installed on our machine, we will use NPM to install Protractor. We say NPM install-gprotractor. Now, this will install two command line tools for you. One is Protractor and the second is WebDriverManager. You need to start the Selenium server before you can have your tests up and running. So for that, you need, but WebDriverManager will take care of all the required binaries and you don't have to install anything separately. But make sure that you do a WebDriverManager update before you do a WebDriverManager start. Now, the WebDriverManager will help you get an instance of Selenium server running at localhost colon double four, double four, slash wd slash hub, the URL that's mentioned. Writing your first test. So it's pretty simple to get started with the writing your first test. It needs two files. One is the configuration file and the second is the spec file. The configuration file tells you where to talk to the Selenium server, where the spec files are located. The spec file can be one file or many files and the framework, which is Jasmine by default and all the other configurations are taken by default. So here if you have a look at the file, it reads the Selenium address, which is exactly the same URL that we mentioned in the previous slide. Next is the specs, which we are mentioning as spec.js, which is just a spec file. It could be many files as well. And next is the framework, which is the Jasmine framework that Protractor uses by default. Now one, this is the spec file. So the describe and its syntax is coming from the Jasmine framework. And browser is a global variable that Protractor exports. You see browser.get with load the particular URL and the expect is the assertions. A spec file can have one or many assertions that we may want as per the test. So before I go ahead, I would quickly like to give you an overview about the application that we are going to refer while we are testing. So here is the angularjs.org if you look at it. So the test that we will be referring to is here. So if I input the text Anisha in this textbook, I expect that it should show hello Anisha there. This is the test that we are going to refer to in the entire talk going forward. Now that we're done writing the spec, how do we run the test? It's pretty simple. We just have to do protractor.js. It will open the browser, perform the test for you and show you the results. Before we go ahead and see the demo, we will quickly understand a bunch of essentials that we might want to understand. Jasmine. Jasmine is a behavior driven development framework for testing the JavaScript code. The describe, the test is defined in the describe function which acts as two parameters. The first is the string and the second is a function. A string which describes the test suit mainly and function describes the block of code that implements it. The second is a global function called it which again acts as two parameters. The first is the string which describes the test that in the plain text and second is the function which is the exact block of code that we are trying to use. So here, this is a very simple two line code that we have. We create an element object and we capture the text of that element and we're expecting that text to equal hello world. Global variables. Protractor exports these global variables. The first is browser. It's a wrapper around an instance of web driver used for navigation and page-wide information. The browser.get method will load the page for you. It expects Angular to be present in the application that you're testing. If the application does not contain Angular, does not have the Angular library, it will throw an error saying the Angular library does not not found. Next is element. Element is a helper function for finding and interacting with DOM elements on the page that you're testing. The element function will accept one parameter which is the locator strategy and return an element finder object for you to interact on the DOM of the page. By a collection of element locator strategies you can search the elements on the page using by.id, by.css, by.name, by.model, and a couple of other locator strategies that we will look forward. Element locators. So one of the most important things that whenever we are doing UI testing is that we need to find the right element, know the state of the application and interact with the element. So the couple of element, most widely used element locators that Protractor has, by.css, find an element using a CSS selector, by.id, find an element with a given id, by.model, find an element with a certain ngmodel, by.binding, find an element bound to a given variable. Now if you look at the last two, they are not very commonly used because these are the ones that are Angular-specific locator strategies. What I mentioned in the initial slides, by.model and by.binding are Angular-specific locator strategies. So locators are passed to the element function as element, by.css, and the CSS that we want to pass there. Now how do we find the element? How do we locate that particular element is we go to that particular element, do a right click, do an inspect, and we can see here. So now if you see here, you will see that here you see ngmodel, your name and how I am interacting with the element is by using by.model, your name. That's how I'm interacting with the particular element on the page, which is the text box that we referred initially. Actions. The element function returns an element finder object. So now the element finder object knows how to find the element on the page, but it will not go ahead and interact with the element on the page until and unless an action method has been called on that object. So here if you look at the code on the left side, we have the element object and we have the element function which is being passed a locator strategy in it. And now we have the action methods. The action methods are nothing but the dot click, dot send keys, dot clear. These are all the action methods that we might want to perform on the web application for our test to proceed. So all actions are asynchronous and all action methods return a promise. What is a promise? We will look forward in the further slides. So now that they return the promise, so to log the text of an element, what we have to do is we have to do element.gettext.then and do a console.log text. We have to use the dot then here. Now understanding promises and control flow. Web driver JS and that's protractor APIs are entirely asynchronous. All functions return promises. Now until I started working with protractor, I had no idea there was a concept called promises that existed. Now promise is nothing but the eventual result of an operation. Promise helps you decide what to do when a particular operation succeeds or fails. Web driver JS maintains a queue of pending promises called the control flow to keep the execution organized. Control flow coordinates the dueling and execution of commands operating on a queue. Now we don't need to write promises because the control flow mechanism of protractor allows us to write promises in a synchronous way. We can write our code in a synchronous way despite of enjoying the asynchronous behavior of the application. Promises, let's make a quick attempt to understand what promises are. Promises represent the eventual result of an operation. Promises are objects. The promise object is used for asynchronous computation. Now let's assume that promise is an object. We're trying to make an HTTP get request which is API docs ID where we expect that it will return the particular title of a document. So it might return the name of that particular document. It might not return because of some error occurred. So now we define, we take the promise object and use the success operation where we say we want to log the title of the published doc and we use the promise object to define what happens when the STDB request fails because of some error. So we are trying to log the request failed with the response and the status code. Now the control flow, like I said, control flow coordinates the scheduling and execution of commands operating on a queue. So now how the code would look like when there is no control flow and how the code would look like when we have control flow. If we do not have control flow now that we know that every action returns a promise. So we will have to resolve each promise in the code using the dot then. So here if you look at the code we have browser.get. It moves to Google.com. And then if you notice we have the dot then operation which says return particular element, finding element with the locator. Again we have a dot then which sends a particular keys which is a web driver into the text box. Again we use the dot then and we send and we click on a particular element. So this is the block of code that we would have to write if we do not have control flow in protractor. But now that we have control flow as a part of protractor it's very simple for us. We can write the code in a synchronous way saying browser.get element by dot ig dot send keys and go ahead and click the button quickly. Page object pattern. Page object pattern simply models the page elements as objects within the test code. Page object pattern is one of the best practices that we can follow whenever we are writing UI tests. It helps us to manage and maintain the test in a better way. It reduces the amount of duplicate code and one of the advantages is that if the UI changes we have to make change at only one place. The fix needs to be done at only one place. Now how would the code look like if we do not have, if we are not using page object pattern we use the describe. We specify the name of the test suit in the it and then we go ahead and load the page which is browser.get element by dot model which is your name which is nothing but that text box that I showed. We are sending keys as Anisha in there and then we are creating a greeting object where we are capturing the element where we are expecting the text to change as per the test and then we do an expect on that particular greeting dot get text to equal hello Anisha. Protract, so the Jasmine expectations also have the ability to understand promises and that's how we see the expect greeting dot get text is working and it is showing you the results to expect hello Anisha. Now, now when we are using the page object pattern how would the code look like? So earlier we saw that how we would write the test when we are not using page object pattern but now we are using page object pattern and we have to create a particular, we have to create the object which is so on the left that you see is the page object file which is angular homepage and defining the function. We describe the two elements that we are trying to interact with. One is name input and the second is greeting. Next, we also define a bunch of functions which is this dot get which is nothing but you can reuse this function every time to navigate to a particular URL instead of writing browser dot get in every test file that you're trying to use. Next is a set name method that we have created which is again nothing but we are trying to interact with the same element and send the keys. So here if we notice we've parameterized it so that we can reuse the same block of code and the same function for any test that we are trying to write and use the same element there. Next is get greeting text. So this will return the text from that particular element which is nothing but it does a return greeting dot get text. We export the particular page object to be used in the test spec. So now we also need to make sure that we are making the appropriate changes in the spec files when we have created a page object. So we do a require saying dot angular home page to the angular home page object and the path has to be related to the spec file that we are using. Now it is again the test that we are trying to describe which says it should greet the named user angular home page dot get which is again the get method from the left that we are trying to use. That set name we are passing the parameters we know that we've parameterized it on the left and we are adding our expect conditions. So all the expect conditions are supposed to be a part of the spec file and we see it here. So we have expect angular home page dot get greeting text which is again the function that we're calling using the function from the left to equal hello Anisha. And that's how we can always reuse the page object file in any other test that we might want to use which involves the same elements that we are trying to use. Protractor browser logs assertion. So often when we are doing UI testing we might miss out on some console log errors that on the browser console log errors that might be that might occur. Some assets might not load correctly. So this is one library that allows you to verify that there are no browser console log errors. How do we use that? It allows us during the browser console logs in each test for warnings and errors. If a particular asset is even not able to load it is showing a 400 but it's not reflecting on the UI. This particular library will capture those errors. We do an NPM install browser protractor browser logs. We define a particular object we do a require on it. And then we add this block of code in the prepare.js which is loaded at the start of every test before the test runs. Now how do we go ahead with it is we define the logs object and we define a before each function which resets that particular object before each test is run and we have an after each test. So after each test is finished running it will check the browser console logs and verify if there are any errors or not. Now the last thing is generating reports. How do we generate reports using Jasmine spec reporter? So we use Jasmine spec reporter and we use the protractor Jasmine to HTML reporter just to make sure that we have HTML reports and the Jasmine spec reporter allows us to have descriptive report on the console. So by default Jasmine does not allow you to have those descriptive reports on the console. So we use Jasmine spec reporter and protractor Jasmine to HTML reporter for having HTML reports. And below is the how the HTML report would look like. So now we will quickly have a look at the code how the code looks like. Okay, so if you look here we have the specs folder here where I've implemented the page object pattern. The first file that you see is the name input spec.js that's the spec file that we have. And second is pages which is the page object file. So we quickly have a look at the code how that looks like. So if you look closely it's exactly the same code that we described. We have different elements and we have the different functions and we're exporting it. And now we will have a look at the spec file how does the spec file look like. So if you see the required it the path is related to the spec file that we have. We have the describe function here we have the it function here the angular home base dot get method we are making a call. We're doing the set name and we are adding the expect condition. Other than that we will also have a look at how the prepare.js looks like. Okay. So this is how the prepare.js was look like we have the Jasmine spec reporter we have the Jasmine browser to HTML reporter we have the browser logs. The three libraries that we discussed during the talk we have all of them here. And here is the block of code for adding HTML reporter. Next is the block of code for add Jasmine spec reporter. And the last is for the protractor browser console logs. You see the before each and the after each function there and we are making a call to each of these functions. How the contract.js looks like is this. So we add the on prepare as a part of contract.js just to make sure that all the functions that we have described in the prepare.js are called when the tests are run. So we'll quickly run the test here how to run the test is like we I told initially it's very simple. We use protractor contract.js. So it opens the browser it goes to that particular text performs the test that was pretty quick to miss out. So this is how it looks like on the console. And this is how the HTML report would look like. You can find the demo code on this URL. It's on my GitHub at slash protractor 101's iPhone demo I guess. And this was the recording that I did of the same demo that I gave live which was a success though. So we don't need that. And thank you. Any questions? Thanks. Yeah. Sure. You wanted to see on the console or you wanted to see the report. So if a particular test fails then there will be a screenshot attached on the right in the HTML report that where the test case fails. So that's also that is also one feature that you can use. If you might want to have a look here. So you see I've mentioned the safe part the screenshots folder takes screenshots only on failures. So you can use that feature as well. Any more questions? I have a question related to the browser loss in the previous. So does this Does this catch the network on the actual JS errors in the console? Yes. Yes. Yes. So it will So the question is that does it actually capture the network errors or just the JS errors? So yes, it will capture any errors that will come as a part of the browser console logs. You've used Selenium before. Yes. How would you compare Selenium to? Okay. So protractor is again built on web driver JS which is nothing but Selenium itself. So it's a wrapper around it. So if you are testing an application which is Angular based protractor is the best tool to use. Okay. Yeah. Thanks. Any more questions? All right. Thank you. I hope you had a good time. Thanks.