Skip to content

Commit 26f1c77

Browse files
author
Mat Walker
committed
Can Launch local ChromeDriver - not ready for release yet
1 parent dea4024 commit 26f1c77

File tree

3 files changed

+230
-26
lines changed

3 files changed

+230
-26
lines changed

src/main/java/TeamControlium/Controlium/Browsers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public static void SetTestBrowser(String browser) {
108108
} catch (Exception e) {
109109
if (browser==null || browser.isEmpty()) {
110110
Logger.WriteLine(Logger.LogLevels.Error, String.format("Cannot get Browser type setting from test data: [%s],[%s]. Defaulting to Chrome", ConfigBrowser[0], ConfigBrowser[1], e.getMessage()));
111-
throw new RuntimeException(String.format("Error getting setting [%s],[%s].", ConfigBrowser[0], ConfigBrowser[1]), e);
111+
browser="Chrome";
112112
}
113113
}
114114

src/main/java/TeamControlium/Controlium/Devices.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ public static void SetTestDevice(String device) {
7979
}
8080
} catch (Exception e) {
8181
if (device==null || device.isEmpty()) {
82-
Logger.WriteLine(Logger.LogLevels.Error, String.format("Cannot get Device type setting from test data: [%s],[%s]. Error: %s", ConfigDevice[0], ConfigDevice[1], e.getMessage()));
83-
throw new RuntimeException(String.format("Error getting setting [%s],[%s].", ConfigDevice[0], ConfigDevice[1]), e);
82+
Logger.WriteLine(Logger.LogLevels.Error, String.format("Cannot get Device type setting from test data: [%s],[%s]. Defaulting to Windows", ConfigDevice[0], ConfigDevice[1]));
83+
device = "Windows";
8484
}
8585
}
8686

src/main/java/TeamControlium/Controlium/SeleniumDriver.java

Lines changed: 227 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,31 @@
33
import TeamControlium.Utilities.Logger;
44

55
import TeamControlium.Utilities.TestData;
6+
import org.apache.commons.io.FilenameUtils;
67
import org.apache.commons.lang3.time.StopWatch;
78
import org.openqa.selenium.By;
89
import org.openqa.selenium.JavascriptExecutor;
910
import org.openqa.selenium.WebDriver;
1011
import org.openqa.selenium.WebElement;
11-
12+
import org.openqa.selenium.chrome.ChromeDriver;
13+
import org.openqa.selenium.chrome.ChromeDriverService;
14+
import org.openqa.selenium.chrome.ChromeOptions;
15+
import org.openqa.selenium.edge.EdgeDriver;
16+
import org.openqa.selenium.edge.EdgeDriverService;
17+
import org.openqa.selenium.edge.EdgeOptions;
18+
import org.openqa.selenium.ie.InternetExplorerDriver;
19+
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
20+
import org.openqa.selenium.ie.InternetExplorerDriverService;
21+
import org.openqa.selenium.ie.InternetExplorerOptions;
22+
23+
import javax.swing.text.Utilities;
24+
import java.io.File;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
27+
import java.nio.file.Paths;
1228
import java.time.Duration;
1329
import java.util.ArrayList;
30+
import java.util.Arrays;
1431
import java.util.List;
1532
import java.util.concurrent.TimeUnit;
1633

