2017-02-09 1 views
1

J'essaie de convertir mes tests au sélénium pour utiliser le Modèle d'Objet de Page (et, par extension, @FindBy). J'ai plusieurs définitions d'objets comme celui-ci:Selenium/PageFactory: Trouver des éléments enfants en utilisant l'élément parent @FindBy?

public WebElement objectParent() { 
    return driver.findElement(By.name("parent-id")) ; 
} 

public WebElement objectChild() { 
    WebElement elem = objectParent(); 
    return elem.findElement(By.name("child-id")) ; 
} 

Converting l'objet parent à l'aide @FindBy est facile:

@FindBy(name = "parent-id") 
WebElement parentObj; 

Fondamentalement, je veux faire quelque chose comme ça, si possible (je sais que ce n » t vrai code, ceci est juste un exemple de pseudo:

@FindBy(name = "parent-id") 
WebElement parentObj; 

@FindBy(parentObj.name = "child-id") 
WebElement childObj; 

Mais est-il un moyen trop cibler l'élément enfant au sein t L'élément parent utilisant @FindBy?. Je dois le faire de cette façon car je cible des éléments spécifiques sur la page qui peuvent partager le même nom ou le même nom de classe avec d'autres éléments de la page. Merci!

+0

Voulez-vous dire les enfants de cet élément dans DOM? –

+0

Oui. J'ai ajouté un exemple de pseudo-code ci-dessus. – kroe761

+0

Est-ce que 'child' et' parent' peuvent être dans des classes différentes? –

Répondre

2

Ce que vous essayez de faire n'est pas facilement réalisable sans écrire sur mesure ElementLocatorFactory.

Tout d'abord, je recommande vraiment d'utiliser XPath. Cela rendrait beaucoup facile à attraper le:
comme ceci: @FindBy(xpath = "\\table[3]") et ...
2ème <li> dans la 3ème table comme ceci: @FindBy(xpath = "\\table[3]\li[2]").

Mais si vous voulez vraiment le faire avec des annotations @FindBy plus courtes, vous pouvez opter pour ElementLocatorFactory.

public class FindByContextModifier implements ElementLocatorFactory { 

    private final SearchContext context; 

    public FindByContextModifier(final SearchContext context) { 
     this.context = context; 
    } 

    public ElementLocator createLocator(final Field field) { 
     return new DefaultElementLocator(context, field); 
    } 
} 

classe avec un élément qui vous fournira le contexte:

public class Parent { 
    @FindBy(name = "myTable") 
    WebElement table; 

    public WebElement getTable() { 
     return this.table; 
    } 
} 

Son enfant:

public class Child { 
    @FindBy(name = "particular") 
    WebElement specialTableListElement; 
} 

Utilisation:

Parent parent = PageFactory.initElements(driver, Parent.class); 
FindByContextModifier parentContext = new FindByContextModifier(parent.getTable()); 
Child child = new Child(); 
// This will look for the name "particular" inside the element with "myTable" name 
PageFactory.initElements(parentContext, child); 
0

Vous n'avez pas besoin écrire un coutume ElemLocatorFactory, il suffit d'utiliser org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory à la place:

Parent parent = PageFactory.initElements(driver, Parent.class); 
DefaultElementLocatorFactory parentContext = new DefaultElementLocatorFactory(parent.getTable()); 
Child child = new Child(); 
PageFactory.initElements(parentContext, child);