在selenium的PageFactory

时间:2016-03-11 03:27:22

标签: java selenium

我知道您无法在Select中初始化PageFactory对象。 我一直在互联网上搜索并找到一个可能的答案,使用ElementLocatorFactory但没有太多关于实施的细节。 我问他们是否是成功实施它的人或有实施它的想法,我可以通过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开发人员的新手,所以请好好对待我:)

3 个答案:

答案 0 :(得分:3)

由于没有人分享某些内容,我将分享我是如何做到的。

我查看了代码并发现其对象类型正在DefaultFieldDecorator的{​​{1}}方法中进行过滤,因此我所做的只是创建了一个自定义FieldDecorator并扩展了{{1因为我只想覆盖decorate

所以,我有一个PageObject类DefaultFieldDecorator

decorate

我的CustomFieldDecorator将包含此覆盖方法:

MyPageObjects

注意以下几行:

public class MyPageObjects {
    protected final WebDriver driver;
    public MyPageObjects (WebDriver driver) {
        this.driver = driver;
    }


    @FindBy(id = "my-select-object")
    public Select mySelectObj;
}

@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;
    }
}

我会像这样的initElements ......

|| Select.class.isAssignableFrom(field.getType())

并像往常一样访问Select对象......

} 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); ,所以要小心。并且page.mySelectObj.selectByVisibleText("hello world"); 选择包裹的类被缓存。

<强>更新

我为Proxy创建了一个代理处理程序。我创建了一个扩展WebElement的类和一个具有Select方法的接口。

Select

Select

CustomSelect.java - 界面

public class CustomSelect extends Select implements SelectInput {
    public CustomSelect(WebElement element) {
        super(element);
    }
}

SelectInput.java - InvocationHandler

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);
}

在CustomFieldDecorator

中创建了一个方法
SelectElementHanlder.java

从CustomFieldDecorator更改此行

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();
        }

    }

}

到此:

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;
    }

现在,我将在PageObject类中声明select对象,如:

} else if (Select.class.isAssignableFrom(field.getType())) {
          return new Select(locator.findElement());

希望它有所帮助。如果有更正,请修改:)

答案 1 :(得分:0)

恕我直言,您可以在类构造函数中初始化Select元素或初始化驱动程序。

Select dropDown = new Select(driver.findElement(locator));

答案 2 :(得分:0)

声明为WebElement

@FindBy(xpath = ".//span[text()='Country Located*']/parent::div/parent::div//select")
private WebElement select_Country;

元素的初始化:

public Constructor(WebDriver driver) {
    PageFactory.initElements(driver,this);
    this.interactions = new Interactions(driver);
    PropertyConfigurator.configure("log4j.properties");
}

创建要等待的方法,然后强制转换为“选择”

public void selectFromDropDown(WebElement element, String country) {
      try{
        if (wait.until(ExpectedConditions.visibilityOf(element)).isDisplayed()){
            Select select = new Select(element);
            select.selectByVisibleText(country);
        }
      }
    }

用法

selectFromDropDown(select_Country,userDetails.getCountry());