Last active
April 17, 2023 00:36
-
-
Save kathyrollo/ffcc19a4a1a0b30ac122d39ec8e47c72 to your computer and use it in GitHub Desktop.
Polymorphic DriverFactory Pattern with Selenium WebDriver (JDK 17)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- https://mvnrepository.com/artifact/org.reflections/reflections --> | |
<dependency> | |
<groupId>org.reflections</groupId> | |
<artifactId>reflections</artifactId> | |
<version>0.10.2</version> | |
<scope>test</scope> | |
</dependency> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public sealed interface Driver permits RemoteDriver { | |
Driver isHeadless(boolean isHeadless); | |
Driver withGridUrl(URL gridUrl); | |
Capabilities getOptions(); | |
WebDriver getDriver(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public non-sealed abstract class RemoteDriver implements Driver { | |
protected boolean isHeadless; | |
protected URL gridUrl; | |
@Override | |
public Driver isHeadless(boolean isHeadless) { | |
this.isHeadless = isHeadless; | |
return this; | |
} | |
@Override | |
public Driver withGridUrl(URL gridUrl) { | |
this.gridUrl = gridUrl; | |
return this; | |
} | |
// Returns RemoteWebDriver if URL is supplied, otherwise returns the local WebDriver | |
protected WebDriver getDriver(Supplier<WebDriver> driver, Capabilities options) { | |
return Optional.ofNullable(gridUrl) | |
.<WebDriver>map(gridUrl -> new RemoteWebDriver(gridUrl, options)) | |
.orElseGet(driver); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create a class to represent each browser | |
public class Chrome extends RemoteDriver { | |
// ChromeOptions derives from Capabilities, satisfying the Driver interface implemented by RemoteDriver | |
@Override | |
public ChromeOptions getOptions() { | |
var options = new ChromeOptions(); | |
options.setExperimentalOption("prefs", prefs); | |
if(isHeadless) { | |
options.addArguments("--headless=new", "--window-size=1920,1080"); | |
} else { | |
options.addArguments("--start-maximized"); | |
} | |
// Add other arguments | |
return options; | |
} | |
// Overrides getDriver(), satisfying the Driver interface implemented by RemoteDriver | |
@Override | |
public WebDriver getDriver() { | |
// Internally calls getDriver() from the RemoteDriver parent class | |
return super.getDriver(() -> new ChromeDriver(getOptions()), getOptions()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.lang3.StringUtils; | |
import org.reflections.Reflections; | |
import org.reflections.util.ConfigurationBuilder; | |
// Other imports | |
public class DriverFactory { | |
private boolean isHeadless; | |
private URL gridUrl; | |
public DriverFactory setHeadless(boolean isHeadless) { | |
this.isHeadless = isHeadless; | |
return this; | |
} | |
public DriverFactory setGridUrl(String gridUrl) throws MalformedURLException { | |
if(!StringUtils.isBlank(gridUrl)) { | |
this.gridUrl = new URL(gridUrl); | |
} | |
return this; | |
} | |
public WebDriver getInstance(String browser) throws ReflectiveOperationException { | |
// Uses reflection to get a list of classes that implement the Driver interface | |
return new ArrayList<>(new Reflections(new ConfigurationBuilder() | |
.forPackage(Driver.class.getPackageName())) | |
.getSubTypesOf(Driver.class)) | |
.stream() | |
// Filters the browser by class name | |
.filter(d -> d.getSimpleName().toLowerCase().contains(browser.toLowerCase())) | |
.findFirst() | |
.orElseThrow(() -> new RuntimeException(browser + " browser is not supported")) | |
.getConstructor() | |
.newInstance() | |
.isHeadless(isHeadless) | |
.withGridUrl(gridUrl) | |
.getDriver(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class BaseTest { | |
protected WebDriver driver; | |
@BeforeEach | |
public void setUp() throws Throwable { | |
driver = new DriverFactory() | |
// Set environment variables in the OS | |
.setHeadless(System.getenv("SELENIUM_HEADLESS")) | |
.setGridUrl(System.getenv("SELENIUM_GRID_URL")) | |
.getInstance(System.getenv("SELENIUM_BROWSER")); | |
driver.get(System.getenv("SELENIUM_BASE_URL")); | |
// More code | |
} | |
@AfterEach | |
public void tearDown() { | |
driver.quit(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment