如何消除页面对象模型中的重复WebElement

时间:2017-10-04 07:57:03

标签: java selenium selenium-webdriver pageobjects page-factory

我正在使用POM框架,我已经为我的应用程序页面创建了页面类。可以说我的申请中有2页1.事件2.时间表。所以我创建了2个页面类

EventPage.java

public class RCON_D_EventPage 
{

    @FindBy(xpath="//input[@placeholder='Search for entered records']")
    public WebElement eventSearchBox;

    @FindBy(xpath="//button[@class='btn rc-gray-bg rc-dashboard-contact-btn ng-scope']")
    public WebElement eventSearchButton;


    @FindBy(xpath="//p[@ class='rc-found-record no-padding ng-binding ng-scope']")
    public WebElement eventSearchResult;

    @FindBy(xpath="//div/span[@class='ng-scope']")
    public WebElement searchResultNotFound;

    @FindBy(xpath="//li/button[@ng-click='goToFirstPage()']")
    public WebElement nextPageButton;

    @FindBy(xpath="//button[@ng-click='clearFilters()'][1]")
    public WebElement clearFilterButton;


    WebDriver driver;

    public RCON_D_EventPage(WebDriver driver)
    {

        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
        this.driver=driver;
    }
    public void enterTextInEventSearchBox(String text)
    {
        eventSearchBox.clear();
        eventSearchBox.sendKeys(text);
    }

    public void clickEventSearchButton()
    {
        eventSearchButton.click();
    }

    public String getEventSearchResult()
    {
        return eventSearchResult.getText();
    }

    public String getNoRecordFoundMessage()
    {
        return searchResultNotFound.getText();
    }
    public void clickNextPageButton()
    {
        nextPageButton.click();
    }
    public void clickClearFilterButton()
    {
        clearFilterButton.click();
    }
}

TimeLinePage.java

public class RCON_D_TimelinePage 
{

    @FindBy(xpath="//input[@placeholder='Search for entered records']")
    public WebElement timelineSearchBox;

    @FindBy(xpath="//button[@class='btn rc-gray-bg rc-dashboard-contact-btn ng-scope']")
    public WebElement searchButton;

    @FindBy(xpath="//p[@class='rc-found-record no-padding ng-binding ng-scope']")
    public WebElement searchResult;

    @FindBy(xpath="//div[@class='row ng-scope']")
    public List<WebElement> totalFoundRecords;

    @FindBy(xpath="//span[text()='No data found']")
    public WebElement noResultMessage;

    @FindBy(xpath="//button[@ng-click='clearFilters()'][1]")
    public WebElement clearFilterButton;

    public RCON_D_TimelinePage(WebDriver driver)
    {

        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
        this.driver=driver;
    }

    public void enterTextInSearchBox(String text)
    {
        timelineSearchBox.sendKeys(text);
    }
    public void clickSearchButton()
    {
        searchButton.click();
    }
    public String getSearchResult()
    {
        return searchResult.getText();
    }
    public int getFoundRecordCount()
    {
        return totalFoundRecords.size();
    }

    public String getNoResultFoundMessage()
    {
        return noResultMessage.getText();
    }

    public void clickClearFilterButton()
    {
        clearFilterButton.click();
    }
}

所以在这两个页面中都有一些常见的WebElement,例如//input[@placeholder='Search for entered records']//button[@class='btn rc-gray-bg rc-dashboard-contact-btn ng-scope']等等。那么我有什么方法可以在页面对象模型中管理这种冗余吗?

2 个答案:

答案 0 :(得分:1)

在这种情况下,您可以使用合成(is-A,has-A关系)。

has-A Relationship

您可以创建一个用于搜索的页面类,并复制此类中的所有方法。而所有其他具有此元素的Page类,您只需创建此页面的对象即可。

以下示例显示了has-A关系。

class SearchPage{
    @FindBy(xpath="//input[@placeholder='Search for entered records']")
    public WebElement timelineSearchBox;

    @FindBy(xpath="//button[@class='btn rc-gray-bg rc-dashboard-contact-btn ng-scope']")
    public WebElement searchButton;

    public SearchPage(WebDriver driver){
        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
        this.driver = driver;
    }
    public void enterTextInSearchBox(String text){
        timelineSearchBox.sendKeys(text);
    }
    public void clickSearchButton(){
        searchButton.click();
    }
}


public class RCON_D_EventPage{
    SearchPage searchPage;
    public RCON_D_EventPage(WebDriver driver){

        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
        this.driver=driver;
        searchPage = new SearchPage(driver);
    }
}

是一种关系

您也可以使用is-A关系实现相同的目标。我的意思是你可以使用SearchPage类扩展每个需要搜索功能的类。

就我个人而言,我建议使用has-A Relationship,因为它在编程方面更有意义,而不是如下所述的is-A。

public class RCON_D_EventPage extends SearchPage{

    public RCON_D_EventPage(WebDriver driver){
        super(driver);
        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
        this.driver=driver;

    }
}

答案 1 :(得分:0)

听起来你有两个页面上有一个共同的标题或者只是一个搜索框。在这种情况下,您要做的是只为标题/搜索框区域创建一个页面对象。它将包含元素

@FindBy(xpath="//input[@placeholder='Search for entered records']")
public WebElement eventSearchBox;

@FindBy(xpath="//button[@class='btn rc-gray-bg rc-dashboard-contact-btn ng-scope']")
public WebElement eventSearchButton;
然后可以从两个现有页面对象中删除

。无论您在哪个页面,都可以在需要时实例化头页面对象。

不要将页面对象视为代表整页。可以把它们想象成一个小部件对象,其中小部件可以是整页,也可以只是页面的一部分,其功能可以在不同的页面上重复。

在这里阅读更多内容:

https://martinfowler.com/bliki/PageObject.html