 I've got a few questions for you, hoping to learn a few things from you today as well. And actually also, so during the talk, if you've got a question, if I say anything that isn't clear, or maybe it doesn't make sense in some way, just put your hand up, ask me the question. For during the talk what I'll do is I'll repeat the question for the purposes of the recording. And then we'll have some time at the end hopefully for some other questions. But try to save the in-depth questions for the end. Just clarifying questions during the talk if that's okay, just to make sure we get through everything. Is that okay? Awesome. Well, according to my laptop, it's still not 10.30, but I think we've got everyone in the room. So if we get the door closed because of the noise, it seems that they need a screwdriver to get the door closed. A crowbar, wow. Normally don't you need them to get the doors open. Right, we're going to start. So good morning everyone. How's the conference been for you so far good? Yeah, learning a lot. Awesome. I want to ask you guys some questions. Just a few things just so I can get to know you a little bit better and I'll tell you a bit about me. And then we're going to talk about some stuff. So I wonder how many people in the room here are testers? Most of you. How many are developers? How many of you use Selenium day to day? Most of you. How many of you use Selenium by writing code? So why didn't you put your hands up when I said how many developers are in the room? So we're all developers, aren't we? If we're writing code, surely. Would anyone disagree with that? See, I see it as, you know you have some developers who specialize in developing trading systems. Or you have some developers who specialize in developing mobile games. And some developers that develop iPhone apps. And some developers that specialize in trading systems. When we're writing code using Selenium, I see us as developers who specialize in test systems. We're writing test systems to test other systems. And it's still, it is a business domain that we work in. And for me, learning as much as I can about object-oriented programming, good design principles, are just as important as learning about exploratory testing or combinatorial mathematics for testing purposes. Would anyone disagree with that? If we're writing code, is it also important to learn to be good at writing code? Excellent. How many of you have heard of solid design principles? S-O-L-I-D. If you put your hand up, I'm going to ask you to tell me one of them. So put your hands up if you know solid. Few of people, right? Anyone? Oh, I've got one person, two people. Anyone, solid? Oh, go on. Simon, tell me what does S stand for? Single responsibility principle. Has anyone heard of that? What does that mean? Simon, go for it. That's right. The single responsibility principle is that a class should have only one and one only responsibility. Another way of thinking about that is one reason to change. And what we're going to be talking about is some of the key design principles used in OO and how we can use those to move forward from where we are when we're using page objects. How many of you are using page objects? Right, cool. Right, so let's get on with it. Found out a bit about you, a little bit about me. I've been working in the software industry for over 20 years now. And I've got the grey hairs to prove it. I've earned every single one of them through the stresses and pressures of having to deliver in tight time scales. Just like all of us. And a long time ago I started a website called Testing Reflections. Used to aggregate a lot of the stuff about agile testing on the web. Also worked with my colleague here, Andy Palmer, on something called Pair With Us, which is still out there. You can find it on Vimeo. It's like a live, unedited screencast of two people pair programming writing some stuff. At the time it was ages ago we were writing some stuff for fitness. And also, if you've read any of these books like agile testing, agile coaching, Virginia Communication and Gap, you'll have seen my name in there in a few places, some sections I actually wrote. So if you didn't know my name before and you've read those books, you might go back and say, oh, I know him. So we're going to talk a little bit about page objects and how they came to be. And I'm really glad I've got Simon in the room because I'm going to challenge him to recall a conversation we had in the pub one day a few years back. I can barely remember it and I think he was a few drinks ahead of me that night, so I'm not sure if he'll remember it, which is good because I can just make stuff up and he can't disagree. I'm going to talk about solids. What is it and why does it matter? And I'm going to introduce something called the screenplay pattern. Now up until probably about six months ago that was called the journey pattern and that's because we didn't have a better name for it. But since then we thought actually no, there's a better name. It makes more sense and it's called the screenplay pattern. So if anyone's seen anyone talking or writing about the journey pattern, this is the same thing and actually you'll find out that it was something that actually I came up with in 2007. 2007 seems to have been quite an important year for some reason. I don't know why, but people came up with lots of ideas in 2007. Simon, didn't you come up with an idea in 2007? Fagri, yeah, something called WebDriver I thought. So way back when, when Selenium first came out, one of the common complaints that people would say is that tests were flaky. They said, oh, Selenium, the framework, it's not good, it's buggy, it's got problems, my tests are failing for no reason and people will complain about it a lot. And then I remember Simon actually wrote this. I don't think he was drinking at the time. Stone cold sober. Stone cold sober, yeah, absolutely. And his point was that Selenium was not unstable. The problem actually was that the tests and the programming practices used in writing the tests were causing the problem. And the problems were coming about through duplication because people were writing the same series of steps in many different tests. If they wanted to register a user, for example, they kept repeating the steps for registering a user in every test where they needed to register a user. Rather than putting them in one place. And that was the common characteristic. Duplication was one of the common characteristics in environments where they complained about flaky tests. I know, because I was often asked to come in and say, please help us sort out our tests, they're really flaky. And I'm like, well, that's because over here you've got a slightly different way of doing this, but they're basically the same and we'd find all these issues. And Simon talked about that around the same time. So what is a page object and how does that help us? So let's imagine an application like this. It's hard to see there, but at the top you've got to-dos and it says you've got a place to enter the to-dos. It doesn't come out very well on a projector, unfortunately. You've got a place to write to-dos. One of the to-dos might be to walk the dog and this to-do here was something else which I can see here, buy some milk and that to-do item has been done. So let's imagine an application that allows you to manage your to-do list. Pretty straightforward, okay? Hardly anything there, you can imagine a page object for that page would be quite small and simple, yeah? Would you agree? Hmm. Let's see. Let's see if what your idea is small and my idea is small is the same. Anyway, so what's a page object? So a page object, oh, God, this comes out bad. Can you change- is there a way of changing the projector contrasts? Is it possible to change the contrast on this? It's very- the contrast or the- it's too bright on here? On the projector, yeah? Thank you. So while he's trying to do that. So this might be something along the lines of a page object. A to-do list page, you've got the ways in which we can find the elements on the page which would be the fields that we'd have on it and then we'd have a bunch of methods for all the different things you can do on that page. I'm not going to show you the page object for this because I didn't actually write one because I don't work with page objects. I don't use them anymore. So you see you've got how we find the page elements and the tasks that a user can complete on that page. Is that a fair way of describing what a page object is? Would anyone have a different way of describing it? So how to find stuff and what we can do. Yeah? Cool. I looked around the interweb and what I found was quite a few different interesting examples of page objects. Put this to one side for a second and I found this particular example somewhere. It's on GitHub. It's just a typical example. You've got some ways of finding the elements on the page and here's how you add a customer. Now what I did then is I zoomed out on that particular class to see what that class looked like and this was for a very simple web app page. It didn't really do very many things about five or six things but it ended up looking like that. Can anyone tell me what's wrong with this? The boss? Let's go back and have a look. Not really. It kind of does what it has to do. It types stuff into the page. It clicks. Yes, too many things on the page. Too much here makes it really hard to find. When you want to add some functionality you've got to find where in this do I make that chat or if you want to change some the way something works you've got to find where in this do I change it and you've got to search and control F. That all takes time. There's a book called Clean Code by Robert Martin or Robert C. Martin affectionately known as Uncle Bob. Has anyone heard of the Clean Code book? There's a good set of principles in there and one of the things that he talks about is that you should be able to understand what a method does within a few seconds of arriving at that method. You should understand how it does it as well within a few seconds of arriving at that method. You should be able to understand a whole class within a few minutes. But if you're sitting here for half an hour trying to understand what's going on here before you know what's changed that's making the time it takes to add each test take longer. Yeah? Cool. So there's another useful mechanism that I use when I'm looking at code and I think, how can I learn, how can I figure out what's wrong with this? Because actually when you look at that class in detail there's quite a few different things that are wrong with it. And there's this concept called code smells. Has anyone heard of code smells? Yeah? Anyone name a code smell? God Objects. Yes, sorry. I couldn't hear you very well. God Objects, another one. Lot of methods in the class. There's a named smell, but yeah. There's a name for that one, which is, but that's cool. Sorry. So a long method. That's another example of a code smell. Which one do you think applies here? The smell here is large class. It's a large class. And all that does, all that's doing is it's telling us that there's a potential problem, a deeper problem. And it might be that what we've got in there is duplication. And it might be that we are using more lines of code than is necessary to say a very simple thing, which we've seen on our travels many a time. So when we detect that there's a smell in our code like large class, then there are some tools that can help us, thinking tools that can help us solve that problem. But one of the challenges is how do you know when it's a large class? I mean how big is a large class? How many lines do you think is what do you think is a reasonable size for a Java class? Anyone? Let's say 1,000 lines of code. Is that okay? 500? Let's do this. Everyone put your hands up. Put your hands up. Keep your hands up. Everyone hands up. All right. Keep your hands up if I've said a number that is okay for a large class. 10 lines of code. Is that okay? 20? Why? For a whole class, 20 lines is too big. I don't know. I'm not sure about that. Let's see. 30? 40? 50? 60? 70 is okay? 80 is okay? 100? 100 have gone down? 150? 200 is okay? Okay. Interesting. We've all got a different idea of what is too big for a Java class. That's a very interesting problem because often when we're working with teams getting the teams just to agree on at what point should we really think about refactoring this class and actually breaking it up into something smaller? Those are the first things you've got to get to. Many, many, many millions of years ago there was a general rule that a module should fit on a single screen. Now screens were a lot smaller. They were very low resolution in those days. So only very few lines of code could fit on the screen. Now with huge screens and high resolutions we can fit a lot on a screen. So it was James Lewis. James Lewis, the guy who's better known for talking about micro services says that a Java class should be no bigger than his head. So it doesn't matter how many lines. For us that's probably about 40 or 50. If you've got a pretty big head maybe it's a bit more. But a Java class should be no bigger than your head. Has anyone in here been told that they've got a big head? No? For anyone that missed that if you have a big ego that's why Simon put his hand up. So what can we do to arrive at a better design for that page object? So there's some key principles that we can use. These were talked about I think it was in the early 2000s. You'll find these in a book called Principles of Object-Oriented Design by again Robert C. Martin. So the solid acronym was arrived at by someone called Michael Feathers who wrote a very good book about working effectively with legacy code. So the solid is an acronym to help us remember the single responsibility principle, open closed principle, the list of substitution principle, interface segregation principle and the dependency inversion principle. Now you've probably used many of these without realising it if you don't already know them. If you do know them then maybe you're using them and you recognise that you use them. Because we've got limited time we're going to focus only on the first two. For me personally and for my colleague Andy who I work with a lot we find that these two are the predominant principles that we find emerging when we start to refactor classes, particularly large classes. So let's look at the first one the single responsibility principle. So this is a definition of it from Robert Martin. But as I said before the main thing is there should be one reason to change a class. Only one reason. The open closed principle this is a definition again and it says that a class should be open for extension but closed for modification. What that means is if I want to add new functionality I should be able to write a separate class add that to my code base and it should just work. I shouldn't change any existing classes. So let's have a look at those two. We're going to see what happens when we take a page object conceptually. Everybody spends a lot of time working with code. So we look at conceptually how this might play out. Let's go back to this page object which is the to do list page and it's got some ways of finding stuff and some ways of doing stuff. How many reasons can you see for this to change? General reasons not specific. Any suggestions? The clues in the name the single responsibility principle. If it has more than one responsibility it has more than one reason to change. So if the way in which you find an element changes it has to change. If the way you do something has to change it has to change. So that's two reasons. Straightaway. Would you agree? So if we were going to split this class up one of the things that we could do is separate it so that there's only one reason for it to change. For example, how to find page elements or how a user completes a given task on that page. So let's take a look at what you might do so for something like that you might just take out all of the elements and the references to them put them in one place and the things that you can do on that page and put it in another place. Who can tell me what refactoring is? Anyone? So refactoring is improving the internal design of something without changing the external behaviour. So our tests would still work if we separated these two things out so this would have to refer to that class. That's the only thing, but the test would still work. So the behaviour would stay the same but we're separating it out so it should theoretically be easier. Now, the thing is this is basically just data and we might represent it in a class, we might represent it in enum now. We might even put it into a properties file or a JSON file and load it dynamically because really that's just data, that's just some names for things and some vectors that we're going to use to find them. So let's just put that to one side because that's just data now as far as I'm concerned. So let's look over here. How many reasons do you think that's got to change at the moment? So if the way that we added to do item changes it changes because that method will have to change. If the way that we filter items changes that class has to change. I've listed four different reasons for it to change now because how we do each of those tasks is going to change. So again, the single responsibility principle would lead us to split that up. However, what if we said no, that feels uncomfortable so let's go back again, let's start over let's try a different refactoring. So let's see what happens when we split it up based on the things that it does. So now we've got a new to do up here and it's got the way you find the element the new to do element and how you add a to do item and how you add multiple to do items. Now this is actually a lot more like the way Martin Fowler describes page objects so if you do a search for Martin Fowler page objects he talks about page objects more as objects on a page rather than objects that represent a page. So rather than it being the whole page they are the objects or the widgets and that was inspired by the work that Simon did back in the day. So this is another way you could split things up and now if the way that we add new to do changes then we only change that if the way that we add we maintain the to do by saying Martin what's complete what's incomplete then we only change that probably a better split altogether and actually the teams that I've worked with have had the least maintenance problems with page objects have generally used this type of approach but there's another way of splitting these up that makes it even easier. Now one of the interesting things about this is that this now doesn't satisfy the open close principle so it kind of satisfies a single responsibility principle but not the open close because if we want to add a way of maintaining our to do's we now have to change that class if we change the way that we maintain to do's we have to change that class now we've got two different reasons for it to change so we need to split them out a little bit more so the refactorings the names refactorings we'd apply here are extract class and a lesser known one or a lesser referred to one in my experience is the replace method with method object. What that means is we'll take a method extract it and put it in a class of its own. That one method becomes a class in its own right. So if you think about it these are task classes because each of them describes how to complete a given user task. Make sense? Now again for me this is just data it's a mapping of names to selectors that's just data if that was in a class or an enum or even dynamically loaded from Jason it doesn't really matter to me so I wouldn't look at changing that because it's just a data object now it doesn't really have any behaviour as such but these do have behaviour so now if the way that we change how we add a to-do item changes then we change that so it's only got one that one, thank you so if the way that we change how we add a single to-do item changes then we only change that class that's the only thing that changes nothing else now it's only got one reason to change. Also if we add new functionality to the page there is a new task that you can complete we add a new class, we don't have to modify anything so they're open for extension but closed for modification we don't change them as such and in fact technically I could change the behaviour of this by writing a new class that wraps that class and hides it away and adds the new functionality around it so again it satisfies the open closed principle. So are there any questions so far? So this is to me this is just good OO design applied to page objects and when a page object is small probably leave it as it is but once it starts to get bigger especially if it gets close to being the same size as your head that's the time to look at splitting it up and I hope I've introduced you to some ways of doing that. I'm going to go on to some more in-depth stuff about showing you what this looks like in practice but I've only questions to clarify what I've said so far I saw a hand here. That's a fantastic idea. Let's take a look at something like that in about five minutes time and that's exactly what you do. So if you have something that you can give the task to that expects a performable interface and that performable interface has the perform method on it then they will work you can just have one thing that knows how to perform tasks and that's it. So we're going to come back to exactly that in a few minutes. Any other clarifying questions? This one calls that one by iterating over a list. There's another hand up just here. Yes, you will have more objects more individual objects and I'm going to address that shortly. I'll show you how that affects the ability to discover what a thing does. Good. Okay, any more? What would happen to the base page object? Would you even need one any more? You might not need one. What you might have is you might have an abstract task that does any of the common things for tasks but the concept of a page object would cease to exist so you wouldn't have a base page object any more. Any common behaviour between all of the tasks you could solve by having a parent task, an abstract task that these all inherited from you could but you wouldn't need to. One of the key things that's coming out here is that we're favouring a concept called composition over inheritance and that's another positive programming principle for OO. That way we can add common functionality by composing a class so the task could be constructed by injecting a common task, common user task and it could use that to provide the common behaviour so then you don't have any inheritance. When you have inheritance has anyone experienced where you have parent classes and child classes and more child classes have you found that as soon as you want to change something somewhere in the middle it suddenly becomes a very painful process whereas when you compose the objects they're all much more malleable and moveable. You can move things around in one place and it doesn't hurt you in others so in the interest of time I have to move on. So we're pretty close I think we're pretty close. I think we're all roughly on the same page here sorry I couldn't resist that. Right so there's another problem one other problem and sorry Simon this is something that's always bugged me about page objects but this is just a personal preference thing so it's not right or wrong it's just something that bugs me. Could someone, who knows how to use Google anyone? Put your hand up anyone? Okay this gentleman here so you know how to use Google can you explain to me just how would I find information about page objects? Go to the Google page fill in my question Selenium page objects I'll fill in my question Selenium page objects and click search okay brilliant. So you're told what am I what am I a person yes the person's good I'm a person I'm a person am I am I a browser am I a driver yes I do drive cars am I a web driver this is only a personal preference and a personal style thing for some you create the thing and every time you call a method you're sending a message to that thing and that thing is under your control but one of the other things that we can do and this is an idea borrowed from domain driven design if anyone's never heard of that or if you haven't feel free to look at a very interesting book about how we can incorporate the thinking around the problem domain all the way through our code base for me what I'm trying to model in my test is a user I'm going to be telling a user to go to the homepage enter your question and click search I'm going to be talking to a user so one of the things that that thinking can do for us is you can just apply that in how you name your variable so when you create your web driver that could just be a user and then suddenly all the methods just read exactly like you're talking to a user anyway and that works perfectly well however just going back to the suggestion this gentleman made about what if we had something that could just execute tasks so let's have a look at something that comes from user interface design so there's something called task analysis and this is something that people that do training people that do user interface design a user experience design will sometimes use what they use is this concept of trying to understand the role of a person like who is it for what is it that they're going to and then what's their goal so what are they trying to achieve as an outcome so when they're designing a user interface we'll know who it is why they are there and what they're trying to achieve as an outcome what tasks they need to complete to achieve those goals and for each task what actions or interactions like click type etc what interactions will they perform in order to complete each task so if we take that model that thinking of a user or let's say an actor who's playing the role of a user then what we end up with is this kind of mindset where your test script is essentially a narrative for each scenario each test scenario you can have a cast of actors playing the roles each actor can perform tasks and those tasks involve interactions which they perform with their abilities so for example I have the ability to browse the web I have the skills of knowing how to start a browser interact with a browser click on things type things and so on and when you apply the same principles to refactoring the page objects to and domain driven design thinking when you think of the domain like this what you end up with is something else which we call the screenplay pattern we call it the screenplay pattern because you have actors and your test script is like the play they're playing roles sometimes an actor can be a supervisor user sometimes an actor can be a book buyer sometimes an actor can be different roles the idea is that we have an actor that performs tasks that was his idea by the way I just quickly implemented that just two minutes ago because he said I should have an interface for tasks which I do so actors perform tasks tasks are composed of actions actors perform action with their abilities they can also ask questions and all of this stuff can be done on the elements of a screen so let's look at a real example as we bring it to a conclusion so let's take a user story like this just in time kind of guy and he wants to capture the most important things he needs to do so that he doesn't leave so many things until the last minute that should actually say Anthony because I am notorious for leaving things until the last minute have you heard the phrase leaving things until the last responsible moment have you heard that phrase in agile development okay I'm the guy who leaves it until the last irresponsible moment so this application was literally made for me so let's say this is what our test could look like if we were writing it in code if you like working with BDD type language then you can have given that James was able to start with an empty to-do list or you could just say James attempts to start with an empty to-do list you don't need the given that now start with an empty to-do list is a task so how many of you write code in Java most of you, a lot of you, most of you how many of you use the sort of assert that type assertions from Hamcrest then you're used to working with things in this way do you know how Hamcrest works so when you say assert that something, comma is equal to what happens then equal to the method equal to doesn't actually compare things what it does is it creates an instance of an equal to matcher with the value that you've given it and then what happens is the assert that method takes the expected result and the matcher and puts them together and that's exactly how this is working it's exactly the same principle so this gives you back an instance of a start with an empty to-do list task this one gives you back an instance of an added to-do item task this gives you back an instance of the items displayed question look Hamcrest matcher right there so what this thing is really doing here is it's just saying this is my expectation and it's comprised of a question which is the items displayed and a Hamcrest matcher and the result of those two is brought together so is anyone ever written a custom Hamcrest matcher a couple of people so sometimes you can actually write Hamcrest matchers as well in Hamcrest so when you want to add a new functionality to Hamcrest you don't have to edit an existing file you just write a new class what principle does that satisfy open, closed principle exactly so it's exactly the same principle that we're applying here now these examples are actually already implemented in a framework called Serenity so a colleague of ours called John Ferguson Smart worked with us we showed him how to do this stuff and he was so excited about it he implemented it into their entity but the amount of code that you actually need to make this work is so small that you don't really it almost doesn't justify having an open source framework you can almost do it yourself but if you want to see how to get started some of the examples are in a link at the end of the slide deck so let's look at how we could create our actor where did James come from so James is an actor we're going to call him James because we're going to use that in some reporting features in Serenity but that's just coincidental and we're going to tell James that what we can do you have the ability to browse the web browse the web is really just a wrapper around web driver that's where the web driver functionality exists that we can reach out to our ability to browse the web and apply the skills that we require so what we can do we have an actor and now we can give him an ability this is what your page object would be reduced to it's just some data saying a bunch of things and here's how I'm going to find them in Serenity it so happens that there's some extra reporting information so here where it says what needs to be done that's just something that's going to be entered into the reporting but really all we're going to look at here is this is the CSS selector and this is the name we're going to use to use that CSS selector and we'll get that data and we'll use our abilities later to get stuff from the page and on this particular subject here we didn't even need to say this much and actually if you're at the end of this talk in room 3 after this talk is another talk by Andy Palmer on a concept called robot handles which I highly recommend you go to see because it dramatically reduces the amount of code you have to write in your tests when you're trying to explain how you interact with a page so room 3 straight after this at 11.30 you highly recommend Andy Palmer's talk so here instead of a method we now have a to-do item class so instead of a added to-do item method on a page object this is a task object remember we talked about the extract method to method object that's what this is now what we tend to do because we find that the information that people are most interested in is actually this information at the top so how is it how do you add a new to-do item that's what people are mostly interested in a constructor like down here or a factory method like here that makes it a read a little nicer in the implementation we tend to put those at the bottom for the task classes and if they're all like that and they're consistent people get used to it very quickly but usually what you're interested in is the information at the top now this is interesting this thing here is a lower level of a performable activity and this is an action so what this is doing here is exactly the same method again it's the actor we pass the actor in the actor attempts to complete this particular task what this does it returns an instance of an enter text interaction it's performable but it's an interaction and then it defers the execution of that and then executes it afterwards so it works in exactly the same way and if you want to look at the implementation of how that works what that's doing is that's wrapping up the interactions you make with the web driver api any questions about this this is an anonymous class this is an actual class file that's also an actual class file somewhere that's not an anonymous class there is actually a class called enter the value sorry and this method here is a factory method so it creates an instance of entering text and then you build upon that using a builder pattern where you build onto it what text you want it to enter and then any subsequent interaction so you can say then hit tab or then hit return so this is creating an instance of an action which is like a task it's performable look almost exactly like this except instead of implementing task it implements action that's the only difference but both of them are performable so you can pass either one of them into the actor and the actor doesn't really care whether it's a task or an action it will perform it either way and that's the cool thing with the actor I mean you can have a look at the code afterwards in the example code in the link at the end you'll see it doesn't take a lot of code there's a lot of stuff in Serenity's implementation because there's a lot of instrumentation and reporting stuff that's been layered on top of it but in order to just do that another place you can look is Jnarrate so if you google Jnarrate and in my name you'll find some code for that that's a reference implementation of this model and you'll see in there that actually it doesn't take very much code at all to make this so you could almost write it yourself probably in less than a day so going back to the point of when you have a lot of classes you will end up with more classes but if you organise them effectively it's actually easier to find out what are the different things that I can do because you can just look at what are the different tasks if you have more tasks you can divide that folder up into smaller groupings of tasks and if you're using a modern IDE and you start instead of having to do dots and seeing what can I do on this page you're no longer restricted to that page you just start typing well, I want to add a to-do item if you're using IntelliJ it will give you a suggestion of all the tasks that start with add so the discoverability problem is a non-issue and actually it makes your test more flexible because you don't always have to necessarily get to a particular page before you can get started on the next thing there's some other interesting things you can do so you can write alternative implementations to do item which could just use the REST API and then you can swap them in and out that's another mechanism that this allows you to do so if you what we would generally want to do is for a given like for the given part of given when then anything that you do in the given we'd want to do that via the APIs we'd never want to go via the front end it's only the when that we might want to do we might want to do via the front end but not always we might end up with so in summary what I've tried to do is point out that page objects are really really useful as training wheels as a place to start while they're small they're easy to work with but as most of us work on quite large scale systems with pages that do quite a few different things and also the concept of a single page web application that one page does everything it becomes quite difficult so the way in which once the page object grows beyond a certain point we can start to split it up because as we try to go faster and faster and faster and these page objects grow and grow and grow it's actually going to slow us down and I'm sure you've all experienced it but couldn't necessarily explain exactly why but everyone was using page objects and everyone was using these inheritance hierarchies so it must be the right way of doing it but when we apply principles like and the O just those two things from the solid OO design principles fundamental principles that have been around for at least 15 years now then it can help us remove the training wheels and arrive at a much better design code and the screenplay pattern could be a place to start it's a way in which you could rather almost bypass the process of having to refactor and you could consider experimenting with starting to write your new tests using this alongside your existing page objects and bit by bit the new test would take over the old ones in a new and better way or you could try and refactor your existing page objects whichever way works for you whatever you do don't try and replace it all at once and that's the end of my talk for today thank you very much right we've got two minutes so I can take some questions we have someone with a microphone who can run around so if you're going to if you want to see him run a lot then make sure you've got people with hands up on this side and on this side and then we'll make the guy run back and forth if you want to be kind to him then we'll just try and work our way across gradually so any questions on this side of the room any questions any questions question can you just turn the mic towards your mouth a bit your application uses frames the focus of what I've tried to get across is more about if you think about it in terms of describing what the user is doing rather than describing what the implementation is doing then what the screen looks like doesn't matter as much anymore because all of the web driver code gets put down really close to where the browser is and then you're abstracted from that and then your tests are expressed in terms of who are you what are you trying to do and what do you expect to happen at the end of it whereas the web driver part is how do we make the computer do that for us so it can be done but how you interact with it with web driver is exactly the same way that you'd interact with it is but that's happening so that's like about three layers below you're abstracted away from that but however you get objects from the page and then click on them at the moment is exactly the same way that this works I'll give you a link right now these are going to go online there's a very lengthy article that pretty much says everything I've said today but a lot better at that bit.ly link the first one bit.ly-rg-screenplay and the examples from today are bit.ly-rg-serenity- rg-serenity-eg and in there what you'll see is you'll be able to work your way through the layers of abstraction to find where you eventually get to where the web driver is the part where we help the computer know how to talk to the other parts of the computer but in terms of how we communicate in terms of writing our tests and express what the users are trying to achieve and the other cool thing about this is the process of just gradually getting us a little bit further away from the details of how the application is built. So if the way that you navigate through the application to register changes, you change that in the registration class and that's it and everything just works and then when the design of the location of things or the things being split across multiple pages is a much less painful activity than if you've already encoded the entire registration process into one page and then oh some UX person says no it should be more like a wizard experience now we're going to split it off into these four different things this makes it a lot easier to cope with that and actually on that note I'll just re-plug Andy Palmer's talk on robot handles that will make it even easier still so I do recommend that Any more questions? We've got someone with a microphone here this will be the last question by the way sorry so how much composition is that's present when I have a double line of and I encode many combinations of objects and then in my data I actually have a different form of composition and most of the results are not that much what's your comment? You may be using the single page but they may be called from different places so as a general rule if a block of code is only called from within one class it probably should stay in that class but if it's called from multiple places then it should probably exist on its own and what will happen is you won't necessarily know what those methods are but if you first extract method so a private method within that class and then what will happen is you'll say actually this whole block of code here needs to be separated out as it's a class in its own and then suddenly you'll find this method goes with it but it's still only called over here then you'll take this block of code and you'll move it somewhere else and then you'll find this one this block of code and a block of code in here needs that method so now that comes out into its own thing so it's a very gradual process of refactoring I'm not going to be able to go into more detail today but I will be around today and tomorrow so do ask me but one of the books I highly recommend for that is a book called Refactoring to Patterns which takes you through the process of refactoring from here's a whole bunch of code and how do I get it to smaller things and another book called Working Effectively with Legacy Code which talks about the seam model so you're looking for seams in your code where you can sort of separate it move it out and piece by piece you're refactoring gradually so that's all we've got time for today but thank you again, thanks for coming and make sure you go to Andy's Robot Handle's talk thank you