2012-05-09 7 views
34

Używam selenu do przetestowania mojej aplikacji internetowej i mogę z powodzeniem znaleźć znaczniki za pomocą By.xpath. Jednak od czasu do czasu muszę znaleźć węzły potomne w tym węźle.Lokalizowanie węzłów podrzędnych WebElements w selenach

Przykład:

<div id="a"> 
    <div> 
     <span /> 
     <input /> 
    </div> 
</div> 

mogę zrobić:

WebElement divA = driver.findElement(By.xpath("//div[@id='a']")) 

Ale teraz muszę znaleźć wejście, więc mogłem zrobić:

driver.findElement(By.xpath("//div[@id='a']//input")) 

Jednak w tym momencie kod I mam tylko divA, nie jego xpath już więcej ... Chciałbym zrobić coś takiego to:

WebElement input = driver.findElement(divA, By.xpath("//input")); 

Ale taka funkcja nie istnieje. Czy mogę to zrobić tak czy inaczej?

BTW: Czasami muszę znaleźć DIV, który ma określony węzeł. Jak mogę zapytać w xpath o "div-tag, który zawiera rozpiętość z tekstem" hello world "?

Odpowiedz

64

Według JavaDocs, można to zrobić:

WebElement input = divA.findElement(By.xpath(".//input")); 

Jak mogę zapytać w XPath za "div-tag, który zawiera rozpiętość z tekstem 'Hello World'" ?

WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]")); 

The XPath spec jest zaskakująco dobry odczyt na ten temat.

+0

Wielkie dzięki. Nie wiedziałem jeszcze, że mogę użyć xpaths wewnątrz '[]' wewnątrz xpaths ... –

+2

najnowszą wersję specyfikacji XPath można znaleźć [tutaj] (https://www.w3.org/TR/xpath- 3/# abbrev) –

+0

po prostu piękne! – angryip

0

Też znalazłem się w podobnej sytuacji kilka tygodni temu. Możesz to również zrobić, tworząc niestandardowy ElementLocatorFactory (lub po prostu przekazując divA do DefaultElementLocatorFactory), aby sprawdzić, czy jest to dziecko pierwszego div - wtedy wywołasz odpowiednią metodę PageFactory initElements.

W tym przypadku, jeśli tak, co następuje:

PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance)); 
// The Page Object instance would then need a WebElement 
// annotated with something like the xpath above or @FindBy(tagName = "input") 
-1

toString() metoda selen poprzez Klasy produkuje coś podobnego "By.xpath: // XpathFoo"

Można więc wziąć podciąg zaczynając okrężnicy z mniej więcej tak:

String selector = divA.toString().substring(s.indexOf(":") + 2); 

z tym, można znaleźć elementu wewnątrz innego elementu z tym:

WebElement input = driver.findElement(By.xpath(selector + "//input")); 

Zaleta: Musisz przeszukać tylko raz rzeczywistą SUT, aby uzyskać premię w wydajności.

Wada: brzydkie ... jeśli chcesz wyszukać element nadrzędny za pomocą selektora css i użyć xpath dla swoich dzieci, musisz sprawdzić typy przed połączeniem ... W tym przypadku rozwiązanie Slanec (przy użyciu findElement na WebElement) jest znacznie lepsze.

-2

Na znalezienie wszystkich childNodes można użyć poniższy urywek

List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*")); 

     for (WebElement e : childs) 
     { 
      System.out.println(e.getTagName()); 
     } 

Zauważ, że to daje wszystkie węzły dziecko na tym samym poziomie -> jak jeśli masz struktura tak:

<Html> 
<body> 
<div> ---suppose this is current WebElement 
    <a> 
    <a> 
     <img> 
      <a> 
     <img> 
    <a> 

Podam tutaj tylko nazwy znaczników z 3 znacznikami. Jeśli chcesz wszystkie elementy potomne Elements rekursywnie, możesz zastąpić powyższy kod przez MyCurrentWebElement.findElements (By.xpath (".//*"));

Nadzieja, która pomaga!

1

Jeśli musisz poczekać, jest metoda presenceOfNestedElementLocatedBy, która pobiera element "macierzysty" i lokalizator, np. a By.xpath:

WebElement subNode = new WebDriverWait(driver,10).until(
    ExpectedConditions.presenceOfNestedElementLocatedBy(
     divA, By.xpath(".//div/span") 
    ) 
); 
Powiązane problemy