How to use the Factory design pattern to create browser instances: the simple approach

Published by Elias on

Introduction

We face one problem trying to apply the multi-browser test approach: the complexity to create the browser instance.

In this article, I will show you the regular browser creation, how we can improve this, and a solution using the Factory design pattern.

The basic

Using Selenium WebDriver, we need to instantiate the browser class and inform its driver. The browser drivers are maintained as third-party plugins, and you can find them here. The only exception is the Safari driver.

Let’s say you want to run a test using Google Chrome. We have the following code:

Using Firefox, we have the following:

The problem using this approach

There’s one main problem using this basic example wherein can see on line 5 in both: the addition of the driver path.

It is not wrong after all, it’s the first way to use it. The problem is that you will do either one or another (I also have seen both):

  • adding the driver path in a generic folder
  • adding the resource path and pushing the driver within your code

The second one is the worst approach ever from my perspective, so do not do that.

To avoid having these problems, I would strongly recommend you to use the WebDriverManager library. I even have an article explaining a generic approach to applying the factory pattern using it.

The Factory design pattern

I have no intention to explain the Factory design pattern as we have tons of excellent articles and books. If you do not know this pattern, I would recommend reading this article.

The basic implementation is to have a class factory that will look into the browser you would like to create to run your tests and instantiate the browser with the configurations you want.

In the following diagram, the factory implementation is the DriverFactory class the browser configuration is the classes with DriverManagr suffix.

DriverFactory class

The DriverFactory class has a method createInstance that receives the browser name as String to create the correct browser instance. We can instantiate the browser-based on either an if-else statement or switch-case. To bring it more legibility, try to always to for the switch-case.

  • Line 5 upper case the browser value to map it to the BrowserList enum t enable us to use it in the switch-case
  • Lines 10, 13, 16, 19, 22, and 25 create the driver instance based on the matching browser
  • Line 28 throws an exception if the browser value is not valid or recognized
  • Line 33 is the internal browser enumeration

Browser Manager classes

You noticed that the browser instance is using a custom class. We could directly use the driver class in the switch-case, like this:

Instead, we are using the ChromeDriverManager that manages the browser driver using WebDriverManager to solve the problem mentioned at the beginning of this article and creates the browser instance.

It can be a better approach to keep your DriverFactory class clean and with only one responsibility where the driver manager classes contain any additional code to each required browser as starting it maximized or changing any specific configuration.

Each driver manager class implements the Factory interface to have consistent implementation of the browser creation. When you open the other classes you will see the same method being used, but the different driver and browser usage.

How to use this approach

You might have a BaseTest class to manage the test pre and postconditions. You need to inform the preconditions of the browser you need to use, passing it as a parameter to the DriverFactory class. The code would look like this:

The BaseWeb class above is an example to you understand who we can use it. I would not recommend you hardcode the browser. You can find a more elegant example getting the browser from a config file looking at this class.

A complete example

You can navigate to the following GitHub repo to see a complete and functional example like the one described in this article. I would recommend you to read the README file to understand a little bit more about the architecture, libraries in use, and the implementation.

https://github.com/eliasnogueira/selenium-java-browser-factory/tree/basic-example

What to do next?

Now it is your turn to get your hands dirty and try to create this approach. I would say to follow these steps:

  1. Create a DriverFactory class with an internal browser enumeration
  2. Add the switch-case statement and add all the cases
  3. Implement only one case to create a browser instance
  4. Create a simple test class and use the DriverFactory method to create the WebDriver instance with a hardcoded browser
  5. If everything is working as expected, proceed to the next steps, otherwise review this article
  6. Create browser manager class and refactor the DriverFactory class to use it
  7. If it is still working, do the same for the other browser you would like to implement

Do not forget you can see an example in the mentioned GitHub repo.

Happy tests!


Elias

I help professional software engineers (backend, frontend, qa) to develop their quality mindset and deliver bug-free software so they become top-level developers and get hired for the best positions in the market.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *