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

How to eliminate duplicate WebElement in Page Object Model

我正在使用 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'] 等等。那么有什么方法可以管理页面对象模型中的这种冗余?

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

有关系

您可以创建一个页面Class 用于搜索并复制此class 中的所有方法。而所有其他具有此元素的Page class,您只需创建此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 class 扩展每个需要搜索功能的 class。

就个人而言,我建议使用 has-A 关系,因为它在编程方面比下面提到的 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;

    }
}

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

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

然后可以从现有的两个页面 object 中删除。无论您在哪个页面,您都可以在需要时实例化 header 页面 object。

不要将第 object 页视为整页。将它们更像是一个小部件 object,其中小部件可以是整个页面或只是具有在不同页面上重复的功能的页面的一部分。

在此处阅读更多内容:

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