Site icon Vinsguru

Selenium WebDriver – Factory Design Pattern Using Java 8 – Supplier

Overview:

We had already covered about Factory Design Pattern in detail here. If you had not read that before, I would suggest you to check that article first. In this article, We are going to follow slightly a different approach using Java8 lambda expressions. Advantage of using lambda expressions is to write only fewer lines of code & not to create multiple classes.

Supplier:

Java from its version 8 supports lambda expressions by using special type of interfaces called Functional Interfaces. If you are new to Java and would like to be good at it, I would suggest you to spend some time here to explore this area very well. It might look like it is a lot of functional interfaces. Actually It is not. There are only very few basic functional interfaces. Some of them are repeating based on the number of arguments it could accept etc / depends on the data types it would return.

The one which we might be interested in for the factory pattern is called Supplier.  Supplier does not accept any arguments. Whenever it is invoked it returns a new/distinct object whenever it is invoked.  If you look at Java’s functional interfaces list, you could see different types of suppliers like IntSupplier, LongSupplier, BooleanSupplier..etc  They are for supporting java’s primitive data types. Lets ignore them for the time being. We are interested in the supplier which returns an object.

Very simple example of Supplier would be as shown here. Basically we would wrap the object inside a Supplier. Here we always return a hard coded data. But you could add your logic to return new Object you want. hopefully you get idea.

Supplier<String> hi = () -> {
    return "Hi";
};

Supplier<String> hello = () -> {
    return "Hello";
};

Now the important part is how to invoke the above supplier. That is simple. Just invoke the method ‘get’ from the supplier.

System.out.println(hi.get());

The above code prints ‘Hi’.

Driver Factory:

If the above example is clear, then understanding below code would be easier for you.  As you see, I return a new Driver instance here whenever supplier is called!

//chrome driver supplier
Supplier<WebDriver> chromeDriverSupplier = () -> {
    System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
    return new ChromeDriver();
};

//firefox driver supplier
Supplier<WebDriver> firefoxDriverSupplier = () -> {
    System.setProperty("webdriver.gecko.driver", "/Users/username/Downloads/geckodriver");
    return new FirefoxDriver();
};

You might want to add additional suppliers like Safari, IE etc depends on your requirement.

public enum DriverType {
    CHROME,
    FIREFOX,
    SAFARI,
    IE;
}

To avoid if-else / switch statements, I create a map as shown here. Once I have all my suppliers, then I add the suppliers into the map.

public class DriverFactory {

    private static final Map<DriverType, Supplier<WebDriver>> driverMap = new HashMap<>();

    //chrome driver supplier
    private static final Supplier<WebDriver> chromeDriverSupplier = () -> {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        return new ChromeDriver();
    };

    //firefox driver supplier
    private static final Supplier<WebDriver> firefoxDriverSupplier = () -> {
        System.setProperty("webdriver.gecko.driver", "/Users/username/Downloads/geckodriver");
        return new FirefoxDriver();
    };

    //add more suppliers here

    //add all the drivers into a map
    static{
        driverMap.put(DriverType.CHROME, chromeDriverSupplier);
        driverMap.put(DriverType.FIREFOX, firefoxDriverSupplier);
    }

    //return a new driver from the map
    public static final WebDriver getDriver(DriverType type){
        return driverMap.get(type).get();
    }

}

Now your test should be simply written as shown here to get a new WebDriver.

public class SampleBrowserTest {

    private WebDriver driver;

    @BeforeTest
    public void setup(){
        driver = DriverFactory.getDriver(DriverType.CHROME);
    }

    @Test
    public void test1(){
        driver.get("https://www.google.com");
        //your test using webdriver
    }

    @AfterTest
    public void teardown(){
        driver.close();
    }

}

Udemy – Selenium WebDriver and Design Patterns Course:

VinsGuru has released a brand new course in Udemy on Selenium WebDriver and Design Patterns. ~8 hours course with all the important design patterns to design better, reusable page object models, test classes etc. Please access the above link which gives you the special discount.  You can also get your money back if you do not like the course within 30 days.

Summary:

The above code looks cleaner and removes ugly if-else/switch statements. Java8 Supplier also helps us from writing too many classes.

 

Happy Testing & Subscribe 🙂

 

Share This:

Exit mobile version