{"id":16536728,"url":"https://github.com/eliasnogueira/selenium-java-browser-factory","last_synced_at":"2025-03-21T09:32:16.010Z","repository":{"id":43971554,"uuid":"346132209","full_name":"eliasnogueira/selenium-java-browser-factory","owner":"eliasnogueira","description":"Example of the Factory design pattern implementation to create browser instances using Selenium WebDriver","archived":false,"fork":false,"pushed_at":"2024-10-27T19:30:56.000Z","size":99,"stargazers_count":26,"open_issues_count":0,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-01T05:06:33.230Z","etag":null,"topics":["factory-pattern","java","selenium-webdriver","test-automation"],"latest_commit_sha":null,"homepage":"http://eliasnogueira.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eliasnogueira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-09T20:14:29.000Z","updated_at":"2025-02-26T14:29:24.000Z","dependencies_parsed_at":"2024-10-27T21:30:04.187Z","dependency_job_id":null,"html_url":"https://github.com/eliasnogueira/selenium-java-browser-factory","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliasnogueira%2Fselenium-java-browser-factory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliasnogueira%2Fselenium-java-browser-factory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliasnogueira%2Fselenium-java-browser-factory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliasnogueira%2Fselenium-java-browser-factory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eliasnogueira","download_url":"https://codeload.github.com/eliasnogueira/selenium-java-browser-factory/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244130281,"owners_count":20402753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["factory-pattern","java","selenium-webdriver","test-automation"],"created_at":"2024-10-11T18:33:02.943Z","updated_at":"2025-03-21T09:32:15.721Z","avatar_url":"https://github.com/eliasnogueira.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Selenium Java Browser Factory\n\nDon't forget to give this project a ⭐\n\n* [Introduction](#introduction)\n* [Technologies and Libraries](#technologies-and-libraries)\n* [Technical explanation](#technical-explanation)\n    * [DriverFactory](#driverFactory)\n    * [BrowserFactory](#browserFactory)\n        * [local browser instance creation](#local-browser-instance-creation)\n        * [remote browser instance creation](#remote-browser-instance-creation)\n* [Explaining the usage scenarios](#explaining-the-usage-scenarios)\n    * [Local execution](#local-execution)\n    * [Remote execution](#remote-execution)\n\n## Introduction\n\nThis project shows how you can use the Factory design pattern to create different browsers using Selenium WebDriver\nfor the web test automation.\n\nYou can also find an explanation about this project implementation\nat http://www.eliasnogueira.com/the-best-way-to-create-browser-instances-using-the-factory-pattern-java-and-selenium-webdriver/\n\nThis branch has the final recommendation.\nIf you don't know how to use it I would recommend you to take a look at the following branches:\n\n* [basic-example](https://github.com/eliasnogueira/selenium-java-browser-factory/tree/basic-example): shows a basic and\n  local implementation of the Factory design pattern\n* [local-remote-example](https://github.com/eliasnogueira/selenium-java-browser-factory/tree/local-remote-example):\n  shows a local and remote implementation of the Factory design pattern\n\nThe **local** implementation means that the tests will execute in your local machine.\nThe **remote** implementation means that the tests will execute in a remote machine (another physical machine, cloud, or\ngrid).\n\n## Technologies and Libraries\n\n* [Java 23](https://openjdk.java.net/projects/jdk/23/) as the programming language\n* [JUnit 5](https://junit.org/junit5/) to support the test creation\n* [Selenium WebDriver](https://www.selenium.dev/) as the web browser automation framework using the Java binding\n* [AssertJ](https://joel-costigliola.github.io/assertj/) as the fluent assertion library\n* [WebDriverManager](https://github.com/bonigarcia/webdrivermanager) as the Selenium binaries management\n* [Owner](http://owner.aeonbits.org/) to minimize the code to handle the properties file\n\n## Technical explanation\n\nThe factory implementation is based on:\n\n* factory class to manage to execute the tests in the local or remote environment\n* browser factory to create the browser instance for the local or remote execution\n* driver manager that has one class per browser we need to use\n\n### DriverFactory\n\nThe [DriverFactory](https://github.com/eliasnogueira/selenium-java-browser-factory/blob/master/src/main/java/com/eliasnogueira/driver/DriverFactory.java)\nclass is responsible for creating the browser instance either for local or remote execution.\nThe target execution is managed by the property `target` on `general.properties` placed on `src/java/resources` folder.\n\nWhen the property value is `local` it creates a local browser instance using the `createDriver()` method from the\n`BrowserFactory` class having the following code snippet:\n\n```java\nwebdriver =BrowserFactory.\n\nvalueOf(browser.toUpperCase()).\n\ncreateDriver();\n```\n\nWhen the property value is `remote` it creates a remote browser instance using the `getOptions()` method from the\n`BrowserFactory` class having the following code snippet:\n\n```java\nwebdriver =\n\ncreateRemoteInstance(BrowserFactory.valueOf(browser.toUpperCase()).\n\ngetOptions());\n```\n\nNote that the `createRemoteInstance` method is being used to connect to a remote environment.\nThe remote environment can be configured by changing the `grid.properties` file placed on `src/main/java/resources`\nfolder.\nYou can create your remote approach or use Selenium Grid. You can find a `docker-compose.yml` file in this project\nroot folder to create the Selenium 4 Grid and run the test.\n\n### BrowserFactory\n\nThe [BrowserFactory](https://github.com/eliasnogueira/selenium-java-browser-factory/blob/master/src/main/java/com/eliasnogueira/driver/BrowserFactory.java)\nenum is responsible to create either the local browser instance or the capabilities to send to remote execution.\n\nIt's an enumeration to simplify the factory creation, but we will get there.\nIt has two abstract methods to make all the enuns implement the same methods:\n\n```java\npublic abstract WebDriver createDriver();\n\npublic abstract AbstractDriverOptions\u003c?\u003e getOptions();\n```\n\nThe `createDriver()` is responsible for the local browser instance creation where the `getOptions()` is responsible for\nthe remote browser instance creation.\n\n#### local browser instance creation\n\nIt uses the WebDriverManager to manage the browser driver and, after that, create a new instance for the browser\nassociated\nby it enum. This is the example for the Google Chrome browser:\n\n```java\n\n@Override\npublic WebDriver createDriver() {\n    WebDriverManager.getInstance(DriverManagerType.CHROME).setup();\n\n    return new ChromeDriver(getOptions());\n}\n```\n\nNote that the `ChromeDriver()` class has the `getOptions()` method as it parameters.\nThe `getOptions` has two intents:\n\n* set the common options to execute the test for the targeting browser\n* be used to create the browser instance in the remote execution\n\n#### remote browser instance creation\n\nRemote test executions using Selenium are based on\nthe [RemoteWebDriver](https://www.selenium.dev/documentation/en/remote_webdriver/remote_webdriver_client/)\ninstead of the `WebDriver` class. To tell the `RemoteWebDriver` the browser we need to run the tests we must set\nthe [BrowserOptions](https://www.selenium.dev/documentation/en/remote_webdriver/remote_webdriver_client/#browser-options)\nthat are usually called Capabilities.\n\nEach browser that supports Selenium has its `Options` class. When we explicitly create an Options instance the\n`RemoteWebDriver`\nwill know the browser to use. In the example below we are using the `ChromeOptions`, so the `RemoteWebDriver`\nwill know that the Google Chrome browser must be used in the remote test execution.\n\n```java\n\n@Override\npublic ChromeOptions getOptions() {\n    ChromeOptions chromeOptions = new ChromeOptions();\n    chromeOptions.addArguments(START_MAXIMIZED);\n    chromeOptions.addArguments(\"--disable-infobars\");\n    chromeOptions.addArguments(\"--disable-notifications\");\n    chromeOptions.setHeadless(configuration().headless());\n\n    return chromeOptions;\n}\n```\n\nWe are also passing some parameters to the browser options.\n\nIf you take a look at the `DriverFactory` class you will see that the `createRemoteInstance()` method is creating a new\ninstance of the `RemoteWebDriver` class, and it needs the capability (our options class) to determine in which browser\nthe test must run.\n\n## Explaining the usage scenarios\n\n### Local execution\n\n* The `general.properties` file has `target=local` and `browser=chrome`\n* You ran the `BookRoomWebTest` class\n* The `BaseWeb` class, in its preconditions method, will:\n    * read the `browser` property value (`chrome`)\n    * call the `DriverFactory.createInstance()`\n* The `DriverFactory.createInstance()` method will:\n    * read the `target` attribute from the `general.properties` which will be `local` for this scenario\n    * determine in the `switch-case` that the local execution must happen\n    * create a local browser instance calling `BrowserFactory.createBrowser()`\n* The `BrowserFactory` will match with the browser name we are using (`chrome`) and will call `createDriver()` method\n    * the `CHROME` enum for the `createDriver()` is using the WebDriverManager to create and initiate the browser driver\n    * and after it's creating the browser instance\n* The test will run in the Google Chrome browser\n\n### Remote execution\n\n* The `general.properties` file has `target=remote` and `browser=firefox`\n* You ran the `docker-compose.yml` to initiate the Selenium 4 Grid\n* You ran the `BookRoomWebTest` class\n* The `BaseWeb` class, in its preconditions method, will:\n    * read the `browser` property value (`firefox`)\n    * call the `DriverFactory.createInstance()`\n* The `DriverFactory.createInstance()` method will:\n    * read the `target` attribute from the `general.properties` which will be `remote` for this scenario\n    * determine in the `switch-case` that the remote execution must happen\n    * create a remote browser instance calling `BrowserFactory.getOptions()`\n    * start the `RemoteWebDriver` session based on the `getOptions` for the browser\n* The test will run in the Google Chrome browser    ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feliasnogueira%2Fselenium-java-browser-factory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feliasnogueira%2Fselenium-java-browser-factory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feliasnogueira%2Fselenium-java-browser-factory/lists"}