diff --git a/README.md b/README.md index 9af3bc7..c9b2937 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,77 @@ This library will load the correct Driver for your browser you choose and ensure that no browser is left behind when it closes ### Main Entry point -SeleniumHelper.getWebDriverHolder() +`SeleniumHelper.getWebDriverHolder()` Environment Args that you can use: -* headless.disabled - if set, then headless mode for browsers is turned off +* `headless.disabled` -* doScreenPrints - if set, then screenshots will be taken if performScreenPrint is called - is used with ```performScreenPrint(WebDriverHolder webDriverHolder, String testName)``` + If set, then headless mode for browsers is turned off (that is, the browser windows will open). -* http.proxyHost, https.proxyHost - These variables are passed through to the browser it seems +* `doScreenPrints` + If set, then screenshots will be taken if `performScreenPrint` is called. Is used with + ```performScreenPrint(WebDriverHolder webDriverHolder, String testName)```. + +* `http.proxyHost` and `https.proxyHost` + + These variables are passed through to the browser. + +### Missing Firefox Profile + +Using the Firefox web driver may cause an error saying the profile could not be found. This will cause the driver to +hang if running headless or throw an error on acknowledgement. This issue arose when using Firefox installed with Snap +on an Ubuntu 22.04 machine. The resolution (as per [this guide](https://www.omgubuntu.co.uk/2022/04/how-to-install-firefox-deb-apt-ubuntu-22-04)) +is as follows: + +1. Uninstall the Firefox Snap. + + ```shell + sudo snap remove firefox + ``` + +2. Create an APT keyring if one has not already been created. + + ```shell + sudo install -d -m 0755 /etc/apt/keyrings + ``` + +3. Import the Mozilla APT repo signing key. + + ```shell + wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | sudo tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null + ``` + +4. Add Mozilla signing key to `sources.list`. + + ```shell + echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | sudo tee -a /etc/apt/sources.list.d/mozilla.list > /dev/null + ``` + +5. Set the Firefox package priority to ensure Mozilla's DEB version is always preferred. Not performing this step may + lead to APT reinstalling the Firefox Snap. + + ```shell + echo ' + Package: * + Pin: origin packages.mozilla.org + Pin-Priority: 1000 + ' | sudo tee /etc/apt/preferences.d/mozilla + ``` + +6. Install the Firefox DEB. + + ```shell + sudo apt update && sudo apt install firefox + ``` + +7. (Optional) Install a localised version of Firefox. The example below is for French. + + ```shell + sudo apt install firefox-l10n-fr + ``` + + A list of all available languages can be found using `apt-cache search firefox-l10n`. ### Change log diff --git a/src/main/java/au/gov/qld/online/selenium/SeleniumHelper.java b/src/main/java/au/gov/qld/online/selenium/SeleniumHelper.java index c539bc5..8c6d4c5 100644 --- a/src/main/java/au/gov/qld/online/selenium/SeleniumHelper.java +++ b/src/main/java/au/gov/qld/online/selenium/SeleniumHelper.java @@ -74,12 +74,10 @@ public void run() { } for (DriverService service : driverServiceAll) { if (service != null) { - try { + try (service) { service.stop(); } catch (Exception e) { LOGGER.error("exception on close", e); - } finally { - service.close(); } } } @@ -138,7 +136,7 @@ public static synchronized WebDriverHolder getWebDriver(DriverTypes driverType, } } - WebDriver webDriver = null; + WebDriver webDriver; WebDriverManager wdm; try { final Platform platform = Platform.getCurrent(); @@ -174,33 +172,21 @@ public static synchronized WebDriverHolder getWebDriver(DriverTypes driverType, break; case FIREFOX: wdm = WebDriverManager.firefoxdriver(); - wdm.setup(); final FirefoxOptions firefoxOptions = new FirefoxOptions(); - if (headlessEnabled) { - firefoxOptions.addArguments("-headless"); - } + wdm.config().setTimeout(30); if (proxy != null) { firefoxOptions.setProxy(proxy); + wdm.config().setProxy(proxy.getHttpProxy()); + } + wdm.setup(); + if (headlessEnabled) { + firefoxOptions.addArguments("-headless"); } if (downloadDirectory != null) { firefoxOptions.addPreference("browser.download.folderList", 2); firefoxOptions.addPreference(browserDownloadOption, downloadDirectory); firefoxOptions.addPreference("browser.download.useDownloadDir", true); } - - // Create a new Firefox profile - FirefoxProfile profile = new FirefoxProfile(); - - // Set the homepage to about:blank - final String aboutBlank = "about:blank"; - profile.setPreference("browser.startup.homepage", aboutBlank); - profile.setPreference("startup.homepage_welcome_url", aboutBlank); - profile.setPreference("startup.homepage_welcome_url.additional", aboutBlank); - - // Disable restoring previous session - profile.setPreference("browser.sessionstore.resume_from_crash", false); - - firefoxOptions.setProfile(profile); GeckoDriverService geckoDriverService = new GeckoDriverService.Builder().usingAnyFreePort().build(); geckoDriverService.start(); driverServiceAll.add(geckoDriverService); @@ -209,11 +195,13 @@ public static synchronized WebDriverHolder getWebDriver(DriverTypes driverType, case EDGE: if (platform.is(WINDOWS)) { wdm = WebDriverManager.edgedriver(); - wdm.setup(); + wdm.config().setTimeout(30); final EdgeOptions edgeOptions = new EdgeOptions(); if (proxy != null) { edgeOptions.setProxy(proxy); + wdm.config().setProxy(proxy.getHttpProxy()); } + wdm.setup(); if (downloadDirectory != null) { Map edgePrefs = new HashMap<>(); edgePrefs.put("download.default_directory", downloadDirectory); @@ -232,13 +220,15 @@ public static synchronized WebDriverHolder getWebDriver(DriverTypes driverType, case SAFARI: if (platform.is(MAC)) { wdm = WebDriverManager.edgedriver(); - wdm.setup(); + wdm.config().setTimeout(30); DesiredCapabilities safariCapabilities = new DesiredCapabilities(); final SafariOptions safariOptions = new SafariOptions(); safariOptions.merge(safariCapabilities); if (proxy != null) { safariOptions.setProxy(proxy); + wdm.config().setProxy(proxy.getHttpProxy()); } + wdm.setup(); if (downloadDirectory != null) { safariOptions.setCapability(browserDownloadOption, downloadDirectory); } @@ -389,6 +379,10 @@ private static synchronized void setupChromeService() throws IOException { } WebDriverManager wdm = WebDriverManager.chromedriver(); + wdm.config().setTimeout(30); + if (proxy != null) { + wdm.config().setProxy(proxy.getHttpProxy()); + } wdm.setup(); chromeService = new ChromeDriverService.Builder() .usingDriverExecutable(new File(wdm.getDownloadedDriverPath())) diff --git a/src/main/java/au/gov/qld/online/selenium/WebDriverHolder.java b/src/main/java/au/gov/qld/online/selenium/WebDriverHolder.java index 3656b01..1c5b030 100644 --- a/src/main/java/au/gov/qld/online/selenium/WebDriverHolder.java +++ b/src/main/java/au/gov/qld/online/selenium/WebDriverHolder.java @@ -4,10 +4,10 @@ public class WebDriverHolder { - private WebDriver webDriver; - private DriverTypes driverType; + private final WebDriver webDriver; + private final DriverTypes driverType; private int numberUsed = 0; - private String downloadDirectory; + private final String downloadDirectory; public WebDriverHolder(WebDriver webDriver, DriverTypes driverType, String downloadDirectory) { this.webDriver = webDriver; diff --git a/src/test/java/au/gov/qld/online/selenium/SeleniumHelperTest.java b/src/test/java/au/gov/qld/online/selenium/SeleniumHelperTest.java index c84887e..bbecd29 100644 --- a/src/test/java/au/gov/qld/online/selenium/SeleniumHelperTest.java +++ b/src/test/java/au/gov/qld/online/selenium/SeleniumHelperTest.java @@ -3,7 +3,6 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -14,6 +13,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; +import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -35,7 +35,7 @@ public void tearDown() { } @Test - @Disabled("ubuntu has issues on profile popup which you can't get past atm") + //@Disabled("ubuntu has issues on profile popup which you can't get past atm") public void shouldStartFirefoxBrowser() { String testName = new Object(){}.getClass().getEnclosingMethod().getName(); SeleniumHelper.setDoScreenPrints(true); @@ -46,7 +46,6 @@ public void shouldStartFirefoxBrowser() { } @Test - @Disabled public void shouldStartFirefoxBrowserMultiTest() { String testName = new Object(){}.getClass().getEnclosingMethod().getName(); SeleniumHelper.setDoScreenPrints(true); @@ -64,11 +63,9 @@ public void shouldStartFirefoxBrowserMultiTest() { holder3.getWebDriver().navigate().to("https://www.whirlpool.net.au"); SeleniumHelper.performScreenPrint(holder3, testName); SeleniumHelper.close(holder); - int afterStart = SeleniumHelper.openDrivers(); } @Test - @Disabled public void shouldStartFirefoxChromeBrowserMultiMixTest() { String testName = new Object(){}.getClass().getEnclosingMethod().getName(); SeleniumHelper.setDoScreenPrints(true); @@ -159,7 +156,6 @@ public void shouldStartHtmlUnitBrowser() { } @Test - @Disabled public void shouldStartHtmlUnitWithJsBrowser() { String testName = new Object(){}.getClass().getEnclosingMethod().getName(); SeleniumHelper.setDoScreenPrints(true); @@ -170,7 +166,6 @@ public void shouldStartHtmlUnitWithJsBrowser() { } @Test - @Disabled public void shouldSetDownloadDirectoryForFirefoxBrowser() throws IOException { String testName = new Object(){}.getClass().getEnclosingMethod().getName(); SeleniumHelper.setDoScreenPrints(true); @@ -202,7 +197,7 @@ public void shouldSetDownloadDirectoryForChromeBrowser() throws IOException, Int try { Assertions.assertThat(downloadedFile).exists(); } catch (AssertionError e) { - Set files = Stream.of(tempDownloadDirectory.toFile().listFiles()) + Set files = Stream.of(Objects.requireNonNull(tempDownloadDirectory.toFile().listFiles())) .filter(file -> !file.isDirectory()) .map(File::getName) .collect(Collectors.toSet());