diff --git a/README.md b/README.md
index b600bbc..d03c0ee 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
# Why you should use this project?
Page Objects are a good way to produce a maintainable and reusable codebase to implement automated ui tests with selenium.
-Nevertheless those page objects can contain a lot of (selenium related) boilerplate code that is mostly reused via copy and paste.
+Nevertheless those page objects can contain a lot of (selenium related) boilerplate code that is mostly reused via copy and paste. (like for example having fluent waits or Actions)
This project provides processors to generate page object implementations by processing annotations placed on interfaces.
By doing that it drastically increases readability of page objects and reduces time for development.
@@ -22,7 +22,7 @@ By doing that it drastically increases readability of page objects and reduces t
# Restrictions
-The project is still in development, so it currently just supports a few Actions like clicking or writing to input fields. Other Actions will be added in the near future or can be easily integrated via an SPI.
+The project is still in development, so it currently just supports a few Actions like clicking or writing to input fields. Nevertheless it's quite simple to define custom Action annotations and their implementations.
Please create an issue, if you need specific action to be implemented. Usually it will be included shortly after ;)
diff --git a/pogen4selenium-api/pom.xml b/pogen4selenium-api/pom.xml
index f397c8d..159252f 100644
--- a/pogen4selenium-api/pom.xml
+++ b/pogen4selenium-api/pom.xml
@@ -9,7 +9,7 @@
io.toolisticon.pogen4selenium
pogen4selenium
- 0.6.1
+ 0.7.0
pogen4selenium-api
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/Action.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/Action.java
index dfae2f1..b05445f 100644
--- a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/Action.java
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/Action.java
@@ -7,6 +7,10 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
+import io.toolisticon.pogen4selenium.runtime.DefaultSideCondition;
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+import io.toolisticon.pogen4selenium.runtime.actions.BaseAction;
+
/**
* Meta-Annotation to allow custom annotations.
*
@@ -16,5 +20,12 @@
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Action {
+
+ /**
+ * The implementation class.
+ * @return
+ */
+ Class extends ActionImpl> value();
+
}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionClick.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionClick.java
index c7d9be3..e34bdab 100644
--- a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionClick.java
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionClick.java
@@ -5,9 +5,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import io.toolisticon.pogen4selenium.runtime.DefaultSideCondition;
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+import io.toolisticon.pogen4selenium.runtime.actions.ActionClickImpl;
+
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
-@Action
+@Action(ActionClickImpl.class)
public @interface ActionClick {
/**
@@ -19,4 +23,10 @@
/** The locator string to use. */
String value();
+ /**
+ * The locator strategy to use, will just be taken into account if by attribute is not set to ELEMENT.
+ * @return the Locator strategy, defaults to DefaultLocatorStrategy
+ */
+ @ActionSideCondition
+ Class extends LocatorCondition> actionSideCondition() default DefaultSideCondition.class;
}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionImpl.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionImpl.java
new file mode 100644
index 0000000..00160ca
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionImpl.java
@@ -0,0 +1,24 @@
+package io.toolisticon.pogen4selenium.api;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+/**
+ * The base interface for all actions.
+ */
+public interface ActionImpl {
+
+ /**
+ * Execute action on passed webElement
+ * @param webElement
+ */
+ public void executeAction(WebElement webElement);
+
+ /**
+ * Execute action on element located by locator
+ * @param locator
+ */
+ public void executeAction(By locator);
+
+
+}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionMoveToAndClick.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionMoveToAndClick.java
index 7b3b274..dba7688 100644
--- a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionMoveToAndClick.java
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionMoveToAndClick.java
@@ -5,9 +5,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import io.toolisticon.pogen4selenium.runtime.DefaultSideCondition;
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+import io.toolisticon.pogen4selenium.runtime.actions.ActionMoveToAndClickImpl;
+
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
-@Action
+@Action(ActionMoveToAndClickImpl.class)
public @interface ActionMoveToAndClick {
/**
@@ -19,4 +23,10 @@
/** The locator string to use. */
String value();
+ /**
+ * The locator strategy to use, will just be taken into account if by attribute is not set to ELEMENT.
+ * @return the Locator strategy, defaults to DefaultLocatorStrategy
+ */
+ @ActionSideCondition
+ Class extends LocatorCondition> actionSideCondition() default DefaultSideCondition.class;
}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionSideCondition.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionSideCondition.java
new file mode 100644
index 0000000..d5fcacc
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionSideCondition.java
@@ -0,0 +1,12 @@
+package io.toolisticon.pogen4selenium.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ActionSideCondition {
+
+}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionWrite.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionWrite.java
index 88bce1b..e740b28 100644
--- a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionWrite.java
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/api/ActionWrite.java
@@ -5,9 +5,13 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import io.toolisticon.pogen4selenium.runtime.DefaultSideCondition;
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+import io.toolisticon.pogen4selenium.runtime.actions.ActionWriteImpl;
+
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
-@Action
+@Action(ActionWriteImpl.class)
public @interface ActionWrite {
/**
@@ -19,4 +23,11 @@
/** The locator string to use. */
String value();
+ /**
+ * The locator strategy to use, will just be taken into account if by attribute is not set to ELEMENT.
+ * @return the Locator strategy, defaults to DefaultLocatorStrategy
+ */
+ @ActionSideCondition
+ Class extends LocatorCondition> actionSideCondition() default DefaultSideCondition.class;
+
}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/DefaultSideCondition.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/DefaultSideCondition.java
new file mode 100644
index 0000000..a47868e
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/DefaultSideCondition.java
@@ -0,0 +1,22 @@
+package io.toolisticon.pogen4selenium.runtime;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+public class DefaultSideCondition implements LocatorCondition {
+
+ @Override
+ public boolean checkCondition(WebDriver driver, WebElement element) {
+ return true;
+ }
+
+ @Override
+ public Collection> exceptionsToIgnore() {
+ return Arrays.asList(NoSuchElementException.class);
+ }
+
+}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/LocatorCondition.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/LocatorCondition.java
new file mode 100644
index 0000000..246425f
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/LocatorCondition.java
@@ -0,0 +1,14 @@
+package io.toolisticon.pogen4selenium.runtime;
+
+import java.util.Collection;
+
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+public interface LocatorCondition{
+
+ boolean checkCondition(WebDriver driver, WebElement element);
+
+ Collection> exceptionsToIgnore();
+
+}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/PageObjectParentImpl.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/PageObjectParentImpl.java
index c149c3b..9274a9d 100644
--- a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/PageObjectParentImpl.java
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/PageObjectParentImpl.java
@@ -13,6 +13,7 @@
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.PageFactory;
+import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
@@ -102,6 +103,16 @@ public WebElement waitForElementToBeInteractable(By by) {
return wait.until(ExpectedConditions.elementToBeClickable(by));
}
+ public WebElement waitForElementToBeInteractable(ExpectedCondition expectedCondition) {
+ Wait wait =
+ new FluentWait<>(driver)
+ .withTimeout(Duration.ofSeconds(15))
+ .pollingEvery(Duration.ofMillis(300))
+ .ignoring(NoSuchElementException.class,ElementNotInteractableException.class);
+
+ return wait.until(expectedCondition);
+ }
+
protected WebElement waitForElementToBeInteractable(WebElement element) {
if(element == null) {
return null;
@@ -132,6 +143,21 @@ public WebElement waitForElementToBePresent(By by) {
}
+ public WebElement waitForElementToBePresent(ExpectedCondition expectedCondition) {
+ Wait wait =
+ new FluentWait<>(driver)
+ .withTimeout(Duration.ofSeconds(15))
+ .pollingEvery(Duration.ofMillis(300))
+ .ignoring(NoSuchElementException.class);
+
+ return wait.until(expectedCondition);
+
+ }
+
+
+
+
+
protected void waitForElementToBeAbsent(String xpath) {
Wait wait =
new FluentWait<>(driver)
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionClickImpl.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionClickImpl.java
new file mode 100644
index 0000000..1c91497
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionClickImpl.java
@@ -0,0 +1,36 @@
+package io.toolisticon.pogen4selenium.runtime.actions;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+
+public class ActionClickImpl extends BaseAction {
+
+ public ActionClickImpl(WebDriver driver, LocatorCondition sideCondition) {
+ super(driver, sideCondition);
+
+ }
+
+ @Override
+ public boolean checkCondition(WebDriver driver, WebElement element) {
+ return element.isDisplayed() && element.isEnabled();
+ }
+
+ @Override
+ public Collection> exceptionsToIgnore() {
+ return Arrays.asList(NoSuchElementException.class);
+ }
+
+
+ @Override
+ protected void applyAction(WebElement webElement) {
+ webElement.click();
+ }
+
+}
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionMoveToAndClickImpl.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionMoveToAndClickImpl.java
new file mode 100644
index 0000000..9726671
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionMoveToAndClickImpl.java
@@ -0,0 +1,35 @@
+package io.toolisticon.pogen4selenium.runtime.actions;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+
+public class ActionMoveToAndClickImpl extends BaseAction {
+
+
+ public ActionMoveToAndClickImpl(WebDriver driver, LocatorCondition sideCondition) {
+ super(driver, sideCondition);
+ }
+
+ @Override
+ public boolean checkCondition(WebDriver driver, WebElement element) {
+ return element.isDisplayed() && element.isEnabled();
+ }
+
+ @Override
+ public Collection> exceptionsToIgnore() {
+ return Arrays.asList(NoSuchElementException.class);
+ }
+
+ @Override
+ protected void applyAction(WebElement webElement) {
+ new Actions(driver).moveToElement(webElement).pause(300).click().perform();
+ }
+
+}
\ No newline at end of file
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionWriteImpl.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionWriteImpl.java
new file mode 100644
index 0000000..0e64c94
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/ActionWriteImpl.java
@@ -0,0 +1,44 @@
+package io.toolisticon.pogen4selenium.runtime.actions;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+
+public class ActionWriteImpl extends BaseAction {
+
+
+ private final String toSet;
+
+ public ActionWriteImpl(WebDriver driver, LocatorCondition sideCondition, String toSet) {
+ super(driver, sideCondition);
+
+ this.toSet = toSet;
+ }
+
+ @Override
+ public boolean checkCondition(WebDriver driver, WebElement element) {
+ return element.isDisplayed() && element.isEnabled();
+ }
+
+ @Override
+ public Collection> exceptionsToIgnore() {
+ return Arrays.asList(NoSuchElementException.class);
+ }
+
+ @Override
+ protected void applyAction(WebElement webElement) {
+
+ webElement.click();
+ webElement.sendKeys(Keys.CONTROL + "a");
+ webElement.sendKeys(Keys.DELETE);
+ webElement.sendKeys(toSet);
+
+ }
+
+}
\ No newline at end of file
diff --git a/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/BaseAction.java b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/BaseAction.java
new file mode 100644
index 0000000..7c6ee1c
--- /dev/null
+++ b/pogen4selenium-api/src/main/java/io/toolisticon/pogen4selenium/runtime/actions/BaseAction.java
@@ -0,0 +1,111 @@
+package io.toolisticon.pogen4selenium.runtime.actions;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.StaleElementReferenceException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+import org.openqa.selenium.support.ui.FluentWait;
+import org.openqa.selenium.support.ui.Wait;
+
+import io.toolisticon.pogen4selenium.api.ActionImpl;
+import io.toolisticon.pogen4selenium.runtime.LocatorCondition;
+
+public abstract class BaseAction implements LocatorCondition, ActionImpl{
+
+
+ protected final WebDriver driver;
+ private final LocatorCondition sideCondition;
+
+ protected BaseAction(WebDriver driver, LocatorCondition sideCondition) {
+ this.driver = driver;
+ this.sideCondition = sideCondition;
+ }
+
+
+ protected abstract void applyAction(WebElement webElement);
+
+ public void executeAction(WebElement webElement) {
+ Wait wait =
+ new FluentWait<>(driver)
+ .withTimeout(Duration.ofSeconds(15))
+ .pollingEvery(Duration.ofMillis(300))
+ .ignoreAll(getExceptionsToIgnore());
+
+ applyAction(wait.until(new OnElementCondition(webElement)));
+ }
+
+ private Collection> getExceptionsToIgnore() {
+ return Stream.concat( sideCondition.exceptionsToIgnore().stream(), this.exceptionsToIgnore().stream()).collect(Collectors.toSet());
+ }
+
+ public void executeAction(By locator) {
+
+
+ Wait wait =
+ new FluentWait<>(driver)
+ .withTimeout(Duration.ofSeconds(15))
+ .pollingEvery(Duration.ofMillis(300))
+ .ignoreAll(getExceptionsToIgnore());
+
+ applyAction(wait.until(new WithLocatorCondition(locator)));
+
+ }
+
+
+ class OnElementCondition implements ExpectedCondition {
+
+ private final WebElement webElement;
+
+ private OnElementCondition(
+ WebElement webElement) {
+
+ this.webElement = webElement;
+
+ }
+
+ @Override
+ public WebElement apply(WebDriver input) {
+ try {
+ return checkCondition(input, webElement) && sideCondition.checkCondition(input,webElement) ? webElement : null;
+ } catch (StaleElementReferenceException e) {
+ return null;
+ }
+ }
+
+ }
+
+ class WithLocatorCondition implements ExpectedCondition {
+
+ private final By locator;
+
+ private WithLocatorCondition(By locator) {
+
+ this.locator = locator;
+
+ }
+
+ @Override
+ public WebElement apply(WebDriver input) {
+
+ try {
+
+ WebElement element = input.findElement(locator);
+ return new OnElementCondition(element).apply(input);
+
+ } catch (NoSuchElementException | StaleElementReferenceException e) {
+ // can be ignored
+ }
+
+ return null;
+ }
+
+ }
+
+}
diff --git a/pogen4selenium-example/pom.xml b/pogen4selenium-example/pom.xml
index a80f04b..5b34dec 100644
--- a/pogen4selenium-example/pom.xml
+++ b/pogen4selenium-example/pom.xml
@@ -9,7 +9,7 @@
io.toolisticon.pogen4selenium
pogen4selenium
- 0.6.1
+ 0.7.0
pogen4selenium-example
@@ -33,7 +33,7 @@
io.toolisticon.pogen4selenium
pogen4selenium-api
- 0.6.1
+ 0.7.0
diff --git a/pogen4selenium-processor/dependency-reduced-pom.xml b/pogen4selenium-processor/dependency-reduced-pom.xml
index 6a1d03d..14c6e2c 100644
--- a/pogen4selenium-processor/dependency-reduced-pom.xml
+++ b/pogen4selenium-processor/dependency-reduced-pom.xml
@@ -3,7 +3,7 @@
pogen4selenium
io.toolisticon.pogen4selenium
- 0.6.1-SNAPSHOT
+ 0.6.2-SNAPSHOT
4.0.0
pogen4selenium-processor
diff --git a/pogen4selenium-processor/pom.xml b/pogen4selenium-processor/pom.xml
index a355d1e..a7c5c9e 100644
--- a/pogen4selenium-processor/pom.xml
+++ b/pogen4selenium-processor/pom.xml
@@ -9,7 +9,7 @@
io.toolisticon.pogen4selenium
pogen4selenium
- 0.6.1
+ 0.7.0
pogen4selenium-processor
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/MethodsToImplementHelper.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/MethodsToImplementHelper.java
index 55c924f..96d5b85 100644
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/MethodsToImplementHelper.java
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/MethodsToImplementHelper.java
@@ -13,7 +13,7 @@
import io.toolisticon.aptk.tools.wrapper.TypeElementWrapper;
import io.toolisticon.pogen4selenium.api.PageObject;
import io.toolisticon.pogen4selenium.processor.common.actions.ActionHelper;
-import io.toolisticon.pogen4selenium.processor.common.actions.ActionWrapper;
+import io.toolisticon.pogen4selenium.processor.common.actions.LocateActionHandler;
import io.toolisticon.pogen4selenium.processor.pageobject.ExtractDataValueWrapper;
import io.toolisticon.pogen4selenium.processor.pageobject.ExtractDataWrapper;
import io.toolisticon.pogen4selenium.processor.pageobject.PauseWrapper;
@@ -55,7 +55,7 @@ public Set getImports() {
return imports;
}
- public List getActions() {
+ public List getActions() {
return ActionHelper.getActions(executableElementWrapper);
}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionClickHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionClickHandler.java
deleted file mode 100644
index c93fe5f..0000000
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionClickHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.toolisticon.pogen4selenium.processor.common.actions;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-
-import io.toolisticon.pogen4selenium.api.ActionClick;
-import io.toolisticon.pogen4selenium.api._By;
-import io.toolisticon.pogen4selenium.processor.pageobject.ActionClickWrapper;
-import io.toolisticon.spiap.api.SpiService;
-
-@SpiService(ActionHandler.class)
-public class ActionClickHandler implements ActionHandler {
-
- @Override
- public String getSupportedActionAnnotationClassFqn() {
- return ActionClick.class.getCanonicalName();
- }
-
- @Override
- public String generateCode(Element element) {
- ActionClickWrapper wrapper = ActionClickWrapper.wrap(element);
-
- if (wrapper.by() == _By.ELEMENT) {
- return "waitForElementToBeInteractable( " + wrapper.value() + "Element).click();\n";
- } else {
- return "waitForElementToBeInteractable( By." + wrapper.by().getCorrespondingByMethodName() + "(\"" + wrapper.value() +"\")).click();\n";
- }
-
- }
-
- @Override
- public Set getImports(Element element) {
- return Collections.emptySet();
- }
-
-}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHandler.java
index 9500ac4..fdeeaeb 100644
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHandler.java
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHandler.java
@@ -10,8 +10,6 @@
/**
* Service provider interface to bind implementations for actions.
*/
-
-@Spi
public interface ActionHandler {
/**
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHelper.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHelper.java
index e2643a7..bc3cf17 100644
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHelper.java
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionHelper.java
@@ -22,10 +22,10 @@ public static boolean hasActions(ExecutableElementWrapper executableElementWrapp
return !getActions(executableElementWrapper).isEmpty();
}
- public static List getActions(ExecutableElementWrapper executableElementWrapper) {
+ public static List getActions(ExecutableElementWrapper executableElementWrapper) {
// Must get annotations by Meta annotation Action
- List actions = getActionsForElement(executableElementWrapper);
+ List actions = getActionsForElement(executableElementWrapper);
List annotatedParameters = executableElementWrapper.getParameters();
@@ -36,12 +36,12 @@ public static List getActions(ExecutableElementWrapper executabl
return actions;
}
- private static List getActionsForElement(ElementWrapper extends Element> element) {
+ private static List getActionsForElement(ElementWrapper extends Element> element) {
return element.getAnnotations().stream()
.filter(e -> e.asElement().hasAnnotation(Action.class))
- .map(e -> {
+ .map(e -> {
- return new ActionWrapper(TypeElementWrapper.wrap((TypeElement)(e.getAnnotationType().asElement())).getQualifiedName(), element.unwrap());
+ return new LocateActionHandler(TypeElementWrapper.wrap((TypeElement)(e.getAnnotationType().asElement())).getQualifiedName(), element.unwrap());
})
.collect(Collectors.toList());
}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionMoveAndClickHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionMoveAndClickHandler.java
deleted file mode 100644
index 893ac2a..0000000
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionMoveAndClickHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.toolisticon.pogen4selenium.processor.common.actions;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-
-import io.toolisticon.pogen4selenium.api.ActionMoveToAndClick;
-import io.toolisticon.pogen4selenium.api._By;
-import io.toolisticon.pogen4selenium.processor.pageobject.ActionMoveToAndClickWrapper;
-import io.toolisticon.spiap.api.SpiService;
-
-@SpiService(ActionHandler.class)
-public class ActionMoveAndClickHandler implements ActionHandler {
-
- @Override
- public String getSupportedActionAnnotationClassFqn() {
- return ActionMoveToAndClick.class.getCanonicalName();
- }
-
- @Override
- public String generateCode(Element element) {
- ActionMoveToAndClickWrapper wrapper = ActionMoveToAndClickWrapper.wrap(element);
-
- if (wrapper.by() == _By.ELEMENT) {
- return "new Actions(getDriver()).moveToElement(waitForElementToBeInteractable( " + wrapper.value() + "Element)).pause(300).click().build().perform();\n";
- } else {
- return "new Actions(getDriver()).moveToElement(waitForElementToBeInteractable( By." + wrapper.by().getCorrespondingByMethodName() + "(\"" + wrapper.value() +"\"))).pause(300).click().build().perform();\n";
- }
-
- }
-
- @Override
- public Set getImports(Element element) {
- return Collections.emptySet();
- }
-
-}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWrapper.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWrapper.java
deleted file mode 100644
index ea472e4..0000000
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWrapper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package io.toolisticon.pogen4selenium.processor.common.actions;
-
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.lang.model.element.Element;
-
-import io.toolisticon.pogen4selenium.processor.pageobject.PageObjectProcessor;
-
-public class ActionWrapper {
-
- private final String annotationTypeFqn;
- private final Element annotatedElement;
-
- private final ActionHandler actionHandler;
-
- static {
- // enforce classloader of processor
- ActionHandlerServiceLocator.setClassLoaderToUse(PageObjectProcessor.class.getClassLoader());
- }
-
- public ActionWrapper(String annotationTypeFqn, Element annotatedElement) {
- super();
-
- this.annotationTypeFqn = annotationTypeFqn;
- this.annotatedElement = annotatedElement;
-
- this.actionHandler = locateActionHandler(annotationTypeFqn);
-
- }
-
- static ActionHandler locateActionHandler (String annotationTypeFqn) {
-
- List matchingHandlers = ActionHandlerServiceLocator.locateAll().stream().filter(e -> annotationTypeFqn.equals(e.getSupportedActionAnnotationClassFqn())).collect(Collectors.toList());
-
- return !matchingHandlers.isEmpty() ? matchingHandlers.get(0) : new DefaultActionHandler();
-
- }
-
-
- public String generateCode() {
- return actionHandler.generateCode(annotatedElement);
- }
-
- public Set getImports() {
- return actionHandler.getImports(annotatedElement);
- }
-
-
-
-}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWriteHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWriteHandler.java
deleted file mode 100644
index 823cb7f..0000000
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/ActionWriteHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package io.toolisticon.pogen4selenium.processor.common.actions;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-
-import io.toolisticon.pogen4selenium.api.ActionWrite;
-import io.toolisticon.pogen4selenium.api._By;
-import io.toolisticon.pogen4selenium.processor.pageobject.ActionWriteWrapper;
-import io.toolisticon.spiap.api.SpiService;
-
-@SpiService(ActionHandler.class)
-public class ActionWriteHandler implements ActionHandler {
-
- @Override
- public String getSupportedActionAnnotationClassFqn() {
- return ActionWrite.class.getCanonicalName();
- }
-
- @Override
- public String generateCode(Element element) {
- ActionWriteWrapper wrapper = ActionWriteWrapper.wrap(element);
-
-
- if (wrapper.by() == _By.ELEMENT) {
- return "writeToElement((" + wrapper.value() + "Element), " + element.getSimpleName() + ");";
- } else {
- return "writeToElement(waitForElementToBePresent(By." + wrapper.by().getCorrespondingByMethodName() + "(\"" + wrapper.value() + "\")), " + element.getSimpleName() + ");";
- }
-
-
-
- }
-
- @Override
- public Set getImports(Element element) {
- return Collections.emptySet();
- }
-
-}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/DefaultActionHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/DefaultActionHandler.java
deleted file mode 100644
index 748809b..0000000
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/DefaultActionHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.toolisticon.pogen4selenium.processor.common.actions;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.lang.model.element.Element;
-
-public class DefaultActionHandler implements ActionHandler {
-
- @Override
- public String getSupportedActionAnnotationClassFqn() {
- // not needed...
- return null;
- }
-
- @Override
- public String generateCode(Element element) {
- return "";
- }
-
- @Override
- public Set getImports(Element element) {
- return Collections.emptySet();
- }
-
-}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/LocateActionHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/LocateActionHandler.java
new file mode 100644
index 0000000..48005fa
--- /dev/null
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/LocateActionHandler.java
@@ -0,0 +1,41 @@
+package io.toolisticon.pogen4selenium.processor.common.actions;
+
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+
+/**
+ * TODO : This was once realized as an SPI solution and need to be removed.
+ */
+public class LocateActionHandler {
+
+ private final Element annotatedElement;
+
+ private final ActionHandler actionHandler;
+
+
+ public LocateActionHandler(String annotationTypeFqn, Element annotatedElement) {
+ super();
+
+ this.annotatedElement = annotatedElement;
+
+ this.actionHandler = locateActionHandler(annotationTypeFqn);
+
+ }
+
+ static ActionHandler locateActionHandler (String annotationTypeFqn) {
+ return new UniversalActionHandler(annotationTypeFqn);
+ }
+
+
+ public String generateCode() {
+ return actionHandler.generateCode(annotatedElement);
+ }
+
+ public Set getImports() {
+ return actionHandler.getImports(annotatedElement);
+ }
+
+
+
+}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/UniversalActionHandler.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/UniversalActionHandler.java
new file mode 100644
index 0000000..f2fbffa
--- /dev/null
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/common/actions/UniversalActionHandler.java
@@ -0,0 +1,68 @@
+package io.toolisticon.pogen4selenium.processor.common.actions;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+
+import io.toolisticon.aptk.tools.TypeMirrorWrapper;
+import io.toolisticon.aptk.tools.wrapper.AnnotationMirrorWrapper;
+import io.toolisticon.aptk.tools.wrapper.ElementWrapper;
+import io.toolisticon.pogen4selenium.api._By;
+import io.toolisticon.pogen4selenium.processor.pageobject.ActionWrapper;
+
+public class UniversalActionHandler implements ActionHandler {
+
+ private final String annotation;
+
+ public UniversalActionHandler(String annotation) {
+ this.annotation = annotation;
+ }
+
+ @Override
+ public String generateCode(Element element) {
+
+ ElementWrapper> elementWrapper = ElementWrapper.wrap(element);
+
+ AnnotationMirrorWrapper annotationMirrorWrapper = AnnotationMirrorWrapper.get(element, annotation).get();
+ TypeMirrorWrapper sideConditionTmw = annotationMirrorWrapper.getAttributeWithDefault("actionSideCondition").getClassValue();
+ _By by = annotationMirrorWrapper.getAttributeWithDefault("by").getEnumValue(_By.class);
+ String annotationValue = annotationMirrorWrapper.getAttribute().get().getStringValue();
+
+ ActionWrapper actionWrapper = ActionWrapper.wrap(annotationMirrorWrapper.asElement().unwrap());
+
+
+
+ if (by == _By.ELEMENT) {
+ return "new " + actionWrapper.valueAsTypeMirrorWrapper().getSimpleName() + "( getDriver(), new " + sideConditionTmw.getSimpleName() + "()" + (elementWrapper.isMethodParameter() ? ", " + element.getSimpleName() : "") + ").executeAction(" + annotationValue + "Element);\n";
+ } else {
+ return "new " + actionWrapper.valueAsTypeMirrorWrapper().getSimpleName() + "( getDriver(), new " + sideConditionTmw.getSimpleName() + "()" + (elementWrapper.isMethodParameter() ? ", " + element.getSimpleName() : "") + ").executeAction(By." + by.getCorrespondingByMethodName() + "(\"" + annotationValue +"\"));\n";
+ }
+
+ }
+
+ @Override
+ public Set getImports(Element element) {
+ AnnotationMirrorWrapper annotationMirrorWrapper = AnnotationMirrorWrapper.get(element, annotation).get();
+ TypeMirrorWrapper sideConditionTmw = annotationMirrorWrapper.getAttributeWithDefault("actionSideCondition").getClassValue();
+
+ ActionWrapper actionWrapper = ActionWrapper.wrap(annotationMirrorWrapper.asElement().unwrap());
+
+
+ Set imports = new HashSet<>();
+ imports.add(sideConditionTmw.getQualifiedName());
+ imports.add(actionWrapper.valueAsTypeMirrorWrapper().getQualifiedName());
+
+ return imports;
+ }
+
+ @Override
+ public String getSupportedActionAnnotationClassFqn() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+
+}
diff --git a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/pageobject/package-info.java b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/pageobject/package-info.java
index 52d9a00..e424b65 100644
--- a/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/pageobject/package-info.java
+++ b/pogen4selenium-processor/src/main/java/io/toolisticon/pogen4selenium/processor/pageobject/package-info.java
@@ -1,12 +1,13 @@
/**
* This package contains the seleniumap annotation processor.
*/
-@AnnotationWrapper(value={PageObject.class, PageObjectElement.class, ActionClick.class, ActionMoveToAndClick.class, ActionWrite.class, ExtractData.class, ExtractDataValue.class ,Pause.class}
+@AnnotationWrapper(value={PageObject.class, PageObjectElement.class, Action.class, ActionClick.class, ActionMoveToAndClick.class, ActionWrite.class, ExtractData.class, ExtractDataValue.class ,Pause.class}
,bindCustomCode = {PageObjectWrapperExtension.class, ExtractDataWrapperExtension.class, ExtractDataValueWrapperExtension.class}
,usePublicVisibility = true)
package io.toolisticon.pogen4selenium.processor.pageobject;
+import io.toolisticon.pogen4selenium.api.Action;
import io.toolisticon.pogen4selenium.api.ActionClick;
import io.toolisticon.pogen4selenium.api.ActionMoveToAndClick;
import io.toolisticon.pogen4selenium.api.ActionWrite;
diff --git a/pom.xml b/pom.xml
index d0e1d8c..d022c6d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.toolisticon.pogen4selenium
pogen4selenium
- 0.6.1
+ 0.7.0
pom
pogen4selenium
Please refer to https://github.com/toolisticon/pogen4selenium