diff --git a/lightning-adapter/pom.xml b/lightning-adapter/pom.xml
new file mode 100644
index 0000000..6ec4ac7
--- /dev/null
+++ b/lightning-adapter/pom.xml
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+
+ com.aerokube.lightning
+ lightning-parent
+ 1.2.2-SNAPSHOT
+
+
+ lightning-adapter
+
+ Lightning Adapter
+ Adapter classes to use Lightning with existing Selenium tests
+
+
+ 4.1.4
+
+
+
+
+ com.aerokube.lightning
+ lightning
+
+
+ org.seleniumhq.selenium
+ selenium-api
+ ${selenium-api.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.hamcrest
+ hamcrest
+ test
+
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ test
+
+
+
+
diff --git a/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebDriver.java b/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebDriver.java
new file mode 100644
index 0000000..72ab4f9
--- /dev/null
+++ b/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebDriver.java
@@ -0,0 +1,487 @@
+package com.aerokube.lightning.adapter;
+
+import com.aerokube.lightning.Position;
+import com.aerokube.lightning.Size;
+import com.aerokube.lightning.model.LocatorStrategy;
+import org.openqa.selenium.*;
+import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException;
+import org.openqa.selenium.logging.Logs;
+
+import javax.annotation.Nonnull;
+import java.net.URL;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static com.aerokube.lightning.By.cssSelector;
+
+public class SeleniumWebDriver implements WebDriver, WebDriver.Options, WebDriver.Navigation, WebDriver.TargetLocator, WebDriver.Timeouts, WebDriver.Window, Alert, JavascriptExecutor, TakesScreenshot, HasCapabilities {
+
+ private final com.aerokube.lightning.WebDriver webDriver;
+
+ public SeleniumWebDriver(com.aerokube.lightning.WebDriver webDriver) {
+ this.webDriver = webDriver;
+ }
+
+ static T execute(@Nonnull Callable action) {
+ try {
+ return action.call();
+ } catch (com.aerokube.lightning.WebDriverException e) {
+ throw processException(e);
+ } catch (Exception e) {
+ throw new WebDriverException(e);
+ }
+ }
+
+ private static WebDriverException processException(com.aerokube.lightning.WebDriverException e) {
+ switch (e.getErrorCode()) {
+ case ELEMENT_CLICK_INTERCEPTED:
+ return new ElementClickInterceptedException(e.getMessage(), e);
+ case ELEMENT_NOT_INTERACTABLE:
+ return new ElementNotInteractableException(e.getMessage(), e);
+ case INSECURE_CERTIFICATE:
+ break;
+ case INVALID_ARGUMENT:
+ return new InvalidArgumentException(e.getMessage(), e);
+ case INVALID_COOKIE_DOMAIN:
+ return new InvalidCookieDomainException(e.getMessage(), e);
+ case INVALID_ELEMENT_STATE:
+ return new InvalidElementStateException(e.getMessage(), e);
+ case INVALID_SELECTOR:
+ return new InvalidSelectorException(e.getMessage(), e);
+ case INVALID_SESSION_ID:
+ return new NoSuchSessionException(e.getMessage(), e);
+ case JAVASCRIPT_ERROR:
+ return new JavascriptException(e.getMessage(), e);
+ case MOVE_TARGET_OUT_OF_BOUNDS:
+ return new MoveTargetOutOfBoundsException(e.getMessage(), e);
+ case NO_SUCH_ALERT:
+ return new NoAlertPresentException(e.getMessage(), e);
+ case NO_SUCH_COOKIE:
+ return new NoSuchCookieException(e.getMessage());
+ case NO_SUCH_ELEMENT:
+ return new NoSuchElementException(e.getMessage(), e);
+ case NO_SUCH_FRAME:
+ return new NoSuchFrameException(e.getMessage(), e);
+ case NO_SUCH_WINDOW:
+ return new NoSuchWindowException(e.getMessage(), e);
+ case SCRIPT_TIMEOUT:
+ return new ScriptTimeoutException(e.getMessage(), e);
+ case SESSION_NOT_CREATED:
+ return new SessionNotCreatedException(e.getMessage(), e);
+ case STALE_ELEMENT_REFERENCE:
+ return new StaleElementReferenceException(e.getMessage(), e);
+ case TIMEOUT:
+ return new TimeoutException(e.getMessage(), e);
+ case UNABLE_TO_SET_COOKIE:
+ return new UnableToSetCookieException(e.getMessage(), e);
+ case UNEXPECTED_ALERT_OPEN:
+ return new UnhandledAlertException(e.getMessage());
+ case UNSUPPORTED_OPERATION:
+ return new UnsupportedCommandException(e.getMessage(), e);
+ }
+ return new WebDriverException(e.getMessage(), e);
+ }
+
+ static com.aerokube.lightning.WebDriver.Locator byToLocator(By by) {
+ if (by instanceof By.Remotable) {
+ By.Remotable.Parameters remoteParameters = ((By.Remotable) by).getRemoteParameters();
+ LocatorStrategy locatorStrategy = LocatorStrategy.fromValue(remoteParameters.using());
+ String expression = String.valueOf(remoteParameters.value());
+ return new com.aerokube.lightning.By(expression, locatorStrategy);
+ }
+ throw new WebDriverException(String.format("Unsupported locator type: %s", by.getClass().getCanonicalName()));
+ }
+
+ @Nonnull
+ private static com.aerokube.lightning.Cookie convertSeleniumCookie(Cookie cookie) {
+ com.aerokube.lightning.Cookie.CookieBuilder cookieBuilder = com.aerokube.lightning.Cookie.create(cookie.getName(), cookie.getValue())
+ .path(cookie.getPath())
+ .domain(cookie.getDomain())
+ .expires(cookie.getExpiry().toInstant())
+ .sameSitePolicy(com.aerokube.lightning.model.Cookie.SameSiteEnum.valueOf(cookie.getSameSite()));
+ if (cookie.isHttpOnly()) {
+ cookieBuilder = cookieBuilder.httpOnly();
+ }
+ if (cookie.isSecure()) {
+ cookieBuilder = cookieBuilder.secureOnly();
+ }
+ return cookieBuilder.build();
+ }
+
+ @Nonnull
+ private static Cookie convertLightningCookie(com.aerokube.lightning.Cookie cookie) {
+ Optional expires = cookie.getExpires();
+ Date date = null;
+ if (expires.isPresent()) {
+ date = Date.from(expires.get());
+ }
+ return new Cookie(cookie.getName(), cookie.getValue(), cookie.getDomain(), cookie.getPath(), date, cookie.isSecureOnly(), cookie.isHttpOnly(), cookie.getSameSitePolicy().getValue());
+ }
+
+ @Override
+ public void get(String url) {
+ execute(() -> webDriver.navigation().navigate(url));
+ }
+
+ @Override
+ public String getCurrentUrl() {
+ return execute(() -> webDriver.navigation().getUrl());
+ }
+
+ @Override
+ public String getTitle() {
+ return execute(() -> webDriver.navigation().getTitle());
+ }
+
+ @Override
+ public List findElements(By by) {
+ return execute(() -> webDriver.elements().findAll(byToLocator(by))
+ .stream().map(SeleniumWebElement::new)
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public WebElement findElement(By by) {
+ com.aerokube.lightning.WebElement webElement = execute(() -> webDriver.elements().findFirst(byToLocator(by)));
+ return new SeleniumWebElement(webElement);
+ }
+
+ @Override
+ public String getPageSource() {
+ return execute(() -> webDriver.document().getPageSource());
+ }
+
+ @Override
+ public void close() {
+ execute(() -> webDriver.windows().current().close());
+ }
+
+ @Override
+ public void quit() {
+ execute(() -> {
+ webDriver.session().delete();
+ return null;
+ });
+ }
+
+ @Override
+ public Set getWindowHandles() {
+ return execute(() -> webDriver.windows().list()
+ .stream().map(com.aerokube.lightning.Window::getHandle)
+ .collect(Collectors.toSet()));
+ }
+
+ @Override
+ public String getWindowHandle() {
+ return execute(() -> webDriver.windows().current().getHandle());
+ }
+
+ @Override
+ public TargetLocator switchTo() {
+ return this;
+ }
+
+ @Override
+ public Navigation navigate() {
+ return this;
+ }
+
+ @Override
+ public Options manage() {
+ return this;
+ }
+
+ @Override
+ public void back() {
+ execute(() -> webDriver.navigation().back());
+ }
+
+ @Override
+ public void forward() {
+ execute(() -> webDriver.navigation().forward());
+ }
+
+ @Override
+ public void to(String url) {
+ execute(() -> webDriver.navigation().navigate(url));
+ }
+
+ @Override
+ public void to(URL url) {
+ execute(() -> webDriver.navigation().navigate(url.toString()));
+ }
+
+ @Override
+ public void refresh() {
+ execute(() -> webDriver.navigation().refresh());
+ }
+
+ @Override
+ public WebDriver frame(int index) {
+ execute(() -> {
+ webDriver.frames().switchTo(index);
+ return null;
+ });
+ return this;
+ }
+
+ @Override
+ public WebDriver frame(String nameOrId) {
+ com.aerokube.lightning.WebDriver.Locator byNameLocator = cssSelector(String.format("frame[name='%s'],iframe[name='%s']", nameOrId, nameOrId));
+ List byName = execute(() -> webDriver.elements().findAll(byNameLocator));
+ if (byName.size() > 0) {
+ frame(new SeleniumWebElement(byName.get(0)));
+ return this;
+ }
+
+ com.aerokube.lightning.WebDriver.Locator byIdLocator = cssSelector(String.format("frame#%s,iframe#%s", nameOrId, nameOrId));
+ List byId = execute(() -> webDriver.elements().findAll(byIdLocator));
+ if (byId.size() > 0) {
+ frame(new SeleniumWebElement(byId.get(0)));
+ return this;
+ }
+
+ throw new NoSuchFrameException("No frame element found by name or id " + nameOrId);
+ }
+
+ @Override
+ public WebDriver frame(WebElement frameElement) {
+ if (frameElement instanceof SeleniumWebElement) {
+ execute(() -> {
+ webDriver.frames().switchTo(((SeleniumWebElement) frameElement).raw());
+ return null;
+ });
+ return this;
+ }
+ throw new IllegalArgumentException("This operation is not supported on third-party WebElement instances");
+ }
+
+ @Override
+ public WebDriver parentFrame() {
+ execute(() -> {
+ webDriver.frames().switchToParent();
+ return null;
+ });
+ return this;
+ }
+
+ @Override
+ public WebDriver window(String nameOrHandle) {
+ List windows = execute(() -> webDriver.windows().list());
+ windows.stream().filter(
+ w -> getWindowHandles().contains(nameOrHandle)
+ )
+ .findFirst()
+ .orElseThrow(() -> new NoSuchWindowException(String.format("Window %s not found", nameOrHandle)))
+ .switchTo();
+ return this;
+ }
+
+ @Override
+ public WebDriver newWindow(WindowType typeHint) {
+ switch (typeHint) {
+ case WINDOW:
+ execute(() -> webDriver.windows().createWindow());
+ break;
+ case TAB:
+ execute(() -> webDriver.windows().createTab());
+ break;
+ }
+ return this;
+ }
+
+ @Override
+ public WebDriver defaultContent() {
+ execute(() -> {
+ webDriver.frames().switchToDefault();
+ return null;
+ });
+ return this;
+ }
+
+ @Override
+ public WebElement activeElement() {
+ com.aerokube.lightning.WebElement webElement = execute(() -> webDriver.elements().current());
+ return new SeleniumWebElement(webElement);
+ }
+
+ @Override
+ public Alert alert() {
+ return this;
+ }
+
+ @Override
+ public void dismiss() {
+ execute(() -> webDriver.prompts().dismiss());
+ }
+
+ @Override
+ public void accept() {
+ execute(() -> webDriver.prompts().accept());
+ }
+
+ @Override
+ public String getText() {
+ return execute(() -> webDriver.prompts().getText());
+ }
+
+ @Override
+ public void sendKeys(String keysToSend) {
+ execute(() -> webDriver.prompts().sendText(keysToSend));
+ }
+
+ @Override
+ public Object executeScript(String script, Object... args) {
+ return execute(() -> webDriver.document().executeScript(script, args));
+ }
+
+ @Override
+ public Object executeAsyncScript(String script, Object... args) {
+ return execute(() -> webDriver.document().executeAsyncScript(script, args));
+ }
+
+ @Override
+ public X getScreenshotAs(OutputType target) throws WebDriverException {
+ return target.convertFromPngBytes(execute(() -> webDriver.screenshot().take()));
+ }
+
+ @Override
+ public void addCookie(Cookie cookie) {
+ execute(() -> webDriver.cookies().add(convertSeleniumCookie(cookie)));
+ }
+
+ @Override
+ public void deleteCookieNamed(String name) {
+ execute(() -> webDriver.cookies().delete(name));
+ }
+
+ @Override
+ public void deleteCookie(Cookie cookie) {
+ execute(() -> webDriver.cookies().delete(cookie.getName()));
+ }
+
+ @Override
+ public void deleteAllCookies() {
+ execute(() -> webDriver.cookies().deleteAll());
+ }
+
+ @Override
+ public Set getCookies() {
+ return execute(() -> webDriver.cookies().getAll())
+ .stream().map(SeleniumWebDriver::convertLightningCookie)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Cookie getCookieNamed(String name) {
+ com.aerokube.lightning.Cookie cookie = execute(() -> webDriver.cookies().get(name));
+ return convertLightningCookie(cookie);
+ }
+
+ @Override
+ public Timeouts timeouts() {
+ return this;
+ }
+
+ @Override
+ public ImeHandler ime() {
+ throw new UnsupportedOperationException("IME is not supported");
+ }
+
+ @Override
+ public Window window() {
+ return this;
+ }
+
+ @Override
+ public Logs logs() {
+ //TODO: need to implement this in Lightning first
+ throw new UnsupportedOperationException("Logs is not yet supported");
+ }
+
+ @Override
+ public Duration getImplicitWaitTimeout() {
+ return execute(() -> webDriver.timeouts().getImplicitWaitTimeout());
+ }
+
+ @Override
+ public Duration getScriptTimeout() {
+ Optional scriptTimeout = execute(() -> webDriver.timeouts().getScriptTimeout());
+ if (scriptTimeout.isEmpty()) {
+ throw new WebDriverException("Script timeout is empty");
+ }
+ return scriptTimeout.get();
+ }
+
+ @Override
+ public Duration getPageLoadTimeout() {
+ return execute(() -> webDriver.timeouts().getPageLoadTimeout());
+ }
+
+ @Override
+ public Timeouts implicitlyWait(long time, TimeUnit unit) {
+ execute(() -> webDriver.timeouts().setImplicitWaitTimeout(Duration.of(time, unit.toChronoUnit())));
+ return this;
+ }
+
+ @Override
+ public Timeouts setScriptTimeout(long time, TimeUnit unit) {
+ execute(() -> webDriver.timeouts().setScriptTimeout(Duration.of(time, unit.toChronoUnit())));
+ return this;
+ }
+
+ @Override
+ public Timeouts pageLoadTimeout(long time, TimeUnit unit) {
+ execute(() -> webDriver.timeouts().setPageLoadTimeout(Duration.of(time, unit.toChronoUnit())));
+ return this;
+ }
+
+ @Override
+ public Dimension getSize() {
+ Size size = execute(() -> webDriver.windows().current().getSize());
+ return new Dimension(size.getWidth(), size.getHeight());
+ }
+
+ @Override
+ public void setSize(Dimension targetSize) {
+ execute(() -> webDriver.windows().current().setSize(targetSize.getWidth(), targetSize.getHeight()));
+ }
+
+ @Override
+ public Point getPosition() {
+ Position position = execute(() -> webDriver.windows().current().getPosition());
+ return new Point(position.getX(), position.getY());
+ }
+
+ @Override
+ public void setPosition(Point targetPosition) {
+ execute(() -> webDriver.windows().current().setPosition(targetPosition.getX(), targetPosition.getY()));
+ }
+
+ @Override
+ public void maximize() {
+ execute(() -> webDriver.windows().current().maximize());
+ }
+
+ @Override
+ public void minimize() {
+ execute(() -> webDriver.windows().current().minimize());
+ }
+
+ @Override
+ public void fullscreen() {
+ execute(() -> webDriver.windows().current().fullscreen());
+ }
+
+ @Override
+ public Capabilities getCapabilities() {
+ return new ImmutableCapabilities(webDriver.getCapabilities().raw());
+ }
+}
diff --git a/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebElement.java b/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebElement.java
new file mode 100644
index 0000000..243a519
--- /dev/null
+++ b/lightning-adapter/src/main/java/com/aerokube/lightning/adapter/SeleniumWebElement.java
@@ -0,0 +1,117 @@
+package com.aerokube.lightning.adapter;
+
+import com.aerokube.lightning.Position;
+import com.aerokube.lightning.Size;
+import org.openqa.selenium.*;
+
+import javax.annotation.Nonnull;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.aerokube.lightning.adapter.SeleniumWebDriver.byToLocator;
+import static com.aerokube.lightning.adapter.SeleniumWebDriver.execute;
+
+public class SeleniumWebElement implements WebElement {
+
+ private final com.aerokube.lightning.WebElement webElement;
+
+ public SeleniumWebElement(com.aerokube.lightning.WebElement webElement) {
+ this.webElement = webElement;
+ }
+
+ @Nonnull
+ com.aerokube.lightning.WebElement raw() {
+ return webElement;
+ }
+
+ @Override
+ public void click() {
+ execute(webElement::click);
+ }
+
+ @Override
+ public void submit() {
+ throw new UnsupportedOperationException("This command is not supported in W3C Webdriver standard");
+ }
+
+ @Override
+ public void sendKeys(CharSequence... keysToSend) {
+ execute(() -> webElement.sendKeys(Arrays.toString(keysToSend)));
+ }
+
+ @Override
+ public void clear() {
+ execute(webElement::clear);
+ }
+
+ @Override
+ public String getTagName() {
+ return execute(webElement::getTagName);
+ }
+
+ @Override
+ public String getAttribute(String name) {
+ return execute(() -> webElement.getAttribute(name).orElse(null));
+ }
+
+ @Override
+ public boolean isSelected() {
+ return execute(webElement::isSelected);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return execute(webElement::isEnabled);
+ }
+
+ @Override
+ public String getText() {
+ return execute(webElement::getText);
+ }
+
+ @Override
+ public List findElements(By by) {
+ return execute(() -> webElement.findAll(byToLocator(by)))
+ .stream().map(SeleniumWebElement::new)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public WebElement findElement(By by) {
+ com.aerokube.lightning.WebElement found = execute(() -> webElement.findFirst(byToLocator(by)));
+ return new SeleniumWebElement(found);
+ }
+
+ @Override
+ public boolean isDisplayed() {
+ return execute(webElement::isDisplayed);
+ }
+
+ @Override
+ public Point getLocation() {
+ Position position = execute(webElement::getPosition);
+ return new Point(position.getX(), position.getY());
+ }
+
+ @Override
+ public Dimension getSize() {
+ Size size = execute(webElement::getSize);
+ return new Dimension(size.getWidth(), size.getHeight());
+ }
+
+ @Override
+ public Rectangle getRect() {
+ return new Rectangle(getLocation(), getSize());
+ }
+
+ @Override
+ public String getCssValue(String propertyName) {
+ return execute(() -> webElement.getCssProperty(propertyName));
+ }
+
+ @Override
+ public X getScreenshotAs(OutputType target) throws WebDriverException {
+ return target.convertFromPngBytes(execute(webElement::takeScreenshot));
+ }
+}
diff --git a/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/BaseTest.java b/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/BaseTest.java
new file mode 100644
index 0000000..c0bc87b
--- /dev/null
+++ b/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/BaseTest.java
@@ -0,0 +1,55 @@
+package com.aerokube.lightning.adapter;
+
+import com.aerokube.lightning.Capabilities;
+import org.openqa.selenium.WebDriver;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import static com.aerokube.lightning.WebDriver.create;
+
+@Testcontainers
+public class BaseTest {
+
+ @Container
+ protected final GenericContainer> browserContainer = getBrowserContainer();
+
+ protected WebDriver driver;
+
+ private static final String IMAGE = "browsers/chrome:101.0";
+
+ protected GenericContainer> getBrowserContainer() {
+ return new GenericContainer<>(DockerImageName.parse(IMAGE))
+ .withPrivilegedMode(true)
+ .withExposedPorts(4444)
+ .withSharedMemorySize(268435456L)
+ .waitingFor(new HttpWaitStrategy().forPort(4444).forPath("/status"));
+ }
+
+ protected String getUri(int port) {
+ return String.format("http://localhost:%s/", port);
+ }
+
+ protected void test(Supplier caps, Consumer steps) {
+ WebDriver driver = null;
+ try {
+ Integer port = browserContainer.getMappedPort(4444);
+ driver = new SeleniumWebDriver(create(getUri(port), caps.get()));
+ steps.accept(driver);
+ } finally {
+ if (driver != null) {
+ driver.quit();
+ }
+ }
+ }
+
+ protected void test(Consumer steps) {
+ test(() -> Capabilities.create().browserName("chrome"), steps);
+ }
+
+}
diff --git a/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/ScreenshotTest.java b/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/ScreenshotTest.java
new file mode 100644
index 0000000..e01966f
--- /dev/null
+++ b/lightning-adapter/src/test/java/com/aerokube/lightning/adapter/ScreenshotTest.java
@@ -0,0 +1,35 @@
+package com.aerokube.lightning.adapter;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.junit.jupiter.api.Test;
+import org.openqa.selenium.OutputType;
+import org.openqa.selenium.TakesScreenshot;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
+
+public class ScreenshotTest extends BaseTest {
+
+ @Test
+ void testPageScreenshot() {
+ test(driver -> {
+ driver.get("https://example.com");
+ assertThat(driver, instanceOf(TakesScreenshot.class));
+ byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
+ assertThat(screenshot.length, greaterThan(0));
+ });
+ }
+
+ @Test
+ void testElementScreenshot() {
+ test(driver -> {
+ driver.get("https://example.com");
+ WebElement body = driver.findElement(By.tagName("body"));
+ byte[] screenshot = body.getScreenshotAs(OutputType.BYTES);
+ assertThat(screenshot.length, greaterThan(0));
+ });
+ }
+
+}
diff --git a/src/test/resources/log4j.properties b/lightning-adapter/src/test/resources/log4j.properties
similarity index 100%
rename from src/test/resources/log4j.properties
rename to lightning-adapter/src/test/resources/log4j.properties
diff --git a/lightning/pom.xml b/lightning/pom.xml
new file mode 100644
index 0000000..08cd27f
--- /dev/null
+++ b/lightning/pom.xml
@@ -0,0 +1,125 @@
+
+
+ 4.0.0
+
+
+ com.aerokube.lightning
+ lightning-parent
+ 1.2.2-SNAPSHOT
+
+
+ lightning
+
+ Lightning
+ Lightweight and lightning fast WebDriver client library
+
+
+ 1.6.6
+ 1.1.2
+ 5.1.0
+ 2.13.3
+ 2.13.3
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson-databind.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson-datatype.version}
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.2
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+ 2.1.1
+
+
+ io.swagger
+ swagger-annotations
+ ${swagger.version}
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.hamcrest
+ hamcrest
+ test
+
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ net.lightbody.bmp
+ browsermob-core
+ 2.1.5
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ test
+
+
+
+
+
+
+
+
+
+
+ org.openapitools
+ openapi-generator-maven-plugin
+ ${openapi-plugin.version}
+
+
+
+ generate
+
+
+ com.aerokube.lightning.model
+ com.aerokube.lightning.api
+ https://github.com/aerokube/selenium-openapi/releases/download/${openapi-spec.version}/selenium.yaml
+ java
+ false
+ false
+ true
+ true
+ native
+
+ java8
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/aerokube/lightning/By.java b/lightning/src/main/java/com/aerokube/lightning/By.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/By.java
rename to lightning/src/main/java/com/aerokube/lightning/By.java
diff --git a/src/main/java/com/aerokube/lightning/Capabilities.java b/lightning/src/main/java/com/aerokube/lightning/Capabilities.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/Capabilities.java
rename to lightning/src/main/java/com/aerokube/lightning/Capabilities.java
diff --git a/src/main/java/com/aerokube/lightning/Cookie.java b/lightning/src/main/java/com/aerokube/lightning/Cookie.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/Cookie.java
rename to lightning/src/main/java/com/aerokube/lightning/Cookie.java
diff --git a/src/main/java/com/aerokube/lightning/ExtensionCapabilities.java b/lightning/src/main/java/com/aerokube/lightning/ExtensionCapabilities.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/ExtensionCapabilities.java
rename to lightning/src/main/java/com/aerokube/lightning/ExtensionCapabilities.java
diff --git a/src/main/java/com/aerokube/lightning/FileUtils.java b/lightning/src/main/java/com/aerokube/lightning/FileUtils.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/FileUtils.java
rename to lightning/src/main/java/com/aerokube/lightning/FileUtils.java
diff --git a/src/main/java/com/aerokube/lightning/Position.java b/lightning/src/main/java/com/aerokube/lightning/Position.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/Position.java
rename to lightning/src/main/java/com/aerokube/lightning/Position.java
diff --git a/src/main/java/com/aerokube/lightning/Size.java b/lightning/src/main/java/com/aerokube/lightning/Size.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/Size.java
rename to lightning/src/main/java/com/aerokube/lightning/Size.java
diff --git a/src/main/java/com/aerokube/lightning/StdCapabilities.java b/lightning/src/main/java/com/aerokube/lightning/StdCapabilities.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/StdCapabilities.java
rename to lightning/src/main/java/com/aerokube/lightning/StdCapabilities.java
diff --git a/src/main/java/com/aerokube/lightning/StdCookie.java b/lightning/src/main/java/com/aerokube/lightning/StdCookie.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/StdCookie.java
rename to lightning/src/main/java/com/aerokube/lightning/StdCookie.java
diff --git a/src/main/java/com/aerokube/lightning/StdWebDriver.java b/lightning/src/main/java/com/aerokube/lightning/StdWebDriver.java
similarity index 99%
rename from src/main/java/com/aerokube/lightning/StdWebDriver.java
rename to lightning/src/main/java/com/aerokube/lightning/StdWebDriver.java
index c70119e..29a254f 100644
--- a/src/main/java/com/aerokube/lightning/StdWebDriver.java
+++ b/lightning/src/main/java/com/aerokube/lightning/StdWebDriver.java
@@ -744,6 +744,12 @@ public Window switchTo() {
execute(() -> contextsApi.switchToWindow(sessionId, switchToWindowRequest));
return this;
}
+
+ @Nonnull
+ @Override
+ public String getHandle() {
+ return handle;
+ }
}
}
@@ -933,6 +939,12 @@ public WebElement sendKeys(@Nonnull String text) {
return this;
}
+ @Nonnull
+ @Override
+ public byte[] takeScreenshot() {
+ return screenshot.take(this);
+ }
+
@Nonnull
@Override
public Accessibility accessibility() {
diff --git a/src/main/java/com/aerokube/lightning/WebDriver.java b/lightning/src/main/java/com/aerokube/lightning/WebDriver.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/WebDriver.java
rename to lightning/src/main/java/com/aerokube/lightning/WebDriver.java
diff --git a/src/main/java/com/aerokube/lightning/WebDriverException.java b/lightning/src/main/java/com/aerokube/lightning/WebDriverException.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/WebDriverException.java
rename to lightning/src/main/java/com/aerokube/lightning/WebDriverException.java
diff --git a/src/main/java/com/aerokube/lightning/WebDriverExtension.java b/lightning/src/main/java/com/aerokube/lightning/WebDriverExtension.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/WebDriverExtension.java
rename to lightning/src/main/java/com/aerokube/lightning/WebDriverExtension.java
diff --git a/src/main/java/com/aerokube/lightning/WebElement.java b/lightning/src/main/java/com/aerokube/lightning/WebElement.java
similarity index 96%
rename from src/main/java/com/aerokube/lightning/WebElement.java
rename to lightning/src/main/java/com/aerokube/lightning/WebElement.java
index 8ad008b..4ae9ce3 100644
--- a/src/main/java/com/aerokube/lightning/WebElement.java
+++ b/lightning/src/main/java/com/aerokube/lightning/WebElement.java
@@ -51,6 +51,9 @@ public interface WebElement {
@Nonnull
WebElement sendKeys(@Nonnull String text);
+ @Nonnull
+ byte[] takeScreenshot();
+
@Nonnull
Accessibility accessibility();
diff --git a/src/main/java/com/aerokube/lightning/Window.java b/lightning/src/main/java/com/aerokube/lightning/Window.java
similarity index 92%
rename from src/main/java/com/aerokube/lightning/Window.java
rename to lightning/src/main/java/com/aerokube/lightning/Window.java
index 4605690..5e4c125 100644
--- a/src/main/java/com/aerokube/lightning/Window.java
+++ b/lightning/src/main/java/com/aerokube/lightning/Window.java
@@ -31,4 +31,6 @@ public interface Window {
@Nonnull
Window switchTo();
+ @Nonnull
+ String getHandle();
}
diff --git a/src/main/java/com/aerokube/lightning/extensions/FirefoxCommands.java b/lightning/src/main/java/com/aerokube/lightning/extensions/FirefoxCommands.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/extensions/FirefoxCommands.java
rename to lightning/src/main/java/com/aerokube/lightning/extensions/FirefoxCommands.java
diff --git a/src/main/java/com/aerokube/lightning/extensions/MobileDevice.java b/lightning/src/main/java/com/aerokube/lightning/extensions/MobileDevice.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/extensions/MobileDevice.java
rename to lightning/src/main/java/com/aerokube/lightning/extensions/MobileDevice.java
diff --git a/src/main/java/com/aerokube/lightning/extensions/MoonCapabilities.java b/lightning/src/main/java/com/aerokube/lightning/extensions/MoonCapabilities.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/extensions/MoonCapabilities.java
rename to lightning/src/main/java/com/aerokube/lightning/extensions/MoonCapabilities.java
diff --git a/src/main/java/com/aerokube/lightning/extensions/MoonCommands.java b/lightning/src/main/java/com/aerokube/lightning/extensions/MoonCommands.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/extensions/MoonCommands.java
rename to lightning/src/main/java/com/aerokube/lightning/extensions/MoonCommands.java
diff --git a/src/main/java/com/aerokube/lightning/extensions/SelenoidCapabilities.java b/lightning/src/main/java/com/aerokube/lightning/extensions/SelenoidCapabilities.java
similarity index 100%
rename from src/main/java/com/aerokube/lightning/extensions/SelenoidCapabilities.java
rename to lightning/src/main/java/com/aerokube/lightning/extensions/SelenoidCapabilities.java
diff --git a/src/test/java/com/aerokube/lightning/BaseTest.java b/lightning/src/test/java/com/aerokube/lightning/BaseTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/BaseTest.java
rename to lightning/src/test/java/com/aerokube/lightning/BaseTest.java
diff --git a/src/test/java/com/aerokube/lightning/ChromeCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/ChromeCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/ChromeCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/ChromeCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/CookiesTest.java b/lightning/src/test/java/com/aerokube/lightning/CookiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/CookiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/CookiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/DocumentTest.java b/lightning/src/test/java/com/aerokube/lightning/DocumentTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/DocumentTest.java
rename to lightning/src/test/java/com/aerokube/lightning/DocumentTest.java
diff --git a/src/test/java/com/aerokube/lightning/EdgeCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/EdgeCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/EdgeCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/EdgeCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/ElementsTest.java b/lightning/src/test/java/com/aerokube/lightning/ElementsTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/ElementsTest.java
rename to lightning/src/test/java/com/aerokube/lightning/ElementsTest.java
diff --git a/src/test/java/com/aerokube/lightning/FirefoxCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/FirefoxCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/FirefoxCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/FirefoxCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/FramesTest.java b/lightning/src/test/java/com/aerokube/lightning/FramesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/FramesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/FramesTest.java
diff --git a/src/test/java/com/aerokube/lightning/Image.java b/lightning/src/test/java/com/aerokube/lightning/Image.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/Image.java
rename to lightning/src/test/java/com/aerokube/lightning/Image.java
diff --git a/src/test/java/com/aerokube/lightning/NavigationTest.java b/lightning/src/test/java/com/aerokube/lightning/NavigationTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/NavigationTest.java
rename to lightning/src/test/java/com/aerokube/lightning/NavigationTest.java
diff --git a/src/test/java/com/aerokube/lightning/OperaCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/OperaCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/OperaCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/OperaCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/PrintTest.java b/lightning/src/test/java/com/aerokube/lightning/PrintTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/PrintTest.java
rename to lightning/src/test/java/com/aerokube/lightning/PrintTest.java
diff --git a/src/test/java/com/aerokube/lightning/PromptsTest.java b/lightning/src/test/java/com/aerokube/lightning/PromptsTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/PromptsTest.java
rename to lightning/src/test/java/com/aerokube/lightning/PromptsTest.java
diff --git a/src/test/java/com/aerokube/lightning/SafariCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/SafariCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/SafariCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/SafariCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/ScreenshotTest.java b/lightning/src/test/java/com/aerokube/lightning/ScreenshotTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/ScreenshotTest.java
rename to lightning/src/test/java/com/aerokube/lightning/ScreenshotTest.java
diff --git a/src/test/java/com/aerokube/lightning/SelenoidCapabilitiesTest.java b/lightning/src/test/java/com/aerokube/lightning/SelenoidCapabilitiesTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/SelenoidCapabilitiesTest.java
rename to lightning/src/test/java/com/aerokube/lightning/SelenoidCapabilitiesTest.java
diff --git a/src/test/java/com/aerokube/lightning/SessionTest.java b/lightning/src/test/java/com/aerokube/lightning/SessionTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/SessionTest.java
rename to lightning/src/test/java/com/aerokube/lightning/SessionTest.java
diff --git a/src/test/java/com/aerokube/lightning/TimeoutsTest.java b/lightning/src/test/java/com/aerokube/lightning/TimeoutsTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/TimeoutsTest.java
rename to lightning/src/test/java/com/aerokube/lightning/TimeoutsTest.java
diff --git a/src/test/java/com/aerokube/lightning/WindowsTest.java b/lightning/src/test/java/com/aerokube/lightning/WindowsTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/WindowsTest.java
rename to lightning/src/test/java/com/aerokube/lightning/WindowsTest.java
diff --git a/src/test/java/com/aerokube/lightning/extensions/FirefoxCommandsTest.java b/lightning/src/test/java/com/aerokube/lightning/extensions/FirefoxCommandsTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/extensions/FirefoxCommandsTest.java
rename to lightning/src/test/java/com/aerokube/lightning/extensions/FirefoxCommandsTest.java
diff --git a/src/test/java/com/aerokube/lightning/extensions/SelenoidTest.java b/lightning/src/test/java/com/aerokube/lightning/extensions/SelenoidTest.java
similarity index 100%
rename from src/test/java/com/aerokube/lightning/extensions/SelenoidTest.java
rename to lightning/src/test/java/com/aerokube/lightning/extensions/SelenoidTest.java
diff --git a/src/test/resources/crx/content-script.js b/lightning/src/test/resources/crx/content-script.js
similarity index 100%
rename from src/test/resources/crx/content-script.js
rename to lightning/src/test/resources/crx/content-script.js
diff --git a/src/test/resources/crx/manifest.json b/lightning/src/test/resources/crx/manifest.json
similarity index 100%
rename from src/test/resources/crx/manifest.json
rename to lightning/src/test/resources/crx/manifest.json
diff --git a/lightning/src/test/resources/log4j.properties b/lightning/src/test/resources/log4j.properties
new file mode 100644
index 0000000..daa066a
--- /dev/null
+++ b/lightning/src/test/resources/log4j.properties
@@ -0,0 +1,10 @@
+# suppress inspection "UnusedProperty" for whole file
+log4j.rootLogger=INFO, out
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d %-5p %c{1} - %m%n
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
+
+log4j.logger.org.testcontainers = ERROR
\ No newline at end of file
diff --git a/src/test/resources/self-signed-root-ca.crt b/lightning/src/test/resources/self-signed-root-ca.crt
similarity index 100%
rename from src/test/resources/self-signed-root-ca.crt
rename to lightning/src/test/resources/self-signed-root-ca.crt
diff --git a/src/test/resources/test.crx b/lightning/src/test/resources/test.crx
similarity index 100%
rename from src/test/resources/test.crx
rename to lightning/src/test/resources/test.crx
diff --git a/src/test/resources/test.xpi b/lightning/src/test/resources/test.xpi
similarity index 100%
rename from src/test/resources/test.xpi
rename to lightning/src/test/resources/test.xpi
diff --git a/src/test/resources/xpi/content-script.js b/lightning/src/test/resources/xpi/content-script.js
similarity index 100%
rename from src/test/resources/xpi/content-script.js
rename to lightning/src/test/resources/xpi/content-script.js
diff --git a/src/test/resources/xpi/manifest.json b/lightning/src/test/resources/xpi/manifest.json
similarity index 100%
rename from src/test/resources/xpi/manifest.json
rename to lightning/src/test/resources/xpi/manifest.json
diff --git a/pom.xml b/pom.xml
index 816c742..c99dd6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,135 +5,76 @@
4.0.0
com.aerokube.lightning
- lightning
+ lightning-parent
1.2.2-SNAPSHOT
+ pom
- Lightning
- Lightweight and lightning fast WebDriver client library
+ Lightning Parent
+ Lightweight and lightning fast WebDriver client library for Java and related components
https://github.com/aerokube/lightning-java
11
11
UTF-8
- 1.6.6
- 1.1.2
- 5.1.0
- 2.13.3
- 2.13.3
- 5.8.2
- 2.2
- 1.17.1
- 1.7.36
2.22.2
3.2.1
3.3.1
3.0.1
1.6.8
+ 5.8.2
+ 2.2
+ 1.17.1
+ 1.7.36
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson-databind.version}
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
- ${jackson-datatype.version}
-
-
- org.openapitools
- jackson-databind-nullable
- 0.2.2
-
-
- javax.ws.rs
- javax.ws.rs-api
- 2.1.1
-
-
- io.swagger
- swagger-annotations
- ${swagger.version}
-
-
- com.google.code.findbugs
- jsr305
- 3.0.2
-
-
- javax.annotation
- javax.annotation-api
- 1.3.2
-
-
- org.junit.jupiter
- junit-jupiter-engine
- ${junit-jupiter.version}
- test
-
-
- org.hamcrest
- hamcrest
- ${hamcrest.version}
- test
-
-
- org.testcontainers
- testcontainers
- ${testcontainers.version}
- test
-
-
- org.testcontainers
- junit-jupiter
- ${testcontainers.version}
- test
-
-
- net.lightbody.bmp
- browsermob-core
- 2.1.5
- test
-
-
- org.slf4j
- slf4j-log4j12
- ${slf4j-log4j12.version}
- test
-
-
+
+ lightning
+ lightning-adapter
+
+
+
+
+
+ com.aerokube.lightning
+ lightning
+ ${project.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
+
+ org.hamcrest
+ hamcrest
+ ${hamcrest.version}
+ test
+
+
+ org.testcontainers
+ testcontainers
+ ${testcontainers.version}
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-log4j12.version}
+ test
+
+
+
-
- org.openapitools
- openapi-generator-maven-plugin
- ${openapi-plugin.version}
-
-
-
- generate
-
-
- com.aerokube.lightning.model
- com.aerokube.lightning.api
- https://github.com/aerokube/selenium-openapi/releases/download/${openapi-spec.version}/selenium.yaml
- java
- false
- false
- true
- true
- native
-
- java8
-
-
-
-
-
org.apache.maven.plugins
maven-surefire-plugin