+ update tabdriver for the new millenium

master
io42630 1 year ago
parent 220243fbd8
commit c8e7f80c83

@ -1 +1,2 @@
java temurin-17
java temurin-17.0.9+9

@ -1,4 +1,9 @@
# TabDriver
= TabDriver
:stylesheet: ../shared/adoc-styles.css
:toc:
:toclevels: 4
* Wrapper for `selenium` to make it easier to use.
* Must use `Chrome` (not `Chromium`).

@ -0,0 +1,3 @@
#!/bin/bash
mvn clean install deploy &

@ -2,8 +2,11 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.olexyn</groupId>
<parent>
<groupId>com.olexyn</groupId>
<artifactId>min-root</artifactId>
<version>jdk17-0.0</version>
</parent>
<artifactId>tabdriver</artifactId>
<version>1.2.2</version>
<packaging>jar</packaging>
@ -11,8 +14,6 @@
<name>tabdriver</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<xx.java.version>17</xx.java.version>
<xx.selenium.version>3.141.59</xx.selenium.version>
<xx.webdriver.version>0.9.7376</xx.webdriver.version>
</properties>
@ -21,8 +22,8 @@
<dependencies>
<dependency>
<groupId>com.olexyn</groupId>
<artifactId>zeebom</artifactId>
<version>1.1</version>
<artifactId>min-bom</artifactId>
<version>jdk17-0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -31,9 +32,8 @@
<dependencies>
<dependency>
<groupId>com.olexyn.min.log</groupId>
<groupId>com.olexyn</groupId>
<artifactId>min-log</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<!-- must come before selenium -->
@ -71,55 +71,13 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.olexyn</groupId>
<artifactId>propconf</artifactId>
<version>1.1</version>
<artifactId>min-prop</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${xx.java.version}</source>
<target>${xx.java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<altDeploymentRepository>internal.repo::default::http://localhost:9020/repository/maven-releases/</altDeploymentRepository>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<url>http://localhost:9020/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<url>http://localhost:9020/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>

@ -11,4 +11,5 @@ public interface Constants {
String LABEL = "label";
String CLASS = "class";
String CHECKBOX = "checkbox";
String ABOUT_BLANK = "about:blank";
}

@ -0,0 +1,32 @@
package com.olexyn.tabdriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.HashMap;
public abstract class DefaultTabDriverConfig implements TabDriverConfigProvider {
@Override
public DesiredCapabilities getCapabilities() {
var cap = DesiredCapabilities.chrome();
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
if (isHeadless()) {
options.addArguments("--window-size=1920,1080");
options.addArguments("--headless");
}
// see also https://chromium.googlesource.com/chromium/src/+/master/chrome/common/pref_names.cc
HashMap<String, Object> chromePrefs = new HashMap<>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", getDownloadDir());
chromePrefs.put("download.prompt_for_download", false);
options.setExperimentalOption("prefs", chromePrefs);
cap.setCapability(ChromeOptions.CAPABILITY, options);
return cap;
}
}

@ -3,26 +3,15 @@ package com.olexyn.tabdriver;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class Tab {
@Getter
@Setter
String handle;
@Getter
@Setter
String name;
@Getter
@Setter
String url;
@Getter
@Setter
String purpose;
public Tab(String handle) {
this.handle = handle;
}

@ -1,31 +1,83 @@
package com.olexyn.tabdriver;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.olexyn.min.log.LogU;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchFrameException;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
public class TabDriver extends ChromeDriver implements JavascriptExecutor {
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static com.olexyn.tabdriver.Constants.ABOUT_BLANK;
@SuppressWarnings("unused")
public class TabDriver implements JavascriptExecutor {
private final Map<String, Tab> tabs = new HashMap<>();
private final ChromeDriver chromeDriver;
@SuppressWarnings("deprecation")
public TabDriver(TabDriverConfigProvider configProvider) {
var path = configProvider.getDriverPath();
var service = new ChromeDriverService.Builder()
.usingDriverExecutable(path.toFile())
.usingAnyFreePort()
.build();
chromeDriver = new ChromeDriver(service, configProvider.getCapabilities());
chromeDriver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
}
public WebDriver.Navigation navigate() {
return chromeDriver.navigate();
}
public WebDriver.TargetLocator switchTo() {
return chromeDriver.switchTo();
}
public String getWindowHandle() {
return chromeDriver.getWindowHandle();
}
public Set<String> getWindowHandles() {
return chromeDriver.getWindowHandles();
}
public String getTitle() {
return chromeDriver.getTitle();
}
public String getCurrentUrl() {
return chromeDriver.getCurrentUrl();
}
private final Map<String, Tab> TABS = new HashMap<>();
public String getPageSource() {
return chromeDriver.getPageSource();
}
public void close() {
chromeDriver.close();
}
public TabDriver(ChromeDriverService service, Capabilities capabilities) {
super(service, capabilities);
manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
public void quit() {
chromeDriver.quit();
}
public List<WebElement> findElements(By by) {
return chromeDriver.findElements(by);
}
public synchronized void registerCurrentTab(String purpose) {
@ -33,28 +85,28 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
tab.setName(getTitle());
tab.setUrl(getCurrentUrl());
tab.setPurpose(purpose);
TABS.put(tab.getHandle(), tab);
tabs.put(tab.getHandle(), tab);
}
public synchronized Tab getCurrentTab() {
return TABS.get(getWindowHandle());
return tabs.get(getWindowHandle());
}
public synchronized List<Tab> getTabByPurpose(String purpose) {
return TABS.values().stream()
.filter(x -> x.getPurpose() == purpose)
.collect(Collectors.toList());
return tabs.values().stream()
.filter(x -> Objects.equals(x.getPurpose(), purpose))
.toList();
}
public synchronized String registerBlankTab(String purpose) {
Set<String> openTabHandles = getWindowHandles();
for (String openTabHandle : openTabHandles) {
if (!TABS.containsKey(openTabHandle)) {
if (!tabs.containsKey(openTabHandle)) {
Tab blankTab = new Tab(openTabHandle);
blankTab.setName("about:blank");
blankTab.setUrl("about:blank");
blankTab.setName(ABOUT_BLANK);
blankTab.setUrl(ABOUT_BLANK);
blankTab.setPurpose(purpose);
TABS.put(openTabHandle, blankTab);
tabs.put(openTabHandle, blankTab);
return openTabHandle;
}
}
@ -68,12 +120,12 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
tab.setName(getTitle());
tab.setUrl(getCurrentUrl());
tab.setPurpose(purpose);
TABS.put(handle, tab);
tabs.put(handle, tab);
return handle;
}
public synchronized void switchToTab(String handle) {
for (Entry<String, Tab> entry : TABS.entrySet()) {
for (Entry<String, Tab> entry : tabs.entrySet()) {
String tabHandle = entry.getKey();
if (tabHandle.equals(handle)) {
switchTo().window(tabHandle);
@ -90,14 +142,15 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
* If the current tab is empty, it is registered - this happens usually only with the initial tab of the session.
*/
public synchronized void newTab(String purpose) {
String currentUrl = getCurrentUrl();
String currentUrl = getCurrentUrl(); // TODO this throws error, just get a new window
if (currentUrl.isEmpty()
|| currentUrl.equals("data:,")
|| currentUrl.equals("about:blank")) {
|| currentUrl.equals(ABOUT_BLANK)) {
registerExistingTab(purpose);
} else {
executeScript("window.open(arguments[0])");
switchToTab(registerBlankTab(purpose));
Optional.ofNullable(registerBlankTab(purpose))
.ifPresent(this::switchToTab);
}
}
@ -115,14 +168,12 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
navigate().refresh();
}
@Override
public synchronized void get(String url) {
super.get(url);
chromeDriver.get(url);
}
@Override
public synchronized WebElement findElement(By by) {
return super.findElement(by);
return chromeDriver.findElement(by);
}
public synchronized void executeScript(String script) {
@ -182,10 +233,16 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
return FRAME_ID_NONE_FOUND;
}
// @Override
// public boolean isJavascriptEnabled() {
// return false;
// }
@Override
public Object executeScript(String script, Object... args) {
return null;
}
@Override
public Object executeAsyncScript(String script, Object... args) {
return null;
}
public enum CRITERIA {
CLASS,
@ -236,10 +293,6 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
return filterElementListBy(elements, CRITERIA.NONE, Constants.EMPTY);
}
public synchronized List<WebElement> findElements(By by) {
return findElements(by);
}
public synchronized void followContainedLink(WebElement element) {
String link = element.getAttribute("href");
if (link != null) { navigate().to(link); }
@ -256,6 +309,15 @@ public class TabDriver extends ChromeDriver implements JavascriptExecutor {
combo.findElement(By.cssSelector("li[data-value='" + dataValue + "']")).click();
}
public synchronized Optional<WebElement> findByCss(String css) {
try {
return Optional.of(findElement(By.cssSelector(css)));
} catch (Exception e) {
return Optional.empty();
}
}
/**
* Any-Match.
*/

@ -1,59 +0,0 @@
package com.olexyn.tabdriver;
import java.nio.file.Path;
import java.util.HashMap;
import com.olexyn.propconf.PropConf;
import lombok.experimental.UtilityClass;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
@UtilityClass
public class TabDriverBuilder {
private static Path CONFIG_PATH;
public static TabDriver build(Path path) {
CONFIG_PATH = path;
if (CONFIG_PATH == null) {
throw new RuntimeException("CONFIG_PATH must be set to an absolute path.");
}
return new TabDriver(configureService(), configureCapabilities());
}
private static ChromeDriverService configureService() {
PropConf.loadProperties(CONFIG_PATH.toString());
var path = Path.of(PropConf.get("chrome.driver.path"));
return new ChromeDriverService.Builder()
.usingDriverExecutable(path.toFile())
.usingAnyFreePort()
.build();
}
private static DesiredCapabilities configureCapabilities() {
var cap = DesiredCapabilities.chrome();
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
if (PropConf.is("headless")) {
options.addArguments("--window-size=1920,1080");
options.addArguments("--headless");
}
// see also https://chromium.googlesource.com/chromium/src/+/master/chrome/common/pref_names.cc
HashMap<String, Object> chromePrefs = new HashMap<>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", PropConf.get("download.dir"));
chromePrefs.put("download.prompt_for_download", false);
options.setExperimentalOption("prefs", chromePrefs);
cap.setCapability(ChromeOptions.CAPABILITY, options);
return cap;
}
}

@ -0,0 +1,19 @@
package com.olexyn.tabdriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.nio.file.Path;
public interface TabDriverConfigProvider {
Path getDriverPath();
String getDownloadDir();
boolean isHeadless();
DesiredCapabilities getCapabilities();
}
Loading…
Cancel
Save