@@ -40,6 +57,10 @@ public class SeleniumDriver {
4057
private Browsers _browser=null;
4158
private Devices _device=null;
4259
private String seleniumHost;
60+
private boolean isLocalSelenium=true;
61+
private String seleniumServerFolder=null;
62+
private boolean seleniumDebugMode=false;
63+
private String seleniumLogFilename=null;
4364

4465
public SeleniumDriver(String seleniumHost,String device,String browser) {
4566
commonConstructs();
@@ -58,19 +79,49 @@ public SeleniumDriver(String device,String browser) {
5879
Browsers.SetTestBrowser(browser);
5980
Devices.SetTestDevice(device);
6081
setSeleniumHost(seleniumHost);
82+
startOrConnectToSeleniumServer();
6183
}
6284
public SeleniumDriver() {
6385
commonConstructs();
6486
Browsers.SetTestBrowser();
6587
Devices.SetTestDevice();
6688
setSeleniumHost(null);
89+
startOrConnectToSeleniumServer();
6790
}
6891

6992
private void commonConstructs() {
7093
// Initialise defaults
7194
setFindTimeout(Duration.ofMillis(defaultTimeout));
7295
setPollInterval(Duration.ofMillis(defaultPollInterval));
7396
setPageLoadTimeout(Duration.ofMillis(defaultTimeout));
97+
98+
// Selenium Parameters
99+
try {
100+
seleniumServerFolder = TestData.getItem(String.class, SeleniumServerFolder[0], SeleniumServerFolder[1]);
101+
}
102+
catch (Exception e){
103+
Logger.WriteLine(Logger.LogLevels.TestDebug, "Selenium Server Folder not set in TestData (%s.%s). Defaulting to local",SeleniumServerFolder[0], SeleniumServerFolder[1]);
104+
seleniumServerFolder = System.getProperty("user.dir");
105+
}
106+
Logger.WriteLine(Logger.LogLevels.TestInformation, "Selenium Server Folder [%s]",seleniumServerFolder);
107+
108+
try {
109+
seleniumDebugMode = TeamControlium.Utilities.General.IsValueTrue(TestData.getItem(String.class, SeleniumDebugMode[0], SeleniumDebugMode[1]));
110+
}
111+
catch (Exception e){
112+
Logger.WriteLine(Logger.LogLevels.TestDebug, "Selenium Server debug mode not set in TestData (%s.%s). Defaulting to off",SeleniumDebugMode[0], SeleniumDebugMode[1]);
113+
seleniumDebugMode=false;
114+
}
115+
Logger.WriteLine(Logger.LogLevels.TestInformation, "Selenium Debug Mode: [%s]",seleniumDebugMode?"on":"off");
116+
117+
try {
118+
seleniumLogFilename = TestData.getItem(String.class, SeleniumLogFilename[0], SeleniumLogFilename[1]);
119+
}
120+
catch (Exception e){
121+
Logger.WriteLine(Logger.LogLevels.TestDebug, "Selenium Log filename not set in TestData (%s.%s). Defaulting to stdio (console)",SeleniumLogFilename[0], SeleniumLogFilename[1]);
122+
seleniumLogFilename=null;
123+
}
124+
Logger.WriteLine(Logger.LogLevels.TestInformation, "Selenium Log filename: [%s]",seleniumLogFilename==null?"stdio (console)":seleniumLogFilename);
74125
}
75126

76127

@@ -223,27 +274,6 @@ public HTMLElement findElement(HTMLElement parentElement,ObjectMapping objectMap
223274
return clauseResults.get(0);
224275
}
225276

226-
private List<HTMLElement> getHtmlElements(HTMLElement parentElement, ObjectMapping objectMapping, boolean allowMultipleMatches, boolean waitUntilSingle, boolean showMultiFound, long totalTimeoutMillis, long pollIntervalMillis, StopWatch timer) {
227-
List<HTMLElement> clauseResults = new ArrayList<HTMLElement>();
228-
while (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) {
229-
clauseResults = findElements(parentElement, objectMapping);
230-
if (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) {
231-
if (clauseResults.size() > 0 && showMultiFound) {
232-
Logger.WriteLine(Logger.LogLevels.TestDebug, "Found %d elements matching [%s]. Waiting until only a single element is found...", clauseResults.size(), objectMapping.getActualFindLogic());
233-
showMultiFound = false;
234-
}
235-
try {
236-
Thread.sleep(pollIntervalMillis);
237-
} catch (Exception e) {
238-
Logger.WriteLine(Logger.LogLevels.Error, "Thread.sleep threw an exception after %s so aborting", durationFormatted(timer.getTime()));
239-
throw new RuntimeException(String.format("Exception thrown while thread sleeping during Find Element (for [%s]) poll interval!", objectMapping.getFriendlyName()));
240-
}
241-
if (timer.getTime() >= totalTimeoutMillis) break;
242-
}
243-
}
244-
return clauseResults;
245-
}
246-
247277
public List<HTMLElement> findElements(HTMLElement parentElement, ObjectMapping mapping) {
248278

249279
List<WebElement> foundElements;
@@ -336,7 +366,13 @@ public void executeJavaScriptNoReturnData(String script, Object[] args)
336366
Object dummy = executeJavaScript(Object.class,script,args);
337367
}
338368

339-
public static void resetSettings() {
369+
370+
private void startOrConnectToSeleniumServer() {
371+
if (isLocalSelenium) {
372+
setupLocalRun();
373+
} else {
374+
throw new RuntimeException("Remote server execution mot yet implemented!");
375+
}
340376
}
341377

342378
private void setSeleniumHost(String host) {
@@ -356,6 +392,174 @@ private void setSeleniumHost(String host) {
356392
}
357393
seleniumHost="localhost";
358394
}
395+
isLocalSelenium = (seleniumHost.equalsIgnoreCase("localhost") || seleniumHost.equals("127.0.0.1"));
396+
}
397+
398+
private void setupLocalRun() {
399+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Running Selenium locally");
400+
401+
try {
402+
if (Browsers.isInternetExplorer()) {
403+
//
404+
// See https://code.google.com/p/selenium/issues/detail?id=4403
405+
//
406+
String executable="IEDriver.exe";
407+
InternetExplorerOptions IEO = new InternetExplorerOptions();
408+
IEO.destructivelyEnsureCleanSession();
409+
410+
setPathToDriverIfExistsAndIsExecutable(seleniumServerFolder, InternetExplorerDriverService.IE_DRIVER_EXE_PROPERTY,executable);
411+
if (seleniumDebugMode)
412+
System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY, "INFO");
413+
414+
415+
if (seleniumLogFilename != null) {
416+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to: %s", seleniumLogFilename);
417+
System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY, CheckAndPreparSeleniumLogFile(seleniumLogFilename));
418+
} else {
419+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to console");
420+
}
421+
422+
InternetExplorerDriverService service = InternetExplorerDriverService.createDefaultService();
423+
424+
IEO.setCapability("INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS", (boolean) true); // Enabling this as part of #ITSD1-1126 - If any issues come back to request
425+
Logger.WriteLine(Logger.LogLevels.TestInformation, "IE Browser being used. Setting INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS active. #ITSD1-1126");
426+
webDriver = new InternetExplorerDriver(service, IEO);
427+
}
428+
else if (Browsers.isChrome()) {
429+
String executable = "ChromeDriver.exe";
430+
ChromeOptions options = new ChromeOptions();
431+
432+
433+
434+
setPathToDriverIfExistsAndIsExecutable(seleniumServerFolder, ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY,executable);
435+
if (seleniumDebugMode) System.setProperty(ChromeDriverService.CHROME_DRIVER_VERBOSE_LOG_PROPERTY, "true");
436+
437+
if (seleniumLogFilename != null) {
438+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to: %s", seleniumLogFilename);
439+
System.setProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, CheckAndPreparSeleniumLogFile(seleniumLogFilename));
440+
} else {
441+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to console");
442+
}
443+
444+
webDriver = new ChromeDriver(ChromeDriverService.createDefaultService(), options);
445+
}
446+
else if (Browsers.isEdge()) {
447+
String executable = "EdgeDriver.exe";
448+
EdgeOptions options = new EdgeOptions();
449+
450+
setPathToDriverIfExistsAndIsExecutable(seleniumServerFolder, EdgeDriverService.EDGE_DRIVER_EXE_PROPERTY,executable);
451+
if (seleniumDebugMode) System.setProperty(EdgeDriverService.EDGE_DRIVER_VERBOSE_LOG_PROPERTY, "true");
452+
453+
if (seleniumLogFilename != null) {
454+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to: %s", seleniumLogFilename);
455+
System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, CheckAndPreparSeleniumLogFile(seleniumLogFilename));
456+
} else {
457+
Logger.WriteLine(Logger.LogLevels.FrameworkInformation, "Writing Selenium Server Output to console");
458+
}
459+
460+
webDriver = new EdgeDriver(EdgeDriverService.createDefaultService(), options);
461+
}
462+
else {
463+
throw new RuntimeException(String.format("Browser [%s] not yet implemented!",Browsers.getBrowserType().name()));
464+
}
465+
} catch (Exception e) {
466+
throw new RuntimeException(String.format("Error instantiating [%s] (%s)", Browsers.isChrome() ? "Chrome" : Browsers.isEdge() ? "Edge" : Browsers.isInternetExplorer() ? "Internet Explorer" : Browsers.isSafari() ? "Safari" : "UNKNOWN!", seleniumServerFolder));
467+
}
468+
}
469+
470+
private List<HTMLElement> getHtmlElements(HTMLElement parentElement, ObjectMapping objectMapping, boolean allowMultipleMatches, boolean waitUntilSingle, boolean showMultiFound, long totalTimeoutMillis, long pollIntervalMillis, StopWatch timer) {
471+
List<HTMLElement> clauseResults = new ArrayList<HTMLElement>();
472+
while (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) {
473+
clauseResults = findElements(parentElement, objectMapping);
474+
if (clauseResults.size() == 0 || (clauseResults.size() != 1 && !allowMultipleMatches && waitUntilSingle)) {
475+
if (clauseResults.size() > 0 && showMultiFound) {
476+
Logger.WriteLine(Logger.LogLevels.TestDebug, "Found %d elements matching [%s]. Waiting until only a single element is found...", clauseResults.size(), objectMapping.getActualFindLogic());
477+
showMultiFound = false;
478+
}
479+
try {
480+
Thread.sleep(pollIntervalMillis);
481+
} catch (Exception e) {
482+
Logger.WriteLine(Logger.LogLevels.Error, "Thread.sleep threw an exception after %s so aborting", durationFormatted(timer.getTime()));
483+
throw new RuntimeException(String.format("Exception thrown while thread sleeping during Find Element (for [%s]) poll interval!", objectMapping.getFriendlyName()));
484+
}
485+
if (timer.getTime() >= totalTimeoutMillis) break;
486+
}
487+
}
488+
return clauseResults;
489+
}
490+
491+
492+
private void setPathToDriverIfExistsAndIsExecutable(final String pathToDriver, final String driverExeProperty,String executable) {
493+
final File driver = new File(pathToDriver,executable);
494+
if (driver.exists() && driver.canExecute()) {
495+
System.setProperty(driverExeProperty, driver.getAbsolutePath());
496+
} else {
497+
throw new IllegalArgumentException(String.format("Driver not found or is not executable in %s", pathToDriver));
498+
}
499+
}
500+
501+
private String CheckAndPreparSeleniumLogFile(String SeleniumDebugFile) {
502+
String seleniumDebugFile = SeleniumDebugFile;
503+
String pathAndFile = "";
504+
505+
if (seleniumDebugFile==null || seleniumDebugFile.isEmpty())
506+
return null;
507+
else
508+
{
509+
//
510+
// If path is relative, make it absolute..
511+
//
512+
final File debugFile = new File(seleniumDebugFile);
513+
String seleniumDebugFileFolder = debugFile.getAbsolutePath();
514+
515+
// File path/name is passed on CMD line so remove all spaces
516+
String seleniumDebugFileName = FilenameUtils.removeExtension(seleniumDebugFile);
517+
String seleniumDebugFileExt = FilenameUtils.getExtension(seleniumDebugFile);
518+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "SeleniumDebugFile: [%s]",seleniumDebugFile);
519+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "seleniumDebugFileFolder: [%s]",seleniumDebugFileFolder);
520+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "seleniumDebugFileName: [%s]",seleniumDebugFileName);
521+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "seleniumDebugFileExt: [%s]",seleniumDebugFileExt);
522+
523+
524+
if (seleniumDebugFileFolder==null || seleniumDebugFileFolder.isEmpty()) seleniumDebugFileFolder = System.getProperty("user.dir");
525+
526+
try
527+
{
528+
int TotalPathLength = seleniumDebugFileFolder.length() + seleniumDebugFileName.length() + seleniumDebugFileExt.length() + 2;
529+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Selenium Debug File - [%s %s.%s]", seleniumDebugFileFolder, seleniumDebugFileName, seleniumDebugFileExt);
530+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Selenium Debug File TotalPathLength = %d", TotalPathLength);
531+
if (TotalPathLength > 248)
532+
{
533+
//
534+
// Max path length is 248, so we need to fiddle....
535+
//
536+
if ((seleniumDebugFileFolder.length() - seleniumDebugFileName.length() - seleniumDebugFileExt.length() -2) > 248)
537+
{
538+
// Ok, we cant do it so bomb out.
539+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "seleniumDebugFileFolder length %d so cannot fix path length by truncating seleniumDebugFileName", seleniumDebugFileFolder.length());
540+
throw new RuntimeException(String.format("Cannot Selenium Debug file. Full path [%d] would have been too long (Max 248 chars)",TotalPathLength));
541+
}
542+
else
543+
{
544+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Reducing path length by truncating seleniumDebugFileName (length currently %d)", seleniumDebugFileName.length());
545+
// Ok, we can do it. Just truncate the TestID the required length...
546+
seleniumDebugFileName = seleniumDebugFileName.substring(0, seleniumDebugFileName.length() - (TotalPathLength - 248));
547+
Logger.WriteLine(Logger.LogLevels.FrameworkDebug, "Reduced to length %d", seleniumDebugFileName.length());
548+
}
549+
}
550+
551+
pathAndFile = Paths.get(seleniumDebugFileFolder,(seleniumDebugFileName + seleniumDebugFileExt)).toString();
552+
553+
(new File(pathAndFile)).mkdirs();
554+
555+
Files.write(Paths.get(pathAndFile), Arrays.asList("TeamControlium Selenium Debug File"));
556+
return pathAndFile;
557+
}
558+
catch (Exception ex)
559+
{
560+
throw new RuntimeException(String.format("Error creating Selenium Debug information file (%s): %s", pathAndFile,ex.getMessage()));
561+
}
562+
}
359563
}
360564

361565
private String durationFormatted(Duration duration) {

0 commit comments

Comments
 (0)