我知道您无法在中初始化Select对象PageFactory。我一直在互联网上搜索,但只找到了一个可能的答案,可以使用ElementLocatorFactory但在实现方面没有太多细节。我要问他们是成功实施它还是有实现它的想法的人,可以通过以外的其他方式来确定ElementLocatorFactory。
Select
PageFactory
ElementLocatorFactory
目前,我仅使用以下内容:
@FindBy(how = How.ID, using = "select-log-status") public WebElement __logStatus; public Select selectLogStatus() { return new Select(__logStatus); }
我正在寻找实现的东西是这样的。
@FindSelectBy(how = How.ID, using = "select-log-status") public Select selectLogStatus;
PS。我是selenium的新手,也是回来的Java开发人员,所以请好好对待我:)
由于没有人分享某些东西,因此我将分享我的做法。
我查看了一下代码,发现它的对象类型正在使用DefaultFieldDecorator的decorate方法进行过滤,因此我所做的只是创建了一个自定义FieldDecorator并扩展了DefaultFieldDecorator该类,因为我只想覆盖decorate。
DefaultFieldDecorator
decorate
所以,我有一个PageObject类 MyPageObjects
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());
我会像这样初始化元素…
MyPageObjects page = new MyPageObjects(driver); PageFactory.initElements(new CustomFieldDecorator( new DefaultElementLocatorFactory(driver), page);
并照常访问Select对象…
page.mySelectObj.selectByVisibleText("hello world");
警告 :这没有用Proxy,所以要小心。并且WebElement包装的Select类被缓存。
Proxy
WebElement
更新:
我为创建了代理处理程序Select。我创建了一个扩展类Select和一个包含Select的方法的接口。
CustomSelect.java
public class CustomSelect extends Select implements SelectInput { public CustomSelect(WebElement element) { super(element); } }
SelectInput.java -接口
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
SelectElementHanlder.java
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 (SelectInput.class.isAssignableFrom(field.getType())) { return proxySelectForLocator(loader, locator);
现在,我将在PageObject类中声明选择对象,例如:
@FindBy(xpath = "some..xpath") public SelectInput ticketStatus;
希望能帮助到你。如果有更正,请修改:)