 because technically it's a bigger topic and what I want to do is actually just go over some basics how to have a design pattern that we can work with that we can understand and go over some basic things that sometimes because it's test code or it's something that a student started and now we need to maintain it causes problems and it causes problems because no one actually understands how much time we spend on it until it's very much so a viable thing that we can't release without and then it becomes a rigorous process of all the time going through this we don't understand what and what those tests are doing sometimes we don't understand what the logs are doing sometimes and we every time we try to do something we're breaking everything else so in the end this is a software and a very delicate one so to answer that big question yes it is very necessary clean code and design patterns when you're doing your testing because test code is code and test code is software as other software so so what is clean code in a very very kind of basic level so clean code is a reader focused language and the idea behind it and I'm gonna gonna kind of gone through this a bit this presentation because I want to also have like code examples and not just uh pseudocode that we have in the presentation so if I'm too fast let me know okay so concept between clean code is we're not writing code for the machine writing code for other people who are right or reading our code to actually be able to understand this is the ui testing so yeah not to say the programming is the art of telling another human what one wants the computer to do and this is something that is the basic of what we need to understand when writing our tests and now why clean code in your testing like specifically in your testing not in life first of all code is your pride it doesn't matter if it's your ui or not something you put your name on treat it as such let's face it writing clean code makes our life easier it's true it maybe is a rougher start in the beginning but when we are already in the process of doing things it's easier because sqa or automation or software engineers or any other profession around that people are working on it you need to read a lot of it and understand a lot of code because you're a professional and this is the industry standards of being a professional now and a big one is because in automation specifically and ui testing it's documentation of user behavior which unlike unit testing or business logic this is how a user behaves and this is a living documentation unlike aesthetic documentation that we have which is obsolete most of the time so let's talk about guidelines so readability of course we don't want to have any redundancies easily extended by others forget what you heard smaller is better and focused so let's take a look at this and i'll ask you what is this the blue part yeah certainly i haven't taken that into account but it doesn't matter really i guess so this is a very this is a very sudo code thing that does something and even if the blue part would have been readable it's ids and clicks or something so generally it's a fine element id and id it's very still like selenium like binding some nodes yeah it's it's selenium with nodes in a sudo code way yeah but the idea is that it's if a person who's not in the code would probably not understand what's going on here so let's just focus on this for now this does this and the idea that we have here is talking about readability first of all let's try to take our code who's nasty and move some parts of it to other places where one spot will be readable at least that segment this is a very easy way to do that so login to imdb that gets username and password and now our code looks more like this so we already have some context and we continue on forward then let's talk about redundancy so most likely if we do a login to imdb we'll have login to imdb as the default user as a netman as whatever most likely we're going to have a lot of those so let's create another method let's call it default user for now whatever will happen later will happen and let's say that username and password will come from in the in the future from configuration hello hello hi as we come to yeah you're in the right place so no redundancies now everyone can actually add on other things and use that test as that method of login and extend it say okay in this one i want the administrator right i don't want to do it and so on easily extend by other let's generally in a very kind of awkward way say kind of let's add logs here it's very simple but then this is how it should practically look and yeah i am very sorry about the font and the fact that it's in dark but i hope i can maybe somehow adjust it trust me you're doing much better than i did when i couldn't even connect my laptop oh no yeah i asked someone else to give me his laptop so things is so anyhow um so what can you see the method signatures at least or is it completely off so i'll just read it out about that so we have we're breaking everything apart so instead of having this very big method of having okay this is login with a lot of driver codes in it we're just taking things away from it and now we have okay let's have open indb let's have set username that's a password and in the end we'll probably want to click the login and now our method of login to indb looks different it looks well you open indb set username set password click login button and we're still have the login to indb as default user this is the way we're readable so another obstruction another time where a disgusting code is being pushed back and easily extended by others is also now where we have a remember me checkbox or not we can just easily edit this is still readable let's talk about now code repetition and smaller so let's look at look at this so we have here the same id and the same call but technically this thing now is going to repeat itself every time we're going to do those things so technically what we can do is just break apart this thing and call it set text because in selenium for example you need to clear the input to set text if you want to set text from scratch it's an example in other places you might not you might not have to do that but we can abstract that and then decide on that obstruction there so if we have set text you can do this now we can do every time we want to put fresh text just clearing it and then sending the keys in selenium and this now how it looks which is way nicer and smaller this is our class now okay let's talk about focus and this is a big topic because and somewhat controversial sometimes focus means that we have three asserts here on this on this test that we have that we're still not sure what it's doing because we know that's the beginning to imdb but the rest is not clear for us but we have asserts that are we have a certain then goes to another place and another certain goes around place i would argue you might want to have one assert per test or at least several asserts that are in the same logical realm so if you're testing one thing and then you're going forward to another place to test another thing that's already problematic because if the first one fails and the second one is not related to the first one then you can't test other things as well so focus is very important here let's then have our tests more focused now so let's go through some guidelines that we have and that's sort of facade because right now we created this thing which we didn't really know what we're doing we just took things and put it somewhere and what is this thing then so we want to have one interface to speak with and we want to have our automation third party be easily replaceable conceptually as i said we had this set text now we have selenium as our third party but maybe in the future we don't want to have selenium we'll have something else maybe we don't need to have the clear and the and the sent keys we want something else and that's the idea is it's one place to go and not search and replace everywhere we have those things you can intervene into parties methods and in a simple way you can actually just start tracking or changing things that are happening there and saying this is not how i want to implement it or this is what i want to happen as well in my interpretation of this and you can magnify the third party methods with the same interface currently have so let's talk about now the ultimate facade pattern of testing which is page objects i this is very well known as page objects i'd like to kind of our prefer to quote view object because today's world we have single page applications and people are asking well if my entire application single page application like yeah okay let's more get it to focus is a view a view changes even though if it's the same page and also for mobile mobile is more view related not pages so i'll use the page object because it's known and then you can google it if you want if you don't know it which is i assume some of you do because it's very well known so page objects are some sort of an api to a page or a view and the idea is if for now i have a login api i know my endpoints i know that i need to send a post request with an object jason of my username my password and i know that if i'm fine and good i'll get i'll get confirmation and i'll put you forward with the i'll ask himself then what is the login page for me is an api something that gives me something and i'm asking myself okay what can i do in a login page i can set a password i can set the username and i can click login and that's the idea so the idea is a page object will give you a code interface and that will talk to the html behind or the javascript behind so it is just another section layer on top of that so let's take a look at our login example so we type our username we type the password we can put in button and we're this is also yeah we're expecting failure success and this is something that's also good to have is if you write those things and once you write those tests you see that sometimes you want to test a failing scenario which is kind of similar but different so you have a similar flow where you do the login but one of them will say we expect now you to move to the home page one of them will say we expect you to stay where you're at and this is something good to also have is this what you're expected to have on your method so let's call those things then more services so what how what do do the services do so we need to have a look begin page object as said and we will set a username password login as default user and still we have a problem because now we have this really great facade pattern oops um of a login but we still have driver all over the place we now created this really nice thing where we have selenium on a login page selenium or on our home page but we still have driver all over the place and this is not really a facade layer or an obstruction layer if we have many many many obstruction layers on many many many different pages and the idea is is to create a base page a base page reps selenium or whatever third party that we have and we extend there all the basic operations of selenium in the same example so if we want to have find element we extend that fine element as well we take it and then we maybe add logings if you want to have a debug or something and it happens once and then we can easily just extend our page pages so for example our page object summary um so we call it only design pattern or a view and page only exposed only the services provided and does not expect exposed selenium it doesn't even know what it is um page objects is not a test don't do any asserts on a page object a page object is an api hey can you do this i want to set a password i want to i want to set this username i want to continue on and methods returning page objects so and this is very also it's supposed to be fluid so the idea is if i click login and i expect to move forward i expect to get a home page i should return the home page in so technically whoever writes the test can say page equal new login page login page click login this default user so if you do page equal login page login we are now on the home page we get the home page into our page so we can continue on in a fluid more in a fluid way and we continue on using clinical principles because this is very important as well needs to be readable so let's look at an example of a page object hierarchy so we have this thing so our base page and i will show more code examples so excuse me if this would look um a bit more awkward now but for now as a structure we have selenium that talks to a base page on a base page it talks to selenium and that's it no more driver anywhere else and how it would look is like this so if we have driver get we'll call it navigating our abstraction why not we have element click i just call it click for now element clear and element type will be set text for us oops and element text will be get text because this is how we prefer to have this is how we write code in our standards and so on and continue on and now we have a login page so how would that actually look then so our login page will inherit then the base page and we will talk we're in our language so for us set text is the better way than send keys and this is our standards and that's how we will talk and we will do our login test now we have our application one base page also inherits from the base page but now it's very interesting because this is imdb this thing is everywhere in imdb aside from the login page you can find it in all the pages so this technically is the application one base page application one is imdb we might have different applications so we will just take this and say well this is our search bar or application imdb base page and everywhere else we will create we'll just inherit from that so this thing would extend again this thing would extend base page base page will extend selenium and then we get all the time everywhere we're at doesn't matter what we can still do page dot search okay so now let's take a look at other things in our imdb example so we can oops yeah so we have on the side this thing exists sometimes i it's in blue or something and we continue on and this is the content this is the view of the home page technically and this thing kind of has other pages that exist on but this is specifically and only exists in the home page so what happened to our original testing we had this thing and now technically we have this thing because you made it more focused and now we have this certainly the blue is still i'll read it out loud and we have our page is equal new login page and page is equal login page login to imdb as a user which will do this we'll do search for ryan Reynolds that pool is happening now um clearly affected um and now what we want to do is test that actually the search is working so we'll do a cert equals search result page get the search result number one get the title should be ryan Reynolds awesome blossom and now we're talking about more asserts that are fine because i brought up the case of don't do as many asserts or more than one anyone test but it's okay to do in the same logical rounds or if you want to test that not just the name works but also the actor or the movie is known for because it comes from different databases but for the user it's the same like click on search i just get information and i want to test that that is fine because we're not doing any interaction we're not doing anything else we're just testing that this page works properly we got to the page already so it's okay and now minor fixes here we can just say actual result instead of doing search result page you get the result on all of them and then it's a bit more readable and that's it practically so what is this this is this it is exactly the test that i kind of ran through and thank you and that's a presentation and now if there are any questions great like sorry if i ran through it and if not then i can show some javascript things that were very minor javascript thing let's open this for answer or a question answer for something so i have a comment so this is pretty much how selenium tests are implemented in javascript in media wiki core if you open it this is what we did so i mean did very influenced by it or did we just came to the same conclusion independently i think we came to the same conclusion independently and it's also very industry standard and way to do that i was also following whatever i thought was a good idea yeah no i as i said this is automation 101 or 102 depends how we want to find the basics it's more making people understand how and and yeah i'm very happy that this is how it's implemented i thought you were based in code from there that's awesome so if you want to see this in real world go to media wiki.org slash selenium there will be a no js link and click it and there will be a list of repositories including media wiki core that have just like this so you can cool actually see how it's done and and one of them is like there's at least one wiki base related oh cool okay look at that any questions comments so oh no it's your computer legec i will find then the github repository that i wanted to show you yeah so i have some code examples here that i would run through all of you if you want and now i can just do this as well so that's this is not comfortable in any way okay so this is a very very basic thing that i created recently relatively just as a concept i forked someone else's code and i actually saw well it's not great and i decided to actually make it better and it's not the perfect solution it's still just like an example so it is an imdb one we can take a look at the library that we have so here i would love to actually take a look at the pages and go start with base page so the idea is that first of all the base page is the only place that actually speaks to the selenium or the web practically so we import it here and here only and we're done with it and we initialize this is also where we do the setup setup should technically go and be in a setup class maybe taking form configuration but for now as i said it's an example and we have components because a base page in my experience tends to be big too big because if you start mimicking what selenium is giving you you get a point where you have a 200 or whatever lines in your base page which is also not a good way to work so what i did is i i kind of stripped down the components of selenium and moved them into components so whenever i want to do text just return new text component whatever i want to do fine i'll just do fine component and wait interactions and then whatever more we want is the opposite of a mech from the scroll so let's take a look then at an example of components just for fun and then continue on yeah why not so for example for weight we have different types of weights and we want to have weight for visible element or weight for element or whatever else you want to implement here so whenever you do whatever session or what we call it in weight you can do weight for visible element in the selector and that's the idea the idea is just to kind of keep our base page a bit trimmed and more readable and then we can take a look more at pages and specifically let's take a look at the homepage for now so yeah so what we want to have here is like we import or we extend our imd base page we do our constructor this is not a good example because the driver is still here shouldn't be but as i said kind of with the working progress on the audit and we have like get suggested trailers and submit search this text get elements text which is something that doesn't really exist in selenium so it's an extension which was written in those in those things makes it easier makes it easier to work with and then it's in one place only so it's always in the end you do something your extension your component and then you can add some things to it and we have logs and i also think it's a very good practice in those in those components and in your base page to have like a debug or trace event so in case the things are really failing and your logs are not enough because you don't want to have okay click here do this this you can actually run and just see whatever like everything that happened if you're in a needle in a haystack scenario and here again components and quickly it so we have the get and we have a set for text and we have get element texts and i'm not saying it's the best implementation saying it's something and we have like an example of what a log debug would look like if we had one and this is the idea the idea that this is completely detached and if something is broken it's one place it's easy to find and yeah that's generally how it looks and i would be happy to share with you as well and if you have any questions or something you know wise i was really fast yeah yeah so there's one question from someone watching the stream okay they asked why not headless chrome have you not used it headless chrome well i don't think it's related to this right now um i i mean headless chrome is a browser infrastructure isn't i just hard-cold chrome here the idea is take from configuration whatever you want i was i'm more talking about how to architect your test environment and your test solution headless chrome works great you want to test on safari if it's possible great when it's done whatever it's great i'm technically don't care about browser in stock even this officially would run also on mobile if you use whatever other selenium to mobile extension that are there so it's more conceptual not down to browser or whatever any other comments on that you could use headless chrome with this code there's no reason i think he meant because i in the example itself i wrote chrome and which is example of like hard coding the chrome i said you need to take it from configuration or environment or whatever this works for chrome this would work for android if the library supports that which i'm not sure i don't know if it's good or bad and then i guess that thing thank you very much is it the one is it the one that doesn't have to do 10 for everything is it like