Java selenium 页面对象菜单

Java selenium Page Object Menu

我正在使用页面对象模型。在我的网站上,大多数页面都有一个菜单,所以我想我应该创建一个 class MenuPage,每个其他有菜单的页面都会扩展它。

但现在我想重新组合菜单中的所有 WebElement,以便将它们与当前页面之一分开。

换句话说,如果一个元素直接在页面上,我会以类似的方式访问它。

MyPage mypage = new MyPage(); /*MyPage extends MenuPage*/
mypage.myWebElement.click();

但是如果网络元素是菜单的一部分,而不是 MyPage 的一部分,我想从

访问它
MyPage mypage = new MyPage();  /*MyPage extends MenuPage*/
mypage.menu.myWebElement.click();

我知道我可以创建一个 class 菜单并将其实例化到 MenuPage 中,但由于它只会在那里使用,所以我不希望将它与 class MenuPage 分开。而且,菜单也有子菜单,所以我想用多级字段来表示它。每个子菜单都有一个新的 class 可以让很多 class 花这么少的钱。

这样做的最佳方法是什么,或者您知道解决问题的其他方法吗?

为了遵循组合优于继承,我建议创建一个接口,例如IHasMenu,它有一个方法returns你的MenuPage 对象,例如 getMenuPage().

这样,所有具有菜单的页面对象都只需实施该方法即可获取菜单。

您的代码将与您想要的类似:

MyPage mypage = new MyPage();
mypage.getMenuPage().myWebElement.click();

界面将是:

interface IHasMenu{
    public MenuPage getMenuPage();
}

还有你的我的页面:

public class MyPage implements IHasMenu
{
    public MenuPage getMenuPage()
    {
        return new MenuPage(); //(Or however you initialize your PO's)
        //Or return a private property if you don't want to create a new one
        //every time this is called
    }
}

如果为继承自 IHasMenu 的每个 class 添加一个 GetMenuPage() 方法让你觉得违反了 DRY 原则,你可以使用扩展方法,并从界面中删除 public MenuPage getMenuPage();。扩展名是这样的:

public static class IHasMenuExtensions
{
    public static MenuPage GetMenuPage(this IHasMenu hasMenuPageObject)
    {
        return new MenuPage();
    }
}

只需确保 IHasMenuExtensionsIHasMenu 位于同一命名空间,这样您就可以像以前一样调用它,而无需为您的扩展添加自定义 using 语句 class.

我敢打赌所有的菜单都是相似的。 您可以恰好实施一个 class SubMenu。 您可以调用其构造函数来指定您需要哪个 SubMenu,例如:

SubMenu sweets = new SubMenu("sweets");
SubMenu vegetables = new SubMenu("vegetables");

页面不是菜单。页面有菜单。只有当 IS A 关系时,我们才能扩展。否则遵循composition over inheritance原则。

我建议您使用 Page Fragments 以获得更好的可重用性。

也就是说,您创建了名为 'Page Fragments' 的可重用组件,如此处所示,并在页面对象中使用它。