Tuesday 7 October 2014

Using Page Factories with Loadable Component!!!

Continues with my previous Post!!!

LoadableComponent is another way to approach PageObjects. LoadableComponent 
is a base class that all of the pages need to extend. The base class has the following 
methods on the interface
             
                   1) get()
                   2) isLoaded()
                   3) load()


 Instead of the usual public class PageObject, we change it:

     public class PageObject extends LoadableComponent<PageObject>

We will have to add overrides for the load() and isLoaded() method. The load method
will load the page for us and the isLoaded() method can allow us to check if the page 
has been loaded correctly.

@override
Protected void load() {
selenium.get("http://book.theautomatedtester.co.uk");
}

@protected void isLoaded() {
String url = selenium.getCurrentUrl();
If (url != "http://book.theautomatedtester.co.uk"){
throw new Exception("The wrong page has loaded");
}
}

As we can see this is just a simple bit of code, but we can make sure that we start 
on the right page when we need to.

Now that we have learnt about LoadableComponents, we should have a look at 
seeing it in action. We need to make changes to our Java Class.


1. The following is how the code should look so far:

public class Chapter2 {
WebDriver selenium;
@FindBy(how= How.NAME, using="verifybutton")
WebElement verifybutton;
public Chapter2(WebDriver selenium){
this.selenium = selenium;
if (!"Chapter 2".equalsIgnoreCase(this.selenium.getTitle())){
selenium.get("http://book.theautomatedtester.co.uk/chapter2");
}
}
public boolean isButtonPresent(String button){
return selenium.findElements(By.xpath
("//input[@id='"+button+"']")).size()>0;
}
}


2. If we have a look at our Chapter 2 Java class, we can see that we need to extend
LoadableComponent. Since this takes generics we will have to pass in our
PageObject class. It should look like:

public class Chapter2 extends LoadableComponent<Chapter2> {

3. In our constructor, we will have to initialize our page factory. We can remove the
rest of the code in there since that will be moved to load(). It should look like the
following:

public Chapter2(WebDriver selenium){
this.selenium = selenium;
PageFactory.initElements(selenium, this);
}


4. We now need to add our override methods. These will allow us to check that we are
on the right page when we load this component:

@override
Protected void load() {
selenium.get("http://book.theautomatedtester.co.uk/chapter2");
}
@protected void isLoaded() {
String url = selenium.getCurrentUrl();
If (url != "http://book.theautomatedtester.co.uk/chapter2"){
throw new Exception("The wrong page has loaded");
}
}

5. Now we need to have a look at updating our test to load everything for us.
 To do this we need to change:

@Test
public void ShouldLoadTheHomePageAndThenCheckButtonOnChapter2() {
selenium.get("http://book.theautomatedtester.co.uk");
HomePage hp = new HomePage(selenium);
Chapter2 ch2 = hp.clickChapter2();
assertTrue(ch2.isButtonPresent("but1"));
}

6. To look like this:

@Test
public void ShouldLoadTheHomePageAndThenCheckButtonOnChapter2(){
Chapter2 cht = new Chapter2(selenium).get();
ch2.isButton("but1");
}


7. Run your test. Everything should look like the following:


public class Chapter2 extends LoadableComponent<Chapter2>{
WebDriver selenium;
@FindBy(how= How.NAME, using="verifybutton")
WebElement verifybutton;
public Chapter2(WebDriver selenium){
this.selenium = selenium;
PageFactory.initElements(selenium, this);
}
@override
Protected void load() {
selenium.get("http://book.theautomatedtester.co.uk/chapter2");
}
@protected
public void isLoaded() {
String url = selenium.getCurrentUrl();
If (url != "http://book.theautomatedtester.co.uk/chapter2"){
throw new Exception("The wrong page has loaded");
}
}
public boolean isButtonDisplayed(String button){
return selenium.findElement(By.id("button")).isDisplayed();
}
}

What just happened?

We have just converted our page object to use the LoadableComponent class 
that comes with the Selenium Project. We saw how we simplified on constructors 
and then just moved this into somewhere easy to maintain. We have seen that 
we can move a lot of the boiler plate code out of our class and rely on it 
being pulled in via LoadableComponent. This means that we no 
longer need to maintain it or we add those items.

Imagine how you have to work with a flow that takes you through a number of pages.
LoadableComponent allows us to set up a workflow. To get this right we need to pass
one in like the following when doing your test setup:

@Before
public void prepareComponents() {
WebDriver selenium = new FirefoxDriver();
HomePage homePage = new HomePage(selenium);
Chapter2 chapter2 = new SecuredPage(selenium, homePage);

}