Friday, May 9, 2014

a browser factory using enum (200 mcg)

When testing web applications, we often need to switch the browsers. There are many ways to manage this, usually people use if else statement.

There is nothing wrong with if else statement, but if you have many branches of else if statement, the code is extremely fragile. Many patterns have been introduced to avoid using if statement, among them, Factory, Factory Method, Strategy are most popular ones. By the assistance from Spring, we can actually use enum to achieve this, here is the enum of browsers we are going to support in the tests, we can always add more if we want to support more browsers.


Firefox is one of the Browsers
Then declare this Browser as an instance variable of AbstractPage and passed in from Constructor,
In a Spring managed property file, i.e. pages.properties, add the name of the enum,
browser=FIREFOX


The way to let Spring know about the property file is to add this bean into Spring context xml file.
    
        
            
                classpath:properties/pages.properties
            
        
    

In your code, whenever you want to access webDriver instance, just simply call,
This also solves the incompatibility issue caused by Firefox upgrade, mentioned here. And you can run test for different browsers,



And since this Browser interface extends WebDriver, it can be used as the constructor parameter to Actions class and perform advanced actions such mouseOver, drapAndDrop, etc.

     Actions action =  new Actions(CHROME);



Let us compare the tests with or without this browser factory,

    //This is an ugly test not using page framework, it has the same function as the test below. :(
    @Test
    public void dragAndDropChrome() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver", "src/main/resources/chrome/chromedriver");
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("http://www.w3schools.com/html/html5_draganddrop.asp");
        WebElement source = webDriver.findElement(id("drag1"));
        System.out.println(source.getAttribute("src"));
        WebElement target = webDriver.findElement(id("div2"));
        System.out.println(target.getTagName() + "=" + target.toString());

        Actions builder = new Actions(webDriver);

        Action dragAndDrop = builder.clickAndHold(source)
                .moveToElement(target)
                .release(source)
                .build();
        dragAndDrop.perform();
    }

    @Test
    public void testDragAndDrop() {
        Browser browser = Browsers.FIREFOX;
        browser.get("http://www.w3schools.com/html/html5_draganddrop.asp");
        browser.dragAndDrop(id("drag1"), id("div2"));
    }

6 comments:

  1. Good stuff. Something new i have never encountered before. Thanks for sharing. you have any thoughts in generating a good test results report.?
    -Vijay

    ReplyDelete
    Replies
    1. You are welcome.

      Please take a look of http://jbehave.org to see whether it meets your need.

      Delete
  2. Replies
    1. https://github.com/yujunliang/seleniumcapsules/blob/master/src/main/java/com/algocrafts/selenium/Browser.java

      Delete