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.
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:
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):
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.
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
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
BrowserListenum t enable us to use it in the
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.
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:
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.
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.
Now it is your turn to get your hands dirty and try to create this approach. I would say to follow these steps:
DriverFactoryclass with an internal browser enumeration
switch-casestatement and add all the cases
caseto create a browser instance
DriverFactorymethod to create the
WebDriverinstance with a hardcoded browser
DriverFactoryclass to use it
Do not forget you can see an example in the mentioned GitHub repo.
Code does not work.
There is no such method as “ChromeDriverManager().createDriver();”
Would you mind sharing how are you creating/adopting the code?
I ran the test from the project example, and it’s working.