Odpowiedzi:
Jest tam kilka opcji. Przykładowy kod jest napisany w Javie, ale przeniesienie do innych języków powinno być proste.
WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
"return arguments[0].parentNode;", myElement);
WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = myElement.findElement(By.xpath("./.."));
WebElement
Uwaga: jak widać, w przypadku wersji JavaScript potrzebujesz rozszerzenia driver
. Jeśli nie masz do niego bezpośredniego dostępu, możesz go odzyskać za WebElement
pomocą:
WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();
By.xpath(“./..”)
aby poprawnie wejść po drzewie DOM podczas używania element.findElement
. Początkowy „./” jest wymagany do ustawienia węzła kontekstu.
Trochę więcej o XPath axes
Powiedzmy, że mamy poniższą HTML
strukturę:
<div class="third_level_ancestor">
<nav class="second_level_ancestor">
<div class="parent">
<span>Child</span>
</div>
</nav>
</div>
//span/parent::*
- zwraca dowolny element, który jest bezpośrednim rodzicem.W tym przypadku wyjście to <div class="parent">
//span/parent::div[@class="parent"]
- zwraca element rodzica tylko o dokładnym typie węzła i tylko wtedy, gdy określony predykat ma wartość True.Wynik: <div class="parent">
//span/ancestor::*
- zwraca wszystkich przodków (w tym rodzica).Wyjście: <div class="parent">
, <nav class="second_level_ancestor">
, <div class="third_level_ancestor">
...
//span/ancestor-or-self::*
- zwraca wszystkich przodków i sam bieżący element.Wyjście: <span>Child</span>
, <div class="parent">
, <nav class="second_level_ancestor">
, <div class="third_level_ancestor">
...
//span/ancestor::div[2]
- zwraca drugiego przodka (zaczynając od rodzica) typu div
.Wynik: <div class="third_level_ancestor">
Rozważmy Twój DOM jako
<a>
<!-- some other icons and texts -->
<span>Close</span>
</a>
Teraz, gdy musisz wybrać tag nadrzędny „a” na podstawie <span>
tekstu, a następnie użyj
driver.findElement(By.xpath("//a[.//span[text()='Close']]"));
Objaśnienie: Wybierz węzeł na podstawie wartości jego węzła potomnego
div
który jest ponownie zagnieżdżony w wielu elementach div, to zamiast .//span
w By.xpath("//div[.//span[text()='Close']]")
możemy użyć *//span
, będzie szukać większości nadrzędnych elementów div z danego zakresu. Teraz będzie to wyglądać takdriver.findElement(By.xpath("//div[*//span[text()='Close']]"));
Spójrz na możliwe osie XPath , których prawdopodobnie szukaszparent
. W zależności od tego, jak znajdujesz pierwszy element, możesz po prostu dostosować do tego ścieżkę xpath.
Alternatywnie możesz wypróbować składnię z podwójną kropką , ..
która wybiera rodzica bieżącego węzła.
Może to być przydatne dla kogoś innego: używając tego przykładowego kodu HTML
<div class="ParentDiv">
<label for="label">labelName</label>
<input type="button" value="elementToSelect">
</div>
<div class="DontSelect">
<label for="animal">pig</label>
<input type="button" value="elementToSelect">
</div>
Jeśli na przykład chcę wybrać element w tej samej sekcji (np. Div) jako etykietę, możesz tego użyć
//label[contains(., 'labelName')]/parent::*//input[@value='elementToSelect']
Oznacza to tylko, patrzeć na etykiecie (to może coś podobnego a
, h2
) o nazwie labelName
. Przejdź do elementu nadrzędnego tej etykiety (tj div class="ParentDiv"
.). Przeszukaj elementy potomne tego rodzica, aby znaleźć dowolny element potomny o wartości elementToSelect
. Dzięki temu nie wybierze drugiego elementToSelect
zDontSelect
div jako rodzicem.
Sztuczka polega na tym, że możesz zmniejszyć obszary wyszukiwania dla elementu, przechodząc najpierw do elementu nadrzędnego, a następnie wyszukując element potomny tego elementu nadrzędnego, którego potrzebujesz. following-sibling::h2
W niektórych przypadkach można również użyć innej składni, takiej jak . Oznacza to następny element rodzeństwa h2
. To zadziała dla elementów na tym samym poziomie, mających tego samego rodzica.
Możesz to zrobić używając / parent :: node () w xpath. Po prostu dołącz / parent :: node () do elementów potomnych xpath.
Na przykład: Niech xpath elementu potomnego to childElementXpath .
Wtedy xpath jego bezpośredniego przodka byłby childElementXpath / parent :: node () .
Xpath jego następnego przodka to childElementXpath / parent :: node () / parent :: node ()
i tak dalej..
Możesz również przejść do przodka elementu za pomocą
'childElementXpath/ancestor::*[@attr="attr_value"]'
. Byłoby to przydatne, gdy masz znany element potomny, który jest unikalny, ale ma element nadrzędny, którego nie można jednoznacznie zidentyfikować.
Za pomocą Selenium możemy wybrać tag nadrzędny w następujący sposób:
driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/../.."));
pomoże ci to znaleźć dziadka znanego elementu. Po prostu usuń jeden (/ ..), aby znaleźć bezpośredni element nadrzędny.
Lubić:
driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/..));
Jest kilka innych sposobów, aby to zaimplementować, ale dla mnie zadziałało dobrze.