 So, thank you very much for coming to my talk. Today we will talk about page object pattern, or page object model, or how whenever you will call that. The concept is the same. And the thing that I will talk about is not the best solutions, it's just the solutions that I get during my seven-year experience working in the big company. So I'm Sarkis, nice to see all of you. I have more than a seven-year experience working with the Selenium and the Automation Quality Insurance, and most of my experience I got working when I was working with Workfront, which is the U.S. best company, and let's go and see what I prepared for you today. So, yep, it's from the screen, it's squeezed a bit, but anyway, we'll have a short introduction. Then we'll talk about page object pattern. I don't want to go details in a low level, I will try to expand some stuff in a bit at a high level, and we will talk about what kind of the weight opportunities we have in the Selenium, and then the most fun part, the challenging part is the loadable component and the slow loadable component that will help us to get right from the weights in the Selenium. And I will talk about the common failure that people are always asking me questions about that, and how to do and how to not do, and then we are a bit short of time. I hope we'll have time for the question and answer, if not, I will be around till the end of the conference. Thank you very much for coming to my talk. Today we will talk about page object pattern, or page object model, or how whenever you will call that, the concept is the same. And the thing that I will talk about is not the best solutions, it's just the solutions that I get during my seven-year experience working in the big company. So I'm Sarkis, nice to see all of you. I have more than a seven-year experience working with the Selenium and the automation quality insurance, and most of my experience I got when I was working with Workfront, which is the US-based company, and let's go and see what I prepared for you today. So, yep, it's from the screen, it's squeezed a bit, but anyway, we'll have a short introduction, then we'll talk about page object pattern. I don't want to go details in a low level. I will try to expand some stuff in a bit a high level, and we will talk about what kind of the wait opportunities we have in the Selenium. And then the most fun part, the challenging part is the loadable component, and the slow loadable component that will help us to get right from the wait in the Selenium. And I will talk about the common failure that people are always asking me questions about that and how to do and how to not do. And then we are a bit short of time, I hope we will have time for the question and answer, if not, I will be around till the end of the conference. Tom, this is not good already. Can some technical guy help us with this? I see normally in my screen, but there is a problem. It will become a bit smaller, but what to do? So, demos that I will provide will be coded in Java. And as an example, I use the GitHub UI interface, and we will try to log in and try that there is exception or something like that. Everything that I will present will be applicable in strong type language, for example, if you are using a C sharp, and most of things will be applicable also in dynamic type languages like Ruby, Piton or something. So also, in my presentation, I will use Maven, test engine, and for sure Selenium. So everyone has the basic knowledge of this. So, page object pattern, I will not, again, like high level to remember what is it if someone is out of information. It's a framework design pattern, which has become popular in the Selenium test automation, and it makes it easier to maintain and reduce the code duplication. This is for Selenium, like when we are after, I think like web application, and it makes it easier to create page, maintain page, and whenever we would like to do with the pages. And let's imagine we have a web application, and there is a different pages, login page, registration page, some stuff, and in page pattern, also in the pages there is a services like different, like specific for that page. So what we are doing, we are collecting every single page will be presented as a class, and the web page will be object, there is a classes, and every class will contain the elements with their services and the methods. So, why we need to use it? This is the important question. It promotes reuse of the code, so we'll have less code. It makes readable the whole suite. Also it's improved maintainability, so it's easy to maintain. It makes it easy to change the classes, and you will not change anything in the test class. So if you have page objects in every class name change or something that developers will change, you will change just once in one place. So how it's structured. Each page is defined its own class, actions and are represented in the class as a method and our functions. Each function can return new page object, especially when we are navigating within the pages, this talks only with the page objects. Page objects, this is like extra step that I added, like with the base objects, a lot of people call that abstract page base objects is whenever you call, and base objects talks to driver. Pages are stored as a variable. So we should make sure, anyway, we should make sure that the Selenium talks only with the page objects, especially with the base class, so when we are changing something, it will be easier. So in a graphical appearance, it will look like this. So this is just a Selenium with the test and the browsers and the report and the read application. When we are adding the page objects, so where it should be, we are isolating tests to be interaction with the Selenium. And another extra step that I would suggest to add a lot of specialists will suggest to do, it's adding one more step between Selenium and the page objects, like to collect everything. This is some abstract class in Java, and this is a way to make it easier to collect everything in there. This is also kind of a place to collect some methods that will be interacting with the Selenium. So type or finding the element instead of every time calling it from driver. Because I had a problem when we were upgrading Selenium versions, so usually there is a solution that should be applied to the type. So instead of going to every page objects and changing the type, we are going to the base class and changing there. So in other appearance, it will look like layers. So in this graphic you can see that the main concept is this layer should not be able to talk to this layer. So every layer can and should talk with neighbors. There should not be any allowance to jump from the layer to the layer. This is how it looks in the packages in the Java for the Maven project. And it's a bit again, sorry, it's not my fault. This is basically how the page objects look like. Here is the just example, so I hard-coded the main URL. So in the real world, we are not doing this, yes? We are doing something in the property file and then reading from there to make it easier. Just being a bit more understandable and readable, I did it. And there is a constructor which is applying the driver. I will show where I am creating the driver. And here is the open page which always we will use when we are starting the test. And this is an abstract and it can become any type of the page that you will extend it. Here, okay, for this get maybe you have a question why there is a get. We will talk about that in a loadable component because it's done for that. And there is some abstract methods and you can add more. So because every page will have a get URL, so we are putting in a page object and then overriding them for the specific page. And open is already being. So this is the continuation of the page object. I make it like two parts to be more readable. I collect it here like find type, like different types of type, like loaded methods. And click also some several types. And some methods that we are always using, this is just for the example because I know everyone like using this because the method of the display throws exception when there is no. So this is the kind of the exception handling example and you can add more based on your application. Here there is a Selenium driver class which done like high level stuff like creating driver and it's collected in a separate class. Here I'm just creating, I'm checking that it's not null then creating. And create the, I created a static method and I can call from everywhere which makes for me easier than always creating for every page. And I have a base test class and every test class extends this, so as a becoming subclass of this. And here I'm doing any stuff that's done for every test. For example, after finishing class all the test just close the browser. Here you can add for example after finishing like clear all cookies or anything globally you want to that because to add and repeat in the classes I don't like, there's no make sense. So generally this is the test that looks like this just small test that trying to log into GitHub and with the wrong credentials and shows that there is no such user and checking the exception, not exception but error message. So weights in Selenium, how many of you have a problem with the weights? How many of you using the slips? How many of you like using the retry? I mean if doesn't work retry once, always. So for the basic weights I will generally show you which kind of the weights options can that there is in the Selenium. Then we'll talk about a loadable component which is created for this purpose to solve this problem. So while we are waiting to load the page to make it ready and to make the all transactions and I always say that the slips, they shouldn't be slipped because it's always making a hard time, not adjustable and when we are running on a continuous integration in the Amazon services which is too expensive, we are losing a lot of money, actually company lose but. So Selenium offers like three types of the weights, implicit weight, explicit weight and the fluent weight. This is the three versions that you can use without anything. So implicit weight, this is the amount that you are giving to the Selenium configs saying that every time when you are getting any element, wait for X time like 10 seconds and the problem here when there is no element and you are checking that there shouldn't be any element, it still waits the 10 seconds. So this is not adjustable, also it's undocumented. It only works for finding the elements and you cannot customize anything. We are setting up for the driver and it's non-visible but it's like driver managed time out or explicit weight and then you are giving the weight. The best practice is to not use this. If you have possibility, if you can manage without it, it's a good thing to not use this one. So explicit weight, here we have documented and defined behavior so you can also read it in the website. What it's doing, it's from every 500 milliseconds, it's pinging to application, checking until it will find and it's return success or time out which you can find and works any condition you can provide. So this visible, this clickable, this should be disabled, anything you want and this is the way how it looks like. I will talk about the page load helper. This is another class that I'm creating and it's make easier and you can provide any condition here and just wait until this condition will become true. And the fluent weight is almost the same as the explicit weight but here you are waiting all the time out and the transaction and additionally you need to tell that how it should throw an exception and when they don't find an object as the best practice. So and implementation looks like again it's not visible so later I will share everything so you can read it because of the screen is not the best one and here there is the implementation for fluent weight, you are providing a time out, you are also providing polling every which means like how many time between the calls you need. So in explicit weight we have a hard code, it's like 500 millisecond, it's adjustable. You can put that every one second, go and check and back and you are handling the exception here and this is overridden method which is coming up, sorry. Explicit weight and the disk weight, here is more dynamic, you can set the time between the calls. And also here you should actually, as a best practice, you should handle the thrown exception and this one is more customizable than the explicit weight. Yeah, it's the same, you will like here what it's doing, it will try to find the element that you are giving here during this time and between the calls like the variable that have here. So here that in the apply you are waiting for the element that you are given here and with these parameters you are setting it here. Yeah, it's something, it's almost the same, it's doing the same logic as a explicit weight but with the customizable version of it. So loadable component is starting the challenging part, maybe, who knows about loadable component. The next question is redundant, are you using in a real project or not, it's only for you, you are using, yeah, yeah, nice, okay. The loadable component is a base class, is a base class on the aim to make weighting page objects until they will load. So it will help us to make the page object pattern useability like less painful and it makes more easier to debug the failures because there is customizable stuff and a lot of maintainable stuff. There is currently an implementation in Java, let's come with Selenium but it's easy to implement in any other language and for that reason I will try to configure custom loadable component also in a Java which I'm doing always because I can also provide error messages for more easier debugging and some stuff like that. So I will suggest also not use the native one, just create your own one and do anything you want. Yeah, for that reason there is also slow loadable component that comes in the next one. So here it's basically how you are making the class loadable, nothing is visible, sorry. It's just extend from loadable component and with it there is also two methods that you always need to overwrite when you are extending from the loadable component. This is loaded and loaded. So these two methods you will implement for every page class. So this is the only like a bit of painful part for the aftermation test, there's a lot of people saying that it's making a lot of work to do for every page even I don't need but anyway there is no lot of good stuff without a bit more work. It will become a bit smaller but what to do. So demos that I will provide will be coded in Java and as example I used GitHub UI interface and we will try to log in and try that there is exception or something like that. Everything that I will present will be applicable in strong type language for example if you are using C sharp and most of things will be applicable also in dynamic type languages like Ruby, Piton or something. So also in my presentations I will use Maven, test engine and for sure Selenium. So everyone has the basic knowledge of this. So page object pattern. I will not again like high level to remember what is it if someone is out of information. It's a framework design pattern which has become popular in the Selenium automation and it makes easier to maintain and reduce the code duplication. This is for Selenium like web application and it makes easier to create page, maintain page and whenever we would like to do it with the pages and let's imagine we have a web application and there is different pages, login page, registration page, some stuff and in page pattern also in the pages there is services like different like specific for that page. So what we are doing we are collecting every single page will be presented as a class and the web page will be object, there is a classes and every class will contain the elements with their services and the methods. So why we need to use it? This is the important question. It promotes reuse of the code so we will have less code. It makes readable the whole suite. Also it's improved maintainability so it's easy to maintain. It makes easy to change the classes and you will not change anything in the test class. If you have page objects in every class name change or something that developers will change you will change just once in one place. So how it's structured? Each page is defined its own class, actions and are represented in the class as a method and the functions. Each function can return new page object especially when we are navigating within the pages This talks only with the page objects. Page objects, this is like extra step that I added like with the base objects. A lot of people call that the abstract page base objects is whenever you call. And base objects talks to driver. Elements are stored as a variable. So we should make sure anyway we should make sure that the selenium talks only with the page objects especially with the base class so when we are changing something it will be easier. So in a graphical appearance it will look like this. So this is just a selenium with the test and the browsers and the report and the web application. When we are adding the page objects so where it should be we are isolating tests to be interaction with the selenium. And another extra step that I will suggest to add and a lot of specialists will suggest to do, it is adding one more step between selenium and the page objects like to collect everything. This is some abstract class in Java and this is a way to make it easier to collect everything in there. This is also kind of a place to collect some methods that will be interacting with the selenium. So type or finding the element instead of every time calling it from the driver. Because I had a problem when we were upgrading selenium versions so usually there is solution that should be applied to the type. So instead of going to every page object and changing the type we are going to the base class and changing there. So in other appearance it will look like layers so which one in this graphic you can see that the main concept is this layer should not be able to talk to this layer. So every layer can and should talk with neighbors. There should not be any allowance to jump from the layer to the layer. This is how it looks in the packages in the Java for the Maven project and it's a bit again cut it but sorry it's not my fault. This is basically how the page objects looks like. Here is the example so I hard coded the main URL so in the real world we are not doing this yes collecting something in the property file and then reading from there to make it easier. Just being a bit more understandable and readable I did it. There is a constructor which is applying the driver. I will show where I am creating the driver. Here is the open page which always you will use when you are starting the test and this is an abstract and it can become any type of page that you will extend it. Here okay for this get maybe you have a question why there is a get we will talk about that in a loadable component because it's done for that and there is some abstract methods and you can add more so because every page will have a get URL so we are putting in a page object and then overriding them for the specific page and open it's already been so this is the continuation of the page object I make it like two parts to be more readable. I collect it here like find type like different types of type like loaded methods click also some several types and some methods that you are always using this is just for the example because I know everyone like using this because the method of the display throws exception when there is no so this is the kind of the exception handling example and you can add more based on your application. Here there is a Selenium driver class which done like high level stuff like creating driver and it's collected in a separate class here I'm just creating I'm checking that it's not null then creating and create the I created a static method and I can call from everywhere which makes for me easier than always creating for every page and I have a base test class and every test class extends this so as a becoming a subclass of this and here I'm doing any stuff that's done for every test for example after finishing class all the test just close the browser here you can add for example after finishing like clear all cookies or anything globally you want to that because to add and repeat in the classes I don't like that there's no make sense so generally this is the test that looks like this just small test that trying to log into GitHub and with the wrong credentials and shows that there is no such user and checking the exception that not exception but error message so weights in Selenium how many of you have problem with the weights how many of you using the slips how many of you like using the retry I mean if doesn't work retry once always so for the basic weights I will generally show you which kind of the weights options can that there is in the Selenium then we'll talk about a lot of components which is created for this purpose to solve this problem so why we are waiting to load the page to make it ready and to make the old transactions and I always say that the slips there shouldn't be sleep because it's always making a hard time non-adjustable and when we are running on a continuous integration in the Amazon services which is too expensive you are losing a lot of money actually company lose but so Selenium offers like three types of the weights implicit weight explicit weight and the fluent weight this is the three versions that you can use without anything so implicit weight this is the amount that you are giving to the Selenium conflicts saying that every time when you are getting the any any element weight for X time like 10 seconds and the problem here when there is no an element and we are checking that there shouldn't be any element it still waits the 10 seconds so this is not adjustable also it's undocumented it's only works for finding the elements and you cannot customize anything you are setting up for the driver and it's non-visible but it's like driver manage time out or explicit weight and then you are giving the weight the best practice is to not use this if you have possibility if you have you can manage without it it's a good thing to not use this one so explicit weight here is we have a documented and defined behavior so you can also read in a website this what is that is doing it's from like every 500 milliseconds it's pinging to application checking pinging checking until it will find and it's return success or time out which you can find and works any condition you can provide so this visible this clickable this should be disabled anything you want and this is the way how it looks like I will talk about the page load helper this is another class that I'm creating and it's make easier and you can provide any any condition here and just like wait until this condition will become true and the fluent bait is almost the same as the explicit weight but here you you are overall timeouts you are waiting all the timeouts and the transaction and additionally you need to tell that how awaits that you should throw up exception and when they don't find an object as the best practice so and implementation looks like again it's not visible so that rival share everything so you can read it because of the screen is not the best one and here there is the implementation for fluent wait you are providing a timeout you are also providing polling every which means how like how many time between the calls you need so in explicit wait we have a hard code it is like 500 millisecond he is adjustable you can put that every one second go and check and back and you are handling the exception here and this is overridden method which is come sorry explicit wait and the display here is more dynamic you can you can set the time between the calls and also you can here you can you should actually as a best practice you should handle the throne exception and this one is more customizable than the explicit weight yeah it's the same yeah you will like here what is doing you will it will try to find the element that you are giving here during this time and between the calls like the variable that have here so here that in the apply you are waiting for the element that you are given here and with these parameters you are setting it here yeah it's something it's it's almost the same it's doing the same the logic as a explicit weight but with the customizable version of it so loadable component is starting the challenging part maybe who knows about loadable component there are a few and so the next question is redundant that are you using in a real project or not only for you you are using yep yep nice okay the loadable component is a base class is a base class and the aim to make weighting page objects until they will load so it will help us to make the page object pattern usability like less painful and it's makes more easier to debug the failures because there is a customizable stuff and stuff and a lot of maintainable stuff so there is a currently an implementation in a Java that's coming to Selenium but it's easy to implement in any other language and for that reason I will try to configure custom loadable component also in a Java which I'm doing always because I can also there's provide the error messages for more easy like easier debugging and some stuff like that so I will suggest also not use the native one just create your own one and do anything you want yeah for that reason there's also slow loadable component that coming the next one so it's basically how you are making the class loadable nothing is visible sorry it's just extend from loadable component and with it there is also two methods that you always need to override when you are extending from the loadable component it's a is loaded and loaded so this two method you will implement for every page class so this is the only like a bit of painful part for the after mentioned this there's a lot of people saying that it's making a lot of work to do for every page even I don't need but anyway there is no lot of good stuff without more work so how to use it the pattern also allows you to model your page objects as a tree nested components allows you better navigation between the pages and load methods will use during the navigation and is loaded method will use to determine it when the page is ready to continue this is the get method from the loadable component class this is the 81 that Java has there is is loaded this method will come the next slide there is a is loaded and the loaded so it's twice check is it loaded the page then continues and if it's not it's called lot so this is mostly for navigation so usually when you are just want to check is it loaded or no you are just making the like we are not implementing the loaded method and here there is already in a page object that the over it overrided methods this is a live empty because I'm not trying to navigate between the pages and he is it checks it's wait until the some element will not be clickable after that when it's now we get so if no it's throw the exception so when you are creating the page you just need to call get when you are calling get it's already we'll check the old stuff from the loadable component and you will check that is loaded conditions for you okay this is the thing that I'll also put in a base object class so here we have this and instead of this and also I I I mentioned before the about the page loader helper instead of checking for like in this way I'm suggesting to have a page load helper and click there the old helpers that you will will like help you to wait until something is ready and this is this use the invocation chain and the implementation with the with this kind of if it looks like this so it's more readable and more easy to implement so I just checked the two and you can do dot more this one also loaded loaded this one is clickable this this one is disabled and all this visibility and disabled and enabled methods you can collect in one place and share with the old page objects so here I'm showing the implementation for the base class so the base class extends from the loadable component and then all your pages are extended from the base class and here you are having the common implementation of the loadable component you can see that there is a custom loadable component which mean that I use the custom one so let's check okay I forget show this is the get so in this implementation it when you are creating it any any page object it always will go through the get so it will check is loaded or no in that case you will have exception is coming so in the native implementation there is no that exception stuff it's just catching something when you are creating you can define anything also you won't like time out or some stuff like that and also you can you can use the exception handling for for the method and for debugging you will have a more possibility other page just when you are navigating then you are returning new pages like return new another page don't get when you are doing new you are calling get because we can like be sure that everyone comes from base object and base objects comes from loadable component and it should implement so this is the way how you can implement in any language also and here you can do anything you want this is just the example you can make it more they got debuggable for you slow loadable component is the almost the same but this is waiting exactly for the components this is better for you when you are you have a lot of jacks calls and you know you want to wait for the jacks call this is a subclass of loadable component it has get additionally it has also wait for and is error methods so after a call load is loaded method will continue to fail until component will be loaded this is the main difference with the loadable component okay here there is also you are providing a time also when you are extending from the slow loadable component you have to implement also there like you will implement the super class construct constructor and you will provide the time and and the and the clock so it's basically looks like slow loadable component so it shouldn't be on the base object it should be for the page exactly for the component and I just make it shorter and you in your constructor you should call this like super constructor which is like needs some system clock and the time the time it's the time how many time it should try and the clock and it's the time that it's trying to get several times yes so any questions so far so good I'm running a bit faster because we don't have a time because we start a bit late to not disturb also others but if you have a question that we will yep any any condition that you can think you are we are open-minded you can open your creativity any condition that you want to check you are putting it in is loaded with the wait until like frame will be loaded or something in the frame that will be accessible or something will be disabled or enabled inside the frame so anything that you can think you can apply there that needs to be checked after the creating the instance sorry I have a drop-down a country drop-down which have a lot of values India, Australia, UK, USA something like that so my page is loaded but the drop-down values are not loaded it is sometimes it may take it takes some little bit of microseconds or seconds to load so but my export is pointing to the value not to the element there are two ways of doing it driver dot a fine element go to element that is country and select the value or India you also do like wait until this element will have this value or generally wait until the element will have a value so you can get the element get the value and check that it's not null it's not empty you can try a parent class and wait until that object compared with the child objects this will become a try yeah so with a loadable component we are not trying because loadable component will try itself yeah so you are giving that only condition and asking them asking the loadable component just continue when this is true and it will wait for you you don't need to make a loop you don't need to make a try you just giving the condition and the loadable or the slow loadable component instead of you will try to do something right yeah yeah that that is what I was about to say that's there are some things that need trigger and after trigger you have to wait so what you can do over here is you can you can look for that object and you can wait your weight condition can be dependent on the child objects or the child classes yeah that that way have I have invented in my page object model yeah it's also option it's also option so it's also option and it is quite time-saving that is what my observation is yeah so let's go through also the common failures then we'll use the rest of time for the questions so common failures usually people who say who says me I tried the Selenium it doesn't work for our project we will not use that and the first question I'm always asking you use the Selenium ID with the Selenium one yes so don't use it I I'm working with the Selenium like seven years I never recorded the test even when we were working with a Selenium one it's like some anti-decode that it's fast only for the first stage after that you will crash everything so using the only Selenium one with the recording stuff we'll always fail when you have like amount of the test not building a framework not building a framework it means that people using the Selenium just from the test they are driver click driver open driver do driver that which is will fail when you have like more than a thousand tests so you will for sure use unique selectors this is a bit challenging for the Selenium but the thing that I'm never do I never I'm trying to never use that X-PAP because X-PAP is too slow in the Internet Explorer and when the position is changed your tests are failing so use the IDs which are unique or the class names if I unique that people usually says that there is what if there is no idea or something like that my approach is just work with the developers so push developers to add unique stuff automation also development so it's not a secondary project I know that in most cases they are saying do whenever you want so it shouldn't be the case that you should you are you are also developer you should also work with a software developer push them to add unique stuff and make this like more stability in your tests and also another case in this topic I'm always pushing developers to get familiar with the tests they are not supposed to write but they should be aware how it's working so when they are making changes so they should understand that it can break given not like early notify a notification or doing like fixing themselves do not use that retries you will fail when you have a thousand tests and you are running on the service clouds one day you will fail even if it works for you now do not try automate things that are not automatable okay basically theoretically everything you can automate if not with the same with other frameworks but don't try to do that because sometimes it's easier to check from like every regression cycle so having someone some manual tester and someone to check it like during the half an hour for every release then automate everything spending some days for implementation and spending some hours for the maintaining them so it's better to not have to make like a lot of stuff and run your automation tests sometimes if you have a suite run them break them fix them do everything you want but just run them not wait for a six month and then find out that nothing there's no test are passing in your environment so the breaking the bills and fixing the bills the most fun part of the automation yep so we are running yes we are running out the time just if you have any question I will be here till the end of the Sunday we can talk we can try to go together we can try to find a solution for your problems and whenever you want sorry it's my name surname is visible thank you for coming thank you organizers to making the opportunity and enjoy the rest of the conference do you somewhere in the loving