2016-03-11 92 views
1

我知道你不能在PageFactory中初始化一個Select對象。 我一直在網上搜索,發現只有一個可能的答案,使用ElementLocatorFactory,但沒有太多的實施細節。 我問他們是否成功實施它或有想法實施它,即時通訊除了ElementLocatorFactory之外的其他方式。在Selenium的PageFactory上選擇對象

目前,我只是在使用這樣的事情:

@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。進出口新的硒和返回Java開發人員,所以請對我好的人:)

回答

2

由於沒有人分享了一些東西,我會分享我是如何做到的。

我看着代碼,並發現它的對象類型被過濾,DefaultFieldDecoratordecorate方法,我這樣做是什麼簡單地創建一個自定義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; 

希望它有幫助。請修改如果有更正:)

+0

你有沒有把這個保存在git倉庫裏?我想看看它作爲一個整體 – Gab

+1

@ GabrieleB-David它在我們的內部git回購。但基本上就是這樣。您也可以查看硒的文檔,因爲它非常有幫助。 – rrw

0

恕我直言,你可以在類的構造函數或者驅動程序初始化初始化一個選擇元素。

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

謝謝你的回答@Haxor,是的,這是正確的。但在我的問題中,我正在使用'PageFactory'來初始化我的頁面對象。但是'PageFactory'只初始化'WebElements'而不是'Select'對象。 – rrw