2017-01-18 2 views
3

J'utilise un modèle d'objet de page. Et sur mon site web la plupart des pages ont un menu, donc je pensais que je devais créer une classe MenuPage que toutes les autres pages qui ont un menu l'étendraient. Mais maintenant je voudrais regrouper tous mes WebElement du menu pour les séparer de celui de la page actuelle. En d'autres termes, si un élément est directement sur la page, j'accéderais à quelque chose comme ça.Java selenium Page Objet Menu

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

Mais si le WebElement fait partie du menu, et ne fait pas partie de MyPage, je voudrais y accéder à partir

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

Je sais que je pourrais créer un menu de classe et d'instance dans MenuPage , mais comme il ne sera utilisé que là, je préférerais ne pas l'avoir séparé de la classe MenuPage. Et aussi, le menu a aussi un sous-menu, et donc je voudrais le représenter avec des champs à plusieurs niveaux. Et avoir une nouvelle classe pour chaque sous-menu pourrait faire beaucoup de classe pour si peu.

Quelle serait la meilleure façon de le faire, ou connaissez-vous un autre moyen d'aborder le problème?

+0

Je pense que vous voyez une partie de l'argument pour la composition de l'héritage avec la façon dont cela devient compliqué en utilisant l'héritage. Je ne suis pas sûr de comprendre totalement ce qui se passe avec les sous-menus, mais si vous pouvez clarifier un peu, il y a probablement quelques approches différentes que vous pouvez utiliser ici. – mrfreester

Répondre

4

page n'est pas menu. La page a un menu. Nous pouvons étendre seulement si est une relation.Sinon, passez au principe composition over inheritance.

Je vous suggère d'aller avec Page Fragments pour une meilleure réutilisabilité. C'est-à-dire que vous créez des composants réutilisables appelés «Fragments de page» comme indiqué ici et que vous les utilisez dans les objets Page.

enter image description here

+0

Pourquoi downvote? Quel est le problème avec cette réponse? – vins

0

Pour suivre Composition de l'héritage je suggère faire une interface, comme IHasMenu, et il a une méthode qui retourne votre objet MenuPage, comme getMenuPage().

De cette façon, tous vos objets de page qui ont un menu doivent simplement implémenter cette méthode pour obtenir votre menu.

Votre code lirait semblable à ce que vous vouliez:

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

L'interface serait:

interface IHasMenu{ 
    public MenuPage getMenuPage(); 
} 

Et votre MaPage:

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 
    } 
} 

Si vous ajoutez une méthode GetMenuPage() pour chaque classe qui hérite de IHasMenu vous fait sentir brut ab En violation du principe DRY, vous pouvez utiliser une méthode d'extension et retirer le public MenuPage getMenuPage(); de votre interface. L'extension serait quelque chose comme ceci:

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

Assurez-vous que IHasMenuExtensions est dans le même espace que IHasMenu, que vous serez en mesure de l'appeler comme vous le feriez avant sans ajouter une déclaration à l'aide pour votre classe d'extensions.

0

Je parie que tous les menus sont similaires. Vous pouvez implémenter exactement une classe SubMenu. Vous pouvez appeler son constructeur pour spécifier SubMenu dont vous avez besoin, par exemple .:

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

Bonne idée, bien que l'usine serait probablement plus appropriée, car beaucoup de frameworks Selenium finissent par avoir besoin d'un constructeur sans paramètre pour initialiser génériquement les webelements, attendre que la page soit chargée, etc ... mais cela fonctionnerait pour certains frameworks – mrfreester

+0

une usine ou [un modèle de constructeur] (https://en.wikipedia.org/wiki/Builder_pattern#Java). Le modèle constructeur nous permet d'éviter les dégâts du constructeur. –

+0

Aussi, si vous avez voté ma réponse, pourriez-vous expliquer pourquoi? Cela aide le PO, moi-même et n'importe qui d'autre à essayer de comprendre pourquoi il y a quelque chose qui ne va pas dans une approche particulière. – mrfreester