Поскольку никто не делился чем-то, я расскажу, как я это сделал.
Я посмотрел в код и обнаружил, что его тип объекта фильтруется в DefaultFieldDecorator
«s decorate
метод, так что я сделал просто создал пользовательское FieldDecorator и расширил DefaultFieldDecorator
класс, потому что я только хотел, чтобы переопределить decorate
,
Итак, у меня есть класс PageObject MyPageObjects
public class MyPageObjects {
protected final WebDriver driver;
public MyPageObjects (WebDriver driver) {
this.driver = driver;
}
@FindBy(id = "my-select-object")
public Select mySelectObj;
}
Мой CustomFieldDecorator будет содержать этот переопределен метод:
@Override
public Object decorate(ClassLoader loader, Field field) {
if (!(WebElement.class.isAssignableFrom(field.getType())
|| Select.class.isAssignableFrom(field.getType())
|| List.class.isAssignableFrom(field.getType())
|| isDecoratableList(field))) {
return null;
}
ElementLocator locator = factory.createLocator(field);
if (locator == null) {
return null;
}
if (WebElement.class.isAssignableFrom(field.getType())) {
return proxyForLocator(loader, locator);
} else if (List.class.isAssignableFrom(field.getType())) {
return proxyForListLocator(loader, locator);
} else if (Select.class.isAssignableFrom(field.getType())) {
return new Select(locator.findElement());
} else {
return null;
}
}
Обратите внимание на линии:
|| Select.class.isAssignableFrom(field.getType())
и
} else if (Select.class.isAssignableFrom(field.getType())) {
return new Select(locator.findElement());
Я бы initElements, как это ...
MyPageObjects page = new MyPageObjects(driver);
PageFactory.initElements(new CustomFieldDecorator(
new DefaultElementLocatorFactory(driver), page);
и доступ Выбрать объект, как обычно ...
page.mySelectObj.selectByVisibleText("hello world");
РИСКОВАННАЯ: Это не использует Proxy
, так быть осторожен. И WebElement
Выбранный класс, завернутый, кэшируется.
UPDATE:
Я создал прокси-обработчик для Select
. Я создал класс, расширяющий Select
, и интерфейс, имеющий методы Select
.
CustomSelect.java
public class CustomSelect extends Select implements SelectInput {
public CustomSelect(WebElement element) {
super(element);
}
}
SelectInput.java
- Интерфейс
public interface SelectInput {
boolean isMultiple();
List<WebElement> getOptions();
List<WebElement> getAllSelectedOptions();
WebElement getFirstSelectedOption();
void selectByVisibleText(String text);
void selectByIndex(int index);
void selectByValue(String value);
void deselectAll();
void deselectByValue(String value);
void deselectByIndex(int index);
void deselectByVisibleText(String text);
}
SelectElementHanlder.java
- InvocationHandler
public class SelectElementWrapperHandler implements InvocationHandler {
private final ElementLocator locator;
public SelectElementWrapperHandler(ElementLocator locator) {
this.locator = locator;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
CustomSelect element;
try {
element = new CustomSelect(locator.findElement());
} catch (Exception e) {
if ("toString".equals(method.getName())) {
return "Proxy select(element) for: " + locator.toString();
}
else throw e;
}
try {
return method.invoke(element, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
Создан метод в CustomFieldDecorator
protected SelectInput proxySelectForLocator(ClassLoader loader, ElementLocator locator) {
InvocationHandler handler = new SelectElementWrapperHandler(locator);
SelectInput proxy;
proxy = (SelectInput) Proxy.newProxyInstance(
loader, new Class[]{SelectInput.class}, handler);
return proxy;
}
И изменить эту линию от CustomFieldDecorator
} else if (Select.class.isAssignableFrom(field.getType())) {
return new Select(locator.findElement());
к этому:
} else if (SelectInput.class.isAssignableFrom(field.getType())) {
return proxySelectForLocator(loader, locator);
Теперь я хотел бы объявить выберите объект в моем классе PageObject как:
@FindBy(xpath = "some..xpath")
public SelectInput ticketStatus;
Надеюсь, это поможет. Пожалуйста, измените, если у вас есть исправления :)
У вас есть это в репозитории git или что-то в этом роде? Я бы хотел взглянуть на него в целом – Gab
@ GabrieleB-David, он находится внутри нашего внутреннего git-репо. Но это в основном это. Вы также можете проверить документы selenium, так как это очень полезно. – rrw