From be46b2742380047a94c6f341030bb9937efa12f9 Mon Sep 17 00:00:00 2001 From: Mat Walker Date: Sat, 6 Oct 2018 12:22:11 +1000 Subject: [PATCH 1/3] Updates to help with unofficial TATTS Katalon PoC --- .idea/compiler.xml | 2 +- .idea/misc.xml | 2 +- Controlium.iml | 34 +------- pom.xml | 81 ++++++++++++++++--- .../Controlium/ControlBase.java | 8 ++ .../Controlium/HTMLElement.java | 11 ++- .../Controlium/ObjectMapping.java | 43 ++++++++-- .../Controlium/SeleniumDriver.java | 8 +- 8 files changed, 136 insertions(+), 53 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index d2f785c..b986cf6 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -10,7 +10,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 18ec0b6..0b02394 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -7,7 +7,7 @@ - + \ No newline at end of file diff --git a/Controlium.iml b/Controlium.iml index 845e6c1..44ab72e 100644 --- a/Controlium.iml +++ b/Controlium.iml @@ -1,15 +1,13 @@ - + - - @@ -39,40 +37,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 53fa98c..3487e6e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 TeamControlium Controlium control-based Selenium abstraction - org.testcontrolium + org.teamcontrolium controlium - 1.0 + 1.0.2 TeamControlium Controlium provides the API and foundations for Control-based use of Selenium https://github.com/TeamControlium 2017 @@ -17,7 +17,7 @@ The MIT License - https://github.com/TeamControlium/Controlium.java/blob/master/LICENSE + https://github.com/TeamControlium/Controlium.java/blob/master/LICENSE.txt repo @@ -39,10 +39,64 @@ 3.7.0 - 10 - 10 + 1.8 + 1.8 + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.0.0 + + false + + + + attach-javadocs + + jar + + + + @@ -70,11 +124,6 @@ commons-io 2.5 - - org.junit.jupiter - junit-jupiter-api - 5.0.0 - org.jsoup @@ -84,7 +133,7 @@ org.teamcontrolium utilities - 1.1.0 + 1.2.2 org.junit.jupiter @@ -107,6 +156,16 @@ +10 + + K8Coder + Kate More + kmoor@alexview.com + + Java Developer + + TeamControlium Committers + +10 + \ No newline at end of file diff --git a/src/main/java/TeamControlium/Controlium/ControlBase.java b/src/main/java/TeamControlium/Controlium/ControlBase.java index 3796b7f..26248fb 100644 --- a/src/main/java/TeamControlium/Controlium/ControlBase.java +++ b/src/main/java/TeamControlium/Controlium/ControlBase.java @@ -149,6 +149,11 @@ public static T setControl(SeleniumDriver seleniumDriver } } + public static boolean controlExists(ControlBase parentControl,T control) { return parentControl.elementExists(control.getMapping());} + public static boolean controlExists(SeleniumDriver seleniumDriver, T control) { return seleniumDriver.findElementOrNull(control.getMapping())!=null;} + public static boolean controlExists(SeleniumDriver seleniumDriver, ControlBase parentControl, T control) { return seleniumDriver.findElement(parentControl.getMapping()).findElementOrNull(control.getMapping())!=null;} + + public boolean controlExists(T control) {return this.elementExists(control.getMapping());} // // All Controls must implement a ControlBeingSet. This is called when the Control is set upon (IE. Find logic applied and bound to a Selenium element). It really // will become useful when caching is implemented. It is used by a Control to do stuff when located in the Dom - IE. A dropdown control may click on it whenever @@ -175,6 +180,9 @@ public boolean isStale() { } } + public boolean elementExists(ObjectMapping mapping) { + return getRootElement().findElementOrNull(mapping)!=null; + } public void clearElement(ObjectMapping mapping) { findElement(mapping).clear(); diff --git a/src/main/java/TeamControlium/Controlium/HTMLElement.java b/src/main/java/TeamControlium/Controlium/HTMLElement.java index 71a3735..7875eaa 100644 --- a/src/main/java/TeamControlium/Controlium/HTMLElement.java +++ b/src/main/java/TeamControlium/Controlium/HTMLElement.java @@ -423,7 +423,7 @@ public void setText(String text,Duration retryInterval) { setText(text,1,retryInterval);} public void setText(String text,int maxTries,Duration retryInterval) { - RuntimeException lastException=null; + Exception lastException=null; throwIfUnbound(); if (maxTries<1) throw new RuntimeException(String.format("Maximum tries [%d]. Cannot be less than 1.",maxTries)); int tryIndex = 0; @@ -435,6 +435,7 @@ public void setText(String text,int maxTries,Duration retryInterval) { try { + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"Calling Selenium driver clear with WebElement. Driver %s, Element %s",getSeleniumDriver()==null?"Null":"Good",getUnderlyingWebElement()==null?"Null!":"Good"); getSeleniumDriver().clear(this.getUnderlyingWebElement()); enterText(text); if (tryIndex > 1) Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "{0} attempt attempt good.)", tryIndex); @@ -445,11 +446,16 @@ public void setText(String text,int maxTries,Duration retryInterval) Thread.sleep(retryInterval.toMillis()); lastException = e; } + catch (Exception e) + { + Thread.sleep(retryInterval.toMillis()); + lastException = e; + } } throw lastException; } catch (InvalidElementState ex) { - Logger.WriteLine(Logger.LogLevels.Error,"Error thrown setting text (clear then enter) in [%s] (Tried %d times): %s",getFriendlyName(),tryIndex,ex.getMessage()); + Logger.WriteLine(Logger.LogLevels.Error,"Error thrown setting text (clear then enter) in [%s] (Tried %d times): %s",getFriendlyName(),tryIndex,ex); throw new InvalidElementState(String.format("Error thrown setting text (clear then enter) in [%s] ([%s]). Tried %d times).",getFriendlyName(),getMappingDetails().getActualFindLogic(),tryIndex),ex); } @@ -480,6 +486,7 @@ public void enterText(String text,int maxTries,Duration retryInterval) { { try { + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"Calling Selenium driver setText with WebElement. Driver %s, Element %s, text = [%s]",getSeleniumDriver()==null?"Null":"Good",getUnderlyingWebElement()==null?"Null!":"Good",text==null?"":text); getSeleniumDriver().setText(this.getUnderlyingWebElement(),(text==null)?"":text); if (tryIndex > 1) Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "{0} attempt attempt good.)", tryIndex); return; diff --git a/src/main/java/TeamControlium/Controlium/ObjectMapping.java b/src/main/java/TeamControlium/Controlium/ObjectMapping.java index d356baa..208618f 100644 --- a/src/main/java/TeamControlium/Controlium/ObjectMapping.java +++ b/src/main/java/TeamControlium/Controlium/ObjectMapping.java @@ -1,8 +1,9 @@ package TeamControlium.Controlium; import java.lang.*; +import java.util.Map; + import TeamControlium.Utilities.Logger; -import javafx.util.Pair; import org.openqa.selenium.By; public class ObjectMapping { @@ -106,7 +107,7 @@ public ObjectMapping copy() { } } - public ObjectMapping ResolveParameters(String... params) { + public ObjectMapping resolveParameters(String... params) { String newFindLogic = null; String newFriendlyName = null; @@ -141,7 +142,7 @@ public ObjectMapping ResolveParameters(String... params) { private By processFindLogic(String property) { By returnValue; - Pair findLogicNameValue; + KeyValue findLogicNameValue; // // Get the find type and logic @@ -151,10 +152,10 @@ private By processFindLogic(String property) { } else { if (property.contains("=")) { String[] nameValue = property.split("=", 2); - findLogicNameValue = new Pair(nameValue[0], nameValue[1]); + findLogicNameValue = new KeyValue(nameValue[0], nameValue[1]); } else { // Default to xpath.... - findLogicNameValue = new Pair("xpath", property); + findLogicNameValue = new KeyValue("xpath", property); } switch (findLogicNameValue.getKey()) { @@ -198,4 +199,36 @@ private By processFindLogic(String property) { return returnValue; } } + + public class KeyValue implements Map.Entry + { + private K key; + private V value; + + public KeyValue(K key, V value) + { + this.key = key; + this.value = value; + } + + public K getKey() + { + return this.key; + } + + public V getValue() + { + return this.value; + } + + public K setKey(K key) + { + return this.key = key; + } + + public V setValue(V value) + { + return this.value = value; + } + } } diff --git a/src/main/java/TeamControlium/Controlium/SeleniumDriver.java b/src/main/java/TeamControlium/Controlium/SeleniumDriver.java index 59f1b5e..3aae3c0 100644 --- a/src/main/java/TeamControlium/Controlium/SeleniumDriver.java +++ b/src/main/java/TeamControlium/Controlium/SeleniumDriver.java @@ -268,6 +268,8 @@ public HTMLElement findElement(HTMLElement parentElement,ObjectMapping objectMap pollIntervalMillis, // Polling ionterval in milliseconds timer); // Find stopwatch timing whole finding + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"Got [%s] elements",clauseResults==null?"Null!":Integer.toString(clauseResults.size())); + if (clauseResults.size()==0) { String errorText = String.format("Time reached and found 0 matching elements using ([%s] - %s) from [%s] (Waited upto %dmS).", objectMapping.getActualFindLogic(), @@ -467,7 +469,8 @@ public void clear(Object webElement) { // // Usually thrown by Selenium when element stale // - throw new InvalidElementState("Unable to clear element. See underlying cause.",e); + Logger.WriteLine(Logger.LogLevels.Error,"Unable to clear element. See underlying cause: %s",e); + throw new InvalidElementState(String.format("Unable to clear element. See underlying cause: %s",e),e); } } @@ -895,10 +898,11 @@ else if (Browsers.isEdge()) { private List getHtmlElements(HTMLElement parentElement, ObjectMapping objectMapping, boolean allowMultipleMatches, boolean waitUntilSingle, boolean showMultiFound, long totalTimeoutMillis, long pollIntervalMillis, StopWatch timer) { List clauseResults = new ArrayList(); while (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) { + Logger.WriteLine(Logger.LogLevels.TestDebug, "Allow Multiple Matches [%s], Wait until single match [%s].", allowMultipleMatches?"true":"false",waitUntilSingle?"true":"false"); clauseResults = findElements(parentElement, objectMapping); + Logger.WriteLine(Logger.LogLevels.TestDebug, "Found %s elements matching [%s].", clauseResults==null?"Null!":Integer.toString(clauseResults.size()), objectMapping.getActualFindLogic()); if (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) { if (clauseResults.size() > 0 && showMultiFound) { - Logger.WriteLine(Logger.LogLevels.TestDebug, "Found %d elements matching [%s]. Waiting until only a single element is found...", clauseResults.size(), objectMapping.getActualFindLogic()); showMultiFound = false; } try { From 5e95b56ba7f7bff39aa5da99e23cd157dd462ede Mon Sep 17 00:00:00 2001 From: Mat Walker Date: Mon, 29 Oct 2018 19:45:31 +1000 Subject: [PATCH 2/3] Updates and fixed for issues found during TATTs PoC usage * ControlBase logging fixes * ControlBase added Selenium getCSSValue for Controls and member elements * HTMLElement logging fixes * HTMLElement added Selenium getCSSValue for Controlium HTMLElements * SeleniumDriver added logging of Selenium Driver hash code during launch to help debug Selenium startup issues * SeleniumDriver increased ability to get Selenium controlled browser windows * SeleniumDriver changed some logging levels to make messages more consistent --- .../Controlium/ControlBase.java | 43 ++++++++++- .../Controlium/HTMLElement.java | 33 ++++++++- .../Controlium/SeleniumDriver.java | 71 +++++++++++++++++-- 3 files changed, 137 insertions(+), 10 deletions(-) diff --git a/src/main/java/TeamControlium/Controlium/ControlBase.java b/src/main/java/TeamControlium/Controlium/ControlBase.java index 26248fb..7806ce3 100644 --- a/src/main/java/TeamControlium/Controlium/ControlBase.java +++ b/src/main/java/TeamControlium/Controlium/ControlBase.java @@ -94,10 +94,11 @@ public static T setControl(SeleniumDriver seleniumDriver StopWatch timeWaited = StopWatch.createStarted(); try { - Logger.WriteLine(Logger.LogLevels.TestInformation, "Setting on Control [%s] from Parent [%s]", + Logger.WriteLine(Logger.LogLevels.TestInformation, "Setting on Control [%s] from Parent [%s] with SeleniumDriver hash [%s] (WebDriver hash [%s])", newControl.getMapping() == null ? "No mapping logic!" : newControl.getMapping().getFriendlyName(), - parentControl == null ? "No parent Control - So Top Level control" : parentControl.getMapping() == null ? "No mapping logic!" : parentControl.getMapping().getFriendlyName()); - + parentControl == null ? "No parent Control - So Top Level control" : parentControl.getMapping() == null ? "No mapping logic!" : parentControl.getMapping().getFriendlyName(), + seleniumDriver==null?"null":Integer.toString(seleniumDriver.hashCode()), + seleniumDriver==null?"N/A":(seleniumDriver.getWebDriver()==null?"Null!":Integer.toString(seleniumDriver.getWebDriver().hashCode()))); // // Check if ParentControl has become stale (has been redrawn). If so, refresh it (force a new findElement on it). Note that this // will effectively ripple up to the top level @@ -248,6 +249,42 @@ public boolean hasAttribute(String attributeName) { } } + public String getCssValue(ObjectMapping mapping, String valueName) { + HTMLElement element = findElement(mapping); + try { + return element.getCssValue(valueName); + } + catch (Exception e) { + return ""; + } + } + public String getCssValue(String valueName) { + try { + return getRootElement().getCssValue(valueName); + } + catch (Exception e) { + return ""; + } + } + + public boolean hasCssValue(ObjectMapping mapping, String valueName) { + HTMLElement element = findElement(mapping); + try { + return element.hasCssValue(valueName); + } + catch (Exception e) { + return false; + } + } + public boolean hasCssValue(String valueName) { + try { + return getRootElement().hasCssValue(valueName); + } + catch (Exception e) { + return false; + } + } + public String getText(ObjectMapping mapping) { HTMLElement element = findElement(mapping); try { diff --git a/src/main/java/TeamControlium/Controlium/HTMLElement.java b/src/main/java/TeamControlium/Controlium/HTMLElement.java index 7875eaa..583e3a9 100644 --- a/src/main/java/TeamControlium/Controlium/HTMLElement.java +++ b/src/main/java/TeamControlium/Controlium/HTMLElement.java @@ -556,7 +556,7 @@ public String getAttribute(String attribute) { throw ex; } catch (Exception e) { - Logger.WriteLine(Logger.LogLevels.TestInformation,"Error thrown getting attribute [%s] from [%s]: %s",getFriendlyName(),e.getMessage()); + Logger.WriteLine(Logger.LogLevels.TestInformation,"Error thrown getting attribute [%s] from [%s]: %s",attribute,getFriendlyName(),e.getMessage()); throw new RuntimeException(String.format("Error thrown getting attribute [%s] from [%s] ([%s])",attribute==null?"Null":attribute,getFriendlyName(),getMappingDetails().getActualFindLogic()),e); } } @@ -570,11 +570,40 @@ public boolean hasAttribute(String attribute) { throw ex; } catch (Exception e) { - Logger.WriteLine(Logger.LogLevels.TestDebug,"Error thrown getting attribute [%s] from [%s]. Assume does not have attribute: %s",getFriendlyName(),e.getMessage()); + Logger.WriteLine(Logger.LogLevels.TestDebug,"Error thrown getting attribute [%s] from [%s]. Assume does not have attribute: %s",attribute,getFriendlyName(),e.getMessage()); return false; } } + public String getCssValue(String valueName) { + throwIfUnbound(); + try { + return getSeleniumDriver().getCssValue(getUnderlyingWebElement(),valueName); + } + catch (InvalidElementState ex) { + throw ex; + } + catch (Exception e) { + Logger.WriteLine(Logger.LogLevels.TestInformation,"Error thrown getting CSS value [%s] from [%s]: %s",valueName,getFriendlyName(),e.getMessage()); + throw new RuntimeException(String.format("Error thrown getting CSS value [%s] from [%s] ([%s])",valueName==null?"Null":valueName,getFriendlyName(),getMappingDetails().getActualFindLogic()),e); + } + } + + public boolean hasCssValue(String valueName) { + throwIfUnbound(); + try { + return getSeleniumDriver().hasCssValue(getUnderlyingWebElement(),valueName); + } + catch (InvalidElementState ex) { + throw ex; + } + catch (Exception e) { + Logger.WriteLine(Logger.LogLevels.TestDebug,"Error thrown getting CSS value [%s] from [%s]. Assume does not have CSS value: %s",valueName,getFriendlyName(),e.getMessage()); + return false; + } + } + + public void click() { throwIfUnbound(); try { diff --git a/src/main/java/TeamControlium/Controlium/SeleniumDriver.java b/src/main/java/TeamControlium/Controlium/SeleniumDriver.java index 3aae3c0..3bbf12d 100644 --- a/src/main/java/TeamControlium/Controlium/SeleniumDriver.java +++ b/src/main/java/TeamControlium/Controlium/SeleniumDriver.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import org.openqa.selenium.*; @@ -28,6 +29,7 @@ import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.ie.InternetExplorerDriverService; import org.openqa.selenium.ie.InternetExplorerOptions; +import org.openqa.selenium.internal.WrapsDriver; import org.w3c.dom.NodeList; import javax.swing.text.html.HTMLDocument; @@ -133,6 +135,9 @@ private void commonConstructs(boolean killFirst, String seleniumHost,String devi setSeleniumHost(seleniumHost); startOrConnectToSeleniumServer(killFirst); + Logger.WriteLine(Logger.LogLevels.FrameworkInformation,"Started SeleniumDriver. Hash code [%d]. WebDriver hash code [%s]", + this.hashCode(), + getWebDriver()==null?"null!":Integer.toString(getWebDriver().hashCode())); } @@ -158,6 +163,24 @@ public Duration setPageLoadTimeout(Duration pageLoadTimeout) { public Browsers getDevice() { return _browser; } public Browsers setDevice(Devices device) { _device=device; return getDevice();} + public Set getAllBrowserWindows() { + if (getWebDriver()!=null) { + return getWebDriver().getWindowHandles(); + } + else { + throw new RuntimeException("Cannot get Browser windows handles as WebDriver null!"); + } + } + + public void setBrowserWindow(String handle) { + if (getWebDriver()!=null) { + getWebDriver().switchTo().window(handle); + } + else { + throw new RuntimeException("Cannot set Browser window as WebDriver null!"); + } + } + public void setIFrame(HTMLElement htmlElement) { WebElement webElement = ((WebElement)htmlElement.getUnderlyingWebElement()); String tag = webElement.getTagName(); @@ -276,7 +299,7 @@ public HTMLElement findElement(HTMLElement parentElement,ObjectMapping objectMap objectMapping.getFriendlyName(), (parentElement == null) ? "DOM Top Level" : parentElement.getMappingDetails().getFriendlyName(), timer.getTime()); - Logger.WriteLine(Logger.LogLevels.Error, errorText); + Logger.WriteLine(Logger.LogLevels.FrameworkInformation, errorText); throw new RuntimeException(errorText); } @@ -351,7 +374,7 @@ public List findElements(HTMLElement parentElement, ObjectMapping m throw new RuntimeException("SeleniumDriver.FindElements called with mapping null!"); } - Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"ObjectMapping = [%s] (%s)",mapping.getOriginalFindLogic(),mapping.getFriendlyName()); + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"webDriver hash [%s], ObjectMapping = [%s] (%s)",webDriver==null?"Null!":Integer.toString(webDriver.hashCode()),mapping.getOriginalFindLogic(),mapping.getFriendlyName()); By seleniumFindBy = mapping.getSeleniumBy(); @@ -403,6 +426,19 @@ public List findElements(HTMLElement parentElement, ObjectMapping m return returnElements; } + public WebDriver getWebDriver() { return webDriver;} + public void setBrowserSize(int x, int y) { + if (webDriver==null) { + throw new RuntimeException("Selenium web driver has not been started!"); + } + webDriver.manage().window().setSize(new Dimension(x,y)); + } + public void setBrowserFullScreen() { + if (webDriver==null) { + throw new RuntimeException("Selenium web driver has not been started!"); + } + webDriver.manage().window().fullscreen(); + } public void gotoURL(String fullURLPath) { try { @@ -414,7 +450,6 @@ public void gotoURL(String fullURLPath) { throw e; } } - public String getPageTitle() { try { String title = webDriver.getTitle(); @@ -563,6 +598,7 @@ public void click(Object webElement) { if (webElement == null) throw new RuntimeException("webElement null!"); try { + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"Click using WebDriver hash [%s]",((WrapsDriver) webElement).getWrappedDriver()==null?"null!!":Integer.toString(((WrapsDriver) webElement).getWrappedDriver().hashCode())); ((WebElement) webElement).click(); } catch (WebDriverException wde) { String errorMessage = wde.getMessage(); @@ -632,6 +668,29 @@ public boolean hasAttribute(Object webElement,String attribute) { } } + public String getCssValue(Object webElement,String valueName) { + if (webElement==null) throw new RuntimeException("webElement null!"); + + try { + String cssValue = ((WebElement)webElement).getCssValue(valueName); + Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Got CSS Value [%s]: [%s]", valueName,(cssValue==null)?"Null":cssValue); + return (cssValue==null)?"":cssValue; + + } + catch (InvalidElementStateException e) { + // + // Usually thrown by Selenium when element stale + // + throw new InvalidElementState(String.format("Unable to get element CSS Value [%s]. See underlying cause.",(valueName==null)?"Null!!":valueName),e); + } + } + public boolean hasCssValue(Object webElement,String valueName) { + if (webElement==null) throw new RuntimeException("webElement null!"); + + return (!getCssValue(webElement,valueName).isEmpty()); + } + + public void scrollIntoView(Object webElement) { Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Scrolling element in to view using JavaScript injection - [Element].scrollIntoView()"); executeJavaScriptNoReturnData("arguments[0].scrollIntoView();", webElement); @@ -856,8 +915,6 @@ else if (Browsers.isChrome()) { String executable = "ChromeDriver.exe"; ChromeOptions options = new ChromeOptions(); - - setPathToDriverIfExistsAndIsExecutable(seleniumServerFolder, ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY,executable); if (seleniumDebugMode) System.setProperty(ChromeDriverService.CHROME_DRIVER_VERBOSE_LOG_PROPERTY, "true"); @@ -870,6 +927,7 @@ else if (Browsers.isChrome()) { if (killFirst) killAllProcesses(executable); webDriver = new ChromeDriver(ChromeDriverService.createDefaultService(), options); + Logger.WriteLine(Logger.LogLevels.FrameworkDebug,"Chrome driver created. Hash [%d]",webDriver.hashCode()); } else if (Browsers.isEdge()) { String executable = "EdgeDriver.exe"; @@ -893,6 +951,7 @@ else if (Browsers.isEdge()) { } catch (Exception e) { throw new RuntimeException(String.format("Error instantiating [%s] (%s)", Browsers.isChrome() ? "Chrome" : Browsers.isEdge() ? "Edge" : Browsers.isInternetExplorer() ? "Internet Explorer" : Browsers.isSafari() ? "Safari" : "UNKNOWN!", seleniumServerFolder)); } + } private List getHtmlElements(HTMLElement parentElement, ObjectMapping objectMapping, boolean allowMultipleMatches, boolean waitUntilSingle, boolean showMultiFound, long totalTimeoutMillis, long pollIntervalMillis, StopWatch timer) { @@ -922,6 +981,8 @@ private void setPathToDriverIfExistsAndIsExecutable(final String pathToDriver, f if (driver.exists() && driver.canExecute()) { System.setProperty(driverExeProperty, driver.getAbsolutePath()); } else { + + throw new IllegalArgumentException(String.format("Driver not found or is not executable in %s", pathToDriver)); } } From e623f81ea653a5a0402439565349120c1061418f Mon Sep 17 00:00:00 2001 From: Mat Walker Date: Mon, 29 Oct 2018 19:54:03 +1000 Subject: [PATCH 3/3] Updated to use latest (1.2.3) TeamControlium utilities --- Controlium.iml | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Controlium.iml b/Controlium.iml index 44ab72e..8a430ab 100644 --- a/Controlium.iml +++ b/Controlium.iml @@ -41,7 +41,7 @@ - + diff --git a/pom.xml b/pom.xml index 3487e6e..0ef5a9b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ TeamControlium Controlium control-based Selenium abstraction org.teamcontrolium controlium - 1.0.2 + 1.1.0 TeamControlium Controlium provides the API and foundations for Control-based use of Selenium https://github.com/TeamControlium 2017 @@ -133,7 +133,7 @@ org.teamcontrolium utilities - 1.2.2 + 1.2.3 org.junit.jupiter