selenium-java-browser-factory
selenium-java-browser-factory copied to clipboard
Example of the Factory design pattern implementation to create browser instances using Selenium WebDriver
Selenium Java Browser Factory
Don't forget to give this project a ⭐
- Introduction
- Technologies and Libraries
-
Technical explanation
- DriverFactory
-
BrowserFactory
- local browser instance creation
- remote browser instance creation
-
Explaining the usage scenarios
- Local execution
- Remote execution
Introduction
This project shows how you can use the Factory design pattern to create different browsers using Selenium WebDriver for the web test automation.
You can also find an explanation about this project implementation at http://www.eliasnogueira.com/the-best-way-to-create-browser-instances-using-the-factory-pattern-java-and-selenium-webdriver/
This branch has the final recommendation. If you don't know how to use it I would recommend you to take a look at the following branches:
- basic-example: shows a basic and local implementation of the Factory design pattern
- local-remote-example: shows a local and remote implementation of the Factory design pattern
The local implementation means that the tests will execute in your local machine. The remote implementation means that the tests will execute in a remote machine (another physical machine, cloud, or grid).
Technologies and Libraries
- Java 21 as the programming language
- JUnit 5 to support the test creation
- Selenium WebDriver as the web browser automation framework using the Java binding
- AssertJ as the fluent assertion library
- WebDriverManager as the Selenium binaries management
- Owner to minimize the code to handle the properties file
Technical explanation
The factory implementation is based on:
- factory class to manage to execute the tests in the local or remote environment
- browser factory to create the browser instance for the local or remote execution
- driver manager that has one class per browser we need to use
DriverFactory
The DriverFactory
class is responsible for creating the browser instance either for local or remote execution.
The target execution is managed by the property target
on general.properties
placed on src/java/resources
folder.
When the property value is local
it creates a local browser instance using the createDriver()
method from the
BrowserFactory
class having the following code snippet:
webdriver = BrowserFactory.valueOf(browser.toUpperCase()).createDriver();
When the property value is remote
it creates a remote browser instance using the getOptions()
method from the
BrowserFactory
class having the following code snippet:
webdriver = createRemoteInstance(BrowserFactory.valueOf(browser.toUpperCase()).getOptions());
Note that the createRemoteInstance
method is being used to connect to a remote environment.
The remote environment can be configured by changing the grid.properties
file placed on src/main/java/resources
folder.
You can create your remote approach or use Selenium Grid. You can find a docker-compose.yml
file in this project
root folder to create the Selenium 4 Grid and run the test.
BrowserFactory
The BrowserFactory enum is responsible to create either the local browser instance or the capabilities to send to remote execution.
It's an enumeration to simplify the factory creation, but we will get there. It has two abstract methods to make all the enuns implement the same methods:
public abstract WebDriver createDriver();
public abstract AbstractDriverOptions<?> getOptions();
The createDriver()
is responsible for the local browser instance creation where the getOptions()
is responsible for
the remote browser instance creation.
local browser instance creation
It uses the WebDriverManager to manage the browser driver and, after that, create a new instance for the browser associated by it enum. This is the example for the Google Chrome browser:
@Override
public WebDriver createDriver() {
WebDriverManager.getInstance(DriverManagerType.CHROME).setup();
return new ChromeDriver(getOptions());
}
Note that the ChromeDriver()
class has the getOptions()
method as it parameters.
The getOptions
has two intents:
- set the common options to execute the test for the targeting browser
- be used to create the browser instance in the remote execution
remote browser instance creation
Remote test executions using Selenium are based on the RemoteWebDriver
instead of the WebDriver
class. To tell the RemoteWebDriver
the browser we need to run the tests we must set the BrowserOptions
that are usually called Capabilities.
Each browser that supports Selenium has its Options
class. When we explicitly create an Options instance the RemoteWebDriver
will know the browser to use. In the example below we are using the ChromeOptions
, so the RemoteWebDriver
will know that the Google Chrome browser must be used in the remote test execution.
@Override
public ChromeOptions getOptions() {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments(START_MAXIMIZED);
chromeOptions.addArguments("--disable-infobars");
chromeOptions.addArguments("--disable-notifications");
chromeOptions.setHeadless(configuration().headless());
return chromeOptions;
}
We are also passing some parameters to the browser options.
If you take a look at the DriverFactory
class you will see that the createRemoteInstance()
method is creating a new
instance of the RemoteWebDriver
class, and it needs the capability (our options class) to determine in which browser
the test must run.
Explaining the usage scenarios
Local execution
- The
general.properties
file hastarget=local
andbrowser=chrome
- You ran the
BookRoomWebTest
class - The
BaseWeb
class, in its preconditions method, will:- read the
browser
property value (chrome
) - call the
DriverFactory.createInstance()
- read the
- The
DriverFactory.createInstance()
method will:- read the
target
attribute from thegeneral.properties
which will belocal
for this scenario - determine in the
switch-case
that the local execution must happen - create a local browser instance calling
BrowserFactory.createBrowser()
- read the
- The
BrowserFactory
will match with the browser name we are using (chrome
) and will callcreateDriver()
method- the
CHROME
enum for thecreateDriver()
is using the WebDriverManager to create and initiate the browser driver - and after it's creating the browser instance
- the
- The test will run in the Google Chrome browser
Remote execution
- The
general.properties
file hastarget=remote
andbrowser=firefox
- You ran the
docker-compose.yml
to initiate the Selenium 4 Grid - You ran the
BookRoomWebTest
class - The
BaseWeb
class, in its preconditions method, will:- read the
browser
property value (firefox
) - call the
DriverFactory.createInstance()
- read the
- The
DriverFactory.createInstance()
method will:- read the
target
attribute from thegeneral.properties
which will beremote
for this scenario - determine in the
switch-case
that the remote execution must happen - create a remote browser instance calling
BrowserFactory.getOptions()
- start the
RemoteWebDriver
session based on thegetOptions
for the browser
- read the
- The test will run in the Google Chrome browser