xpath для доступа к сгенерированному JS экземпляру класса

Мне нужно использовать xpath в качестве локатора для Selenium Webdriver, чтобы нажать кнопку. Он находится в диалоговом окне, которое генерируется динамически. Firebug/firepath дает ссылки на div с номерами, которые будут меняться. Я прочитал здесь много отличных советов, и я близок, но, похоже, не могу получить точную спецификацию. Мне нужен xpath для доступа к Close и Cancel:

<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<button class="ui-button ui-widget ui-state-default ui-corner-all 
ui-button-text-only  ui-state-hover" type="button" role="button" aria-disabled="false">
<span class="ui-button-text">Close</span>
</button>
<button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
type="button" role="button" aria-disabled="false">
<span class="ui-button-text">Create</span>

Нет успеха ни с одним из них:

    xpath="//*[@class='ui-button-text' and @value='Close'") 
    xpath="//span[contains(@class='ui-button-text' and @value='Close')]")

person user1083649    schedule 06.12.2011    source источник


Ответы (2)


Использование:

//span[@class = 'ui-button-text' and . = 'Close']

Они выбирают все элементы span в XML-документе со строковым значением "Close" и строковым значением атрибута class, чей атрибут class равен "ui-button-text" .

person Dimitre Novatchev    schedule 06.12.2011
comment
Огромное спасибо. Я больше не получаю недопустимую ошибку xpath, но по-прежнему не могу получить доступ к элементу. Похоже, это потому, что есть несколько диалогов с этим классом, и они закрываются, хотя активен только один. Я пытаюсь добавить что-то вроде: //[@class='ui-dialog'][style:display()!='none'] перед диапазоном... если я получу правильный синтаксис, это сработает? Другие предложения? - person user1083649; 08.12.2011
comment
@ user1083649: Является ли style:sisplay() функцией расширения, доступной для механизма XPath? Если нет (что, я думаю, так и есть), то из-за этого вы получите соответствующую ошибку. Вы должны иметь возможность однозначно идентифицировать элемент, который вы хотите выбрать, используя только его свойства и отношения только в документе XML - иначе вы не знаете, о чем спрашиваете... - person Dimitre Novatchev; 08.12.2011
comment
Еще раз спасибо - функция расширения недоступна, и ваше замечание вернуло меня на правильный путь. В итоге я использовал родного брата, чтобы добраться до нужной области: xpath=//div[@id='about-app-dialog']/../div[@class='ui-dialog-buttonpane ui-widget-content ui-helper-clearfix']/button/span[@class = 'ui-button-text' и . = 'ОК'] - person user1083649; 09.12.2011

Используйте выражение @Dimitre:

//span[@class='ui-button-text' and .='Close']

Я отвечаю, чтобы объяснить, где вы ошиблись с вашими первоначальными выражениями.

Первое выражение:

//*[@class='ui-button-text' and @value='Close'")]

При этом выбираются все элементы (*) в любом месте документа (//), у которых есть атрибут (@) с именем class, значение которого равно ui-button-text, и атрибут с именем value, значение которого равно Close. Спецификатор оси атрибута — это символ @. Это сокращение от attribute::. Следующие выражения эквивалентны:

//*[@class='ui-button-text' and @value='Close'")]
//*[attribute::class='ui-button-text' and attribute::value='Close'")] 

Приведенные выше выражения могут быть полностью расширены до:

/descendant-or-self::node()/child::*[attribute::class='ui-button-text' and 
                                     attribute::value='Close'")] 

Вкратце: постарайтесь понять синтаксические сокращения XPath при построении выражений.

Второе выражение:

//span[contains(@class='ui-button-text' and @value='Close')]

Функция XPath contains имеет следующую подпись:

boolean contains(string, string)

... и описывается в спецификации следующим образом:

Функция contains возвращает true, если первая строка аргумента содержит вторую строку аргумента, в противном случае возвращает false.

Кажется, вы пытаетесь рассматривать его как более общую магическую функцию, которая проверяет, содержит ли элемент некоторые атрибуты, но по сути это строковая функция.

Я рекомендую быстро (или не очень быстро) прочитать Рекомендацию XPath 1.0:

А пока вы будете только гадать.

person Wayne    schedule 06.12.2011
comment
Спасибо за объяснение - я прочитал рекомендации xpath, но явно изо всех сил пытаюсь применить это на практике. К сожалению, даже правильное выражение не дает мне зацепиться за веб-элемент. Я думаю, что это должно быть нажатие другой кнопки диалога, которая неактивна, и мне нужно добавить родителя к пути, чтобы он получил класс, отображение которого не равно none до спецификации, с которой помог Dimitre. Что-то вроде xpath=//[@class='ui-dialog'][style:display()!='none'] до span(@class). Это звучит на правильном пути? - person user1083649; 08.12.2011