Don’t use assertTrue to verify a text
March 13, 2020WebDriverManager is an excellent tool to automate the management of the browser driver binaries by running your automated test scripts locally with Selenium WebDriver and Java.
Simple example
A simple and small example, if you don’t know this tool is:
public class ChromeTest {
public void openGoogleChrome() {
// setup the browsr binary and set the proper path
WebDriverManager.chromedriver().setup();
// create the Google Chrome browser instance
WebDriver driver = new ChromeDriver();
driver.get("https://eliasnogueira.com");
}
}
The main thing here is the code on line 6. The WebDriverManager
class has a method with the name of the browser, like a chained method. Following if you use the setup()
method this class will download the browser binary according to your operating system and set the binary path.
What is a Browser Factory
Factory is a Design Pattern. It’s used when we need to create an object that shares a common implementation. In this context of browser creation, it will use methods like create()
, close()
, getDriver()
.
We have, sometimes, different approaches for a Browser Factory. Below you can see one possible approach:
You have an interface (DriverManager) that has the implementation for each browser (create and quit). They are separated because each browser has its way of implementing certain configurations.
We must create a factory to instantiate the correct browser. On the diagram, you can see an enumeration to support browser creation.
The TestClasses uses the DriverManagerFactory
to create the browser instance.
This approach is a good one, of course with a BaseTest
some configuration to easily create multi-browser support, but if you have to create an approach or execute your tests locally we can apply a light-way implementation with WebDriverManager
.
Browser Factory with WebDriverManager
Since version 3.8.1 you can now use an enumeration to set up and initiate the target browser.
import static io.github.bonigarcia.wdm.DriverManagerType.CHROME;
import org.openqa.selenium.WebDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
// …
DriverManagerType chrome = DriverManagerType.CHROME;
WebDriverManager.getInstance(chrome).setup();
Class<?> chromeClass = Class.forName(chrome.browserClass());
driver = (WebDriver) chromeClass.newInstance();
Line 8 sets the DriverManagerType
enum to Chrome.
Line 9 shows the browser setup, passing the enum (Chrome) as a parameter to getInstance()
method.
Line 10 is getting the full class name, from the enum, to create a class.
Line 11 creates a new instance of that class.
Did you figure out that the enum DriverManagerType
has the full class name? You now can generate a browser factory with a few lines of code.
How to create it
Try to follow, first, what we need to do:
- Create a class with a method that will receive the browser name
- Convert the browser name to the enum
DriverManagerType
- Get the full class name from the enumeration and create a class
- Set up the browser (binary and path)
- Instantiate the browser and return it
Now look at the code below:
public class LocalDriverManager {
// to make this work just pass the browser name, that must match from the DriverManagerType class
public WebDriver createInstance(String browser) {
WebDriver driver = null;
try {
DriverManagerType driverManagerType = DriverManagerType.valueOf(browser.toUpperCase());
Class<?> driverClass = Class.forName(driverManagerType.browserClass());
WebDriverManager.getInstance(driverManagerType).setup();
driver = (WebDriver) driverClass.newInstance();
} catch (IllegalAccessException | ClassNotFoundException e) {
// exception or log for class not found
} catch (InstantiationException e) {
// exception of log for instantiation problem
}
return driver;
}
}
Line 4 is a method that receives a browser name as a parameter and returns a WebDriver
object.
Line 8 transforms the browser name into a DriverManagerType
if the name matches.
Line 9 gets the received browser’s complete class name from the DriverManagerType and passes it to a generic class object.
Line 10 sets the driver (binary and path) for the received browser.
Line 11 creates a new instance of the browser.
Eg: if the received browser was Chrome this line will, implicitly, do: new ChromeDriver();
Line 17 returns the browser instantiated and ready for use in your test class.
The benefits
You can have these benefits:
- Only one code for browser factory creation
- Less code to maintain
- Fast solution for multi-browser
Drawbacks
If you need to add additional configurations to the browser, like enabling/disabling headless mode, changing the screen size and so on you should implement them as shown in the explanation about the browser factory.
Looking for a real example?
At selenium-java-lean-test-achitecture, you can see an implementation of the local browser factory.
The application has a properties file. If you clone this project and execute it on your machine take a look at the file general.properties on src/main/java/resources/conf
folder. There’s a property target
as local
, which means local execution.
Now open the LocalDriverManager class on src/main/java/driver/local
. It’s the same implementation of this post.
The execution is controlled by the DriverFactory class on src/main/java/driver
reading the target execution (local or remote) and instantiating the local or remote driver manager.
The BaseWeb class on src/main/java/test
, a base test, receives as a parameter the browser or uses Chrome if no browser is informed, creates the WebDriver instance sends the browser information to the DriverFactory. Your execution is set as local, so the DriverFactory will instantiate LocalDriverManager
to the browser informed.
1 Comment
Hello Sir!
Please, what would be the best approach to launch the Chrome browser in headless mode in LocalDriverManager?