Reputation: 165
I'm using a Page Object model. And on my website most page have a menu, so I was thinking I should create a class MenuPage that every other page that have a menu would extends it.
But now I would like to regroups all my WebElement from the menu to kinda separate them from the one of the current page.
In other word, if an element is directly on the page, I would access it something like that.
MyPage mypage = new MyPage(); /*MyPage extends MenuPage*/
mypage.myWebElement.click();
But if the webelement is part of the menu, and not part of MyPage, I would like to access it from
MyPage mypage = new MyPage(); /*MyPage extends MenuPage*/
mypage.menu.myWebElement.click();
I know I could create a class menu and instance it into MenuPage, but since it will only be used there, I would prefer not to have it separated from the class MenuPage. And also, the menu also have submenu, and so I would like to represent it with multi-level fields. And having a new class for each submenu could make a lots of class for so little.
What would be the best way to do so, or do you know a other way to approch the problem?
Upvotes: 3
Views: 2469
Reputation: 1991
To follow Composition over inheritance I would suggest making an interface, like IHasMenu
, and it has one method that returns your MenuPage
object, like getMenuPage()
.
That way all of your page objects that have a menu just have to implement that one method to get your menu.
Your code would read similar to what you wanted:
MyPage mypage = new MyPage();
mypage.getMenuPage().myWebElement.click();
The interface would be:
interface IHasMenu{
public MenuPage getMenuPage();
}
And your MyPage:
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
}
}
If adding a GetMenuPage()
method for every class that inherits from IHasMenu
makes you feel gross about violating the DRY principle, you can use an extension method, and remove the public MenuPage getMenuPage();
from your interface. The extension would be something like this:
public static class IHasMenuExtensions
{
public static MenuPage GetMenuPage(this IHasMenu hasMenuPageObject)
{
return new MenuPage();
}
}
Just make sure that IHasMenuExtensions
is in the same namespace as IHasMenu
, than you'll be able to call it just like you would before without adding a custom using statement for your extensions class.
Upvotes: 0
Reputation: 15400
Page is not menu. Page has menu. We can extend only if it IS A relationship. Otherwise go with composition over inheritance principle.
I would suggest you to go with Page Fragments for better reusability.
That is, you create reusable components called 'Page Fragments' as shown here and use it in the Page Objects.
Upvotes: 5
Reputation: 4596
I bet all the menus are similar.
You could implement exactly one class SubMenu
.
You could call its constructor to specify which SubMenu
you need, e.g.:
SubMenu sweets = new SubMenu("sweets");
SubMenu vegetables = new SubMenu("vegetables");
Upvotes: 0