com.codeborne.selenide.appium.SelenideAppiumPageFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of selenide-appium Show documentation
Show all versions of selenide-appium Show documentation
Selenide adaptor for Appium framework
package com.codeborne.selenide.appium;
import com.codeborne.selenide.BaseElementsCollection;
import com.codeborne.selenide.Driver;
import com.codeborne.selenide.Selenide;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.impl.CollectionSource;
import com.codeborne.selenide.impl.ElementFinder;
import com.codeborne.selenide.impl.LazyWebElementSnapshot;
import com.codeborne.selenide.impl.NoOpsList;
import com.codeborne.selenide.impl.SelenidePageFactory;
import com.codeborne.selenide.impl.WebElementSource;
import io.appium.java_client.HasBrowserCheck;
import io.appium.java_client.pagefactory.AndroidFindAll;
import io.appium.java_client.pagefactory.AndroidFindBy;
import io.appium.java_client.pagefactory.AndroidFindByAllSet;
import io.appium.java_client.pagefactory.AndroidFindByChainSet;
import io.appium.java_client.pagefactory.AndroidFindBySet;
import io.appium.java_client.pagefactory.AndroidFindBys;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.DefaultElementByBuilder;
import io.appium.java_client.pagefactory.bys.builder.AppiumByBuilder;
import io.appium.java_client.pagefactory.iOSXCUITFindAll;
import io.appium.java_client.pagefactory.iOSXCUITFindBy;
import io.appium.java_client.pagefactory.iOSXCUITFindByAllSet;
import io.appium.java_client.pagefactory.iOSXCUITFindByChainSet;
import io.appium.java_client.pagefactory.iOSXCUITFindBySet;
import io.appium.java_client.pagefactory.iOSXCUITFindBys;
import org.jspecify.annotations.Nullable;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ByIdOrName;
import org.openqa.selenium.support.pagefactory.FieldDecorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.time.Duration;
import java.util.List;
import java.util.Optional;
import static com.codeborne.selenide.impl.WebdriverUnwrapper.cast;
import static io.appium.java_client.remote.options.SupportsAutomationNameOption.AUTOMATION_NAME_OPTION;
public class SelenideAppiumPageFactory extends SelenidePageFactory {
private static final Logger logger = LoggerFactory.getLogger(SelenideAppiumPageFactory.class);
private final List> platformAnnotations =
List.of(AndroidFindBy.class, AndroidFindBys.class, AndroidFindAll.class, AndroidFindByAllSet.class, AndroidFindByChainSet.class,
AndroidFindBySet.class, iOSXCUITFindBy.class, iOSXCUITFindBys.class, iOSXCUITFindAll.class, iOSXCUITFindByAllSet.class,
iOSXCUITFindByChainSet.class, iOSXCUITFindBySet.class);
@Override
protected By findSelector(Driver driver, Field field) {
AppiumByBuilder builder = byBuilder(driver, field);
builder.setAnnotated(field);
By selector = builder.buildBy();
return selector != null ? selector : super.findSelector(driver, field);
}
private DefaultElementByBuilder byBuilder(Driver driver, Field field) {
if (!isPlatformAnnotationAdded(field)) {
return new DefaultElementByBuilder(null, null);
}
if (!driver.hasWebDriverStarted()) {
throw new WebDriverException("The SelenideAppiumPageFactory requires a webdriver instance to be created before page" +
" initialization; No webdriver is bound to current thread. You need to call open() first");
}
Optional hasBrowserCheck = cast(driver, HasBrowserCheck.class);
if (hasBrowserCheck.isPresent() && hasBrowserCheck.get().isBrowser()) {
return new DefaultElementByBuilder(null, null);
}
Optional hasCapabilities = cast(driver, HasCapabilities.class);
if (hasCapabilities.isPresent()) {
Capabilities d = hasCapabilities.get().getCapabilities();
String platform = String.valueOf(d.getPlatformName());
String automationName = String.valueOf(d.getCapability(AUTOMATION_NAME_OPTION));
return new DefaultElementByBuilder(platform, automationName);
}
return new DefaultElementByBuilder(null, null);
}
@Override
protected FieldDecorator defaultFieldDecorator(Driver driver, @Nullable WebElementSource searchContext) {
SearchContext context = getSearchContext(driver, searchContext);
return new AppiumFieldDecorator(context);
}
@Nullable
@Override
public Object decorate(
ClassLoader loader,
Driver driver,
@Nullable WebElementSource searchContext,
Field field,
By selector,
Type[] genericTypes
) {
if (selector instanceof ByIdOrName) {
return decorateWithAppium(loader, searchContext, field);
}
return super.decorate(loader, driver, searchContext, field, selector, genericTypes);
}
@Nullable
private Object decorateWithAppium(ClassLoader loader, @Nullable WebElementSource searchContext, Field field) {
if (searchContext == null) {
logger.warn("Cannot initialize field {}", field);
return null;
}
AppiumFieldDecorator defaultAppiumFieldDecorator = new AppiumFieldDecorator(searchContext.getWebElement(), Duration.ZERO);
Object appiumElement = defaultAppiumFieldDecorator.decorate(loader, field);
if (appiumElement instanceof WebElement) {
// TODO Make appiumElement lazy-loaded
return Selenide.$((WebElement) appiumElement);
}
return appiumElement;
}
@Override
protected SelenideElement decorateWebElement(Driver driver, @Nullable WebElementSource searchContext, By selector,
Field field, @Nullable String alias) {
return shouldCache(field) ?
LazyWebElementSnapshot.wrap(new ElementFinder(driver, searchContext, selector, 0, alias)) :
ElementFinder.wrap(driver, SelenideAppiumElement.class, searchContext, selector, 0, alias);
}
@Override
protected BaseElementsCollection extends SelenideElement, ? extends BaseElementsCollection, ?>> createCollection(
CollectionSource collection, Class> klass
) {
return klass.isAssignableFrom(SelenideAppiumList.class) ?
new SelenideAppiumList(collection) :
super.createCollection(collection, klass);
}
private static class SelenideAppiumList extends SelenideAppiumCollection implements NoOpsList {
SelenideAppiumList(CollectionSource collection) {
super(collection);
}
}
private boolean isPlatformAnnotationAdded(Field field) {
return platformAnnotations.stream().anyMatch(field::isAnnotationPresent);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy