Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Не работает ByChained поиск в Selenium


(Рома Иовлев) #1

Добрый день,
Хотел узнать почему у меня в селениум не правильно работает нахождение элементов по цепочке.

Вопрос: Как сделать правильно елси это не баг, если я хочу найти корневой элемент по Xpath и остальные элементы внутри тоже искать используя Xpath.
Пример (на C# но думаю, в Java та же проблема)

var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://www.w3schools.com/html/html_tables.asp");
var el1 = driver.FindElements(By.XPath("//*[text()='HTML Table Example:']//..//table[1]//th"));
var el2 = driver.FindElements(new ByChained(By.XPath("//*[text()='HTML Table Example:']//..//table[1]"), By.TagName("th")));
var el3 = driver.FindElements(new ByChained(By.XPath("//*[text()='HTML Table Example:']//..//table[1]"), By.XPath("//th")));
var el4 = driver.FindElements(By.XPath("//*[text()='HTML Table Example:']//..//table[1]")).First().FindElements(By.XPath("//th")); 

по идее результаты должны быть одинаковые, но el3 и el4 почему-то игнорируют предыдущий “контекст” и ищут как-будто от корня. Как с этим бороться?


(Александр Таранков) #2

А каким образом задан контекст? el3 от какого элемента должен искать? От el1 или el2?

Чтобы задать контекст, нужно FindElements() вызывать не для driver, а для el1 или el2, в зависимости от того, кто из них задает контекст.

Более того, контекст надо задавать одним элементом, а не списком, то есть надо делать сначала FindElement(), который задает контекст и от него уже искать


(vmaximv) #3

Читайте спецификацию, это не проблема вебрайвера:
http://www.w3.org/TR/xpath/


(Рома Иовлев) #4

el3 в моем понимании (и то как это делается в общем то в случае el2)
Сначала ищет по By.XPath("//[text()=‘HTML Table Example:’]//…//table[1]")
и потом в найденном должен искать By.XPath("//th") (в случае el2 это работает)
el4 аналогично
сначала находит driver.FindElements(By.XPath("//
[text()=‘HTML Table Example:’]//…//table[1]")).First() - это и есть контекст
а дальше в найденном делает .FindElements(By.XPath("//th"));


(Рома Иовлев) #5

Спасибо. Надо ставить . перед вторым поиском чтобы искать в контексте By.XPath(".//th")
Правильный ответ:
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl(“http://www.w3schools.com/html/html_tables.asp”);
var el3 = driver.FindElements(new ByChained(By.XPath("//[text()=‘HTML Table Example:’]//…//table[1]"), By.XPath(".//th")));
var el4 = driver.FindElements(By.XPath("//
[text()=‘HTML Table Example:’]//…//table[1]")).First().FindElements(By.XPath(".//th"));