For example, the page has a container field with a locator id = "test1" and another field with a locator id = "field1"
The joined locator should search in the locator id = "test1" for the locator id = "field1": locator1.findElement().findElement((By) locator2)
How to create an element locator contained from multiple merged locators in Java Selenium
In the code, it is indicated as mergeLocator, but I do not know how to do this.
ElementLocator mergeLocator = locator1 + locator2;
My code:
import lombok.SneakyThrows;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.pagefactory.DefaultFieldDecorator;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class ElementsDecorator extends DefaultFieldDecorator {
private WebDriver driver;
public ElementsDecorator(ElementLocatorFactory factory, WebDriver driver) {
super(factory);
this.driver = driver;
}
@SneakyThrows
@Override
public Object decorate(ClassLoader loader, Field field) {
ElementLocator locator1 = factory.createLocator(field);
ElementLocator locator2 = factory.createLocator(field.getDeclaringClass().getDeclaredField("container"));
ElementLocator mergeLocator = locator1 + locator2;
return createElement(loader, mergeLocator, field.getType());
}
protected <T> T createElement(ClassLoader loader, ElementLocator locator, Class<?> tClass) {
WebElement proxy = proxyForLocator(loader, locator);
try {
return (T) tClass.getConstructor(WebElement.class, WebDriver.class).newInstance(proxy, driver);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | InstantiationException |
InvocationTargetException e) {
throw new AssertionError("WebElement can't be represented as " + tClass);
}
}
}