Перейти к содержимому

Фотография

Проблема с поиском элементов по xpath внутри фреймов


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 22

#1 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 05 марта 2014 - 13:37

При тестировании веб репортов с использованием webDriver'a столкнулась с необычной на первый взгляд проблемой. Каждый web-репорт содержит внутри себя целую иерархию фреймов, соответственно, чтобы добраться до нужного элемента репорта (например диаграммы), необходимо подключиться к нужному фрейму. С этим проблем не возникло, фреймы прекрасно находятся как по именам и идентификаторам, так и по xpath (если имена и идентификаоры изменяются при рефреше страницы соответственно). Однако, почему-то поиск элементов внутри конкретного фрейма по xpath (кроме другого фрейма!) всегда заканчивается неудачей, при том что поиск того же элемента по id/name/tagName проходит удачно. У меня есть подозрение, что я как-то неверно указываю путь до элемента относительно корня документа (контекста?). Но почему тогда фреймы находятся с тем же подходом к написанию xpath?

Пример структуры документа и кода для поиска элемента:

<html>
 <body>
    <div>      
        ......
          <iframe id="уникальный">
             #document
              <html>
                   ....
                      <iframe id="неуникальный" title="Название">
                          #document
                           <html>
                              <body>
                                  <div>
                                       .....
                                      <div id="уникальный">
                                          <div> - тут много элементов без уникальных id и в них уже искомый элемент
                                               <rect id="неуникальный" >

пытаюсь найти rect (их может быть много, поэтому пусть будет хотя бы список)

driver.switchTo().frame(id);
WebElement fr = driver.findElement(By.xpath("//iframe[@title='Название']"));
driver.switchTo().frame(fr);
List<WebElement> els = driver.findElements(By.xpath("//rect"));

В итоге тест падает по таймауту (хотя он довольно большой выставлен) и говорит, что искомый элемент не найден. Если заменить поиск по xpath на, например,

List<WebElement> els = driver.findElements(By.tagName("rect"));

то все ищется. В чем загвоздка? ) Просто в конечном итоге нужно найти конкретный элемент rect и я пока не вижу другого способа, кроме как через xpath его уникально  определить, а тут такая засада...

 

Заранее спасибо!

 

 
 
 
 

  • 0

#2 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 05 марта 2014 - 13:48

Интересный подход. Переключаетесь в нужный фрейм, а ищете по всему драйверу.
Не проще ли искать в самом фрейме?

List<WebElement> els = fr.findElements(By.xpath(".//rect"));

Плюс вопрос: а зачем Вы переключаетесь во фрейм?
Имею в виду, почему не сделать просто:

WebElement fr = driver.findElement(By.xpath("//iframe[@title='Название']"));
List<WebElement> els = fr.findElements(By.xpath(".//rect"));

Так тоже будет работать. Отвечаю!  :biggrin:


  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#3 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 05 марта 2014 - 14:04

хм, интересное замечание. В свое время из документации я поняла, что если переключиться на конкретный фрейм (а тут меня в принципе интересует только этот фрейм и его дочерние элементы), то все дальнейшие команды и адресация будет происходить относительно этого фрема. Поправьте, если я не права). В любом случае, даже если учесть, что я, переключившись на конкретный фрейм, осуществляю поиск по всему документу, то почему все таки по тегу объекты находятся, а по xpath нет? или как раз в этом случае xpath ищет относительно всего документа (верхнего уровня), а поиск по тегу осуществляется в рамках конкретного фрейма? Это могло бы тогда объяснить проблему :)


  • 0

#4 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 05 марта 2014 - 14:04

Так тоже будет работать. Отвечаю!   :biggrin:

Интересно это с какой версии Селениума автосвитч во фреймы сделали о_О?

 

По вашей логике и так будет работать?

 

driver.findElement(By.xpath("//iframe[@title='Название']//rec"))


  • 0

#5 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 06 марта 2014 - 03:36

 

Так тоже будет работать. Отвечаю!   :biggrin:

Интересно это с какой версии Селениума автосвитч во фреймы сделали о_О?

 

По вашей логике и так будет работать?

 

driver.findElement(By.xpath("//iframe[@title='Название']//rec"))

 

XPATH ищет по HMTL-дереву. Так как iframe - тоже тег в HTML-дереве, то да, так работать должно.


  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#6 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 06:22

Ни это

driver.findElement(By.xpath("//iframe[@title='Название']//rec"))

ни это

WebElement fr = driver.findElement(By.xpath("//iframe[@title='Название']"));
List<WebElement> els = fr.findElements(By.xpath(".//rect"));

не работает))

 

пока работает только один вариант ((( с переключением на конкретный фрейм и поиск в нем элемента по имени тега... но так находятся все rect'ы, и найти среди них конкретный - оч проблематично... 


  • 0

#7 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 06:37

XPATH ищет по HMTL-дереву. Так как iframe - тоже тег в HTML-дереве, то да, так работать должно.

Ого. Круто. Выходит зря все как дурные во фреймы свичаются. Да и разработчики еще путают - какой-то switchTo().frame() реализовали.
Пойду удалю в тестах все фреймы и хитрый код на автосвич. Хотя...
Не. Надо проверить сначала наверное.




WebDriver driver = new FirefoxDriver();
		try {
			String frameLocator = "//iframe";
			String elementLocator = "//*[@class='audio-player']";
			driver.get("http://nunzioweb.com/iframes-example.htm");
			WebElement frame = driver.findElement(By.xpath(frameLocator));
			driver.switchTo().frame(frame);
			
			WebElement element = driver.findElement(By.xpath(elementLocator));
			System.out.println(element);
			
			driver.switchTo().defaultContent();
			
			frame = driver.findElement(By.xpath(frameLocator));
			try{
			element = frame.findElement(By.xpath("."+elementLocator));
			}catch (NoSuchElementException e){
				System.out.println("Oooppppss. NoSuchElement");
			}
			
			try{
				driver.findElement(By.xpath(frameLocator+"."+elementLocator));
			}catch (NoSuchElementException e){
				System.out.println("Oooppppss. NoSuchElement");
			}
					
		} finally {
			driver.quit();
		}

Output:




[[FirefoxDriver: firefox on XP (d902befc-72b1-4dd9-9942-6e60a589ec80)] -> xpath: //*[@class='audio-player']]
Oooppppss. NoSuchElement
Oooppppss. NoSuchElement

#чтотонетак
 
По теме. ТС - Вы явно что-то недоговариваете.
1. 




driver.switchTo().frame(id);
WebElement fr = driver.findElement(By.xpath("//iframe[@title='Название']"));
driver.switchTo().frame(fr);
List<WebElement> els = driver.findElements(By.xpath("//rect"));
 
В итоге тест падает по таймауту (хотя он довольно большой выставлен) и говорит, что искомый элемент не найден.

 

- findElements не может упасть по определению.
2.

Просто в конечном итоге нужно найти конкретный элемент rect и я пока не вижу другого способа, кроме как через xpath его уникально определить

Вы не показали, каким образом определяете эту самую уникальность.


  • 0

#8 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 06 марта 2014 - 06:56

#чтотонетак

:vava: "Flawless victory!" ©  :good:

 

iframe содержит свой HTML-root element.

Об этом-то я и забыл + не обратил внимание в исходном коде, данном топик-стартером.

Не работаю я с фреймами. Простите меня, пожалуйста!


  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#9 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 07:56

- findElements не может упасть по определению.

 

пардон, падало с таймаутом в случае, когда было findElement

 

Вы не показали, каким образом определяете эту самую уникальность.

 

уникальность конкретного рект определить можно по одному из его парентов, 

 

Короче, сейчас вот такой код

driver.switchTo().frame("openDocChildFrame");
WebElement fr = driver.findElement(By.xpath("//iframe[@title='Analysis Application']"));
driver.switchTo().frame(fr);
WebElement el = driver.findElement(By.xpath("//*[@data-chart-identifier='CLIENT_SIDE_CHART']"))

в итоге находит нужного парента по xpath вообще без проблем

далее, в рамках этого парента пытаюсь найти все элементы rect

вот это работает

List<WebElement> els = el.findElements(By.tagName("rect"));

а вот это НЕ работает

List<WebElement> els = el.findElements(By.xpath(".//rect"));

почему?

 


  • 0

#10 BabyRoot

BabyRoot

    Специалист

  • Members
  • PipPipPipPipPip
  • 833 сообщений


Отправлено 06 марта 2014 - 08:00

а если точку убрать?


  • 0

#11 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 08:03

А сделайте так:





System.out.println(el.getAttribute("outerHTML"));

И покажите что выведет.

 

а если точку убрать?

Тогда будет серчить по всему фрейму


  • 0

#12 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 08:15

а если точку убрать?

 

никакой разницы


  • 0

#13 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 08:24

А сделайте так:

System.out.println(el.getAttribute("outerHTML"));

 

там ооооооооочень много текста. этот элемент лишь верхушка большого айсберга, внутри которого очень много всяких элемeнтов, в том числе rect.


  • 0

#14 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 08:47

А у вас там нет таких вкусностей типа

<svg блаблабла xmlns="http://www.w3.org/2000/svg">

  • 0

#15 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 09:13

svg есть, но без xmlns="http://www.w3.org/2000/svg"

 

а может кто еще проконсультировать, почему вот это не работает (подобные примеры видела в инете и народ писал что так работает)

List<WebElement> els = driver.findElements(By.xpath(".//div[@id='*container*']"));

у меня не находит вообще ничего (( вообще какая-то засада, внутри фрейма по xpath не ищется ничего, кроме еще одного iframe. все остальное тока по имени класса, тега и т.п.


  • 0

#16 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 09:33

Кроме xmlns  других вариантов, почему работает по tagName и не работает по xpath, нету.

 

Ищем так и делаем выводы:

//*[name()='rect']

 

а может кто еще проконсультировать

Регулярные выражения это прерогатива XPath2.0, который на данный момент не поддерживается браузерами.


  • 0

#17 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 09:54

Регулярные выражения это прерогатива XPath2.0, который на данный момент не поддерживается браузерами.

 

хм, а как тогда? искать все, а затем средствами явы перебирать в поисках нужных?


  • 0

#18 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 09:56

Чойта? Изучаем пристальнее XPath1.0 и забываем про findElements

 

http://www.w3.org/TR...tring-Functions


  • 0

#19 seamcat

seamcat

    Новый участник

  • Members
  • Pip
  • 23 сообщений
  • ФИО:Юлия
  • Город:НН


Отправлено 06 марта 2014 - 10:17

пыталась юзать такой кейс

List<WebElement> els = driver.findElements(By.xpath(".//div[contains(@id, 'container')]"));

говорит, что выражение неправильное или в результате не дает элемент. чего опять не так? ))


  • 0

#20 vmaximv

vmaximv

    Опытный участник

  • Members
  • PipPipPipPip
  • 350 сообщений

Отправлено 06 марта 2014 - 10:25

Скобку закрывающую забыли. И не оффтопте - ведь проблема темы вроде как решена.


  • 0


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных