Привет!
В работе внезапно застрял на одной головоломке. Помогите, пожалуйста, с поиском решения.
На странице есть блок для выбора категории. Пример DOM:
<div class="values">
<ul class="topValues">
<li>Категория 2</li>
<li>Категория 4</li>
</ul>
<ul class="allValues g-hidden">
<li>Категория 1</li>
<li>Категория 2</li>
<li>Категория 3</li>
<li>Категория 4</li>
<li>Категория 5</li>
</ul>
<a href="javascript:void(0)">Показать все</a>
</div>
По умолчанию при открытии страницы отображается список самых популярных категорий (первый ul), а второй ul список скрыт (классом g-hidden задается стиль display:none;). Если нажать на кнопку “Показать все”, то модель меняет вид:
<div class="values">
<ul class="topValues" style="display:none;">
<li>Категория 2</li>
<li>Категория 4</li>
</ul>
<ul class="allValues g-hidden" style="display:block;">
<li>Категория 1</li>
<li>Категория 2</li>
<li>Категория 3</li>
<li>Категория 4</li>
<li>Категория 5</li>
</ul>
<a href="javascript:void(0)">Скрыть</a>
</div>
Здесь с помощью атрибута style скрыт первый список ul и стал отображаться второй ul. Если теперь нажать кнопку “Скрыть”, то модель становится такой:
<div class="values">
<ul class="topValues" style="display:block;">
<li>Категория 2</li>
<li>Категория 4</li>
</ul>
<ul class="allValues g-hidden" style="display:none;">
<li>Категория 1</li>
<li>Категория 2</li>
<li>Категория 3</li>
<li>Категория 4</li>
<li>Категория 5</li>
</ul>
<a href="javascript:void(0)">Показать все</a>
</div>
Здесь атрибуты style у списков не исчезают, а лишь меняется их значение с none на block и наоборот.
Собственно, задача: XPath должен возвращать список элементов li всегда только того списка ul, который отображается в данный момент.
Как пытаюсь делать я, и какая возникла проблема:
List<WebElement> categoryList = driver.findElements(By.xpath("(//div[@class = 'values']/ul[not(contains(@style, 'none'))])[1]/li"));
Я опирался на то, что в начальном состоянии страницы у списков нет атрибута style, и решил, что с помощью not(contains()) будут выбраны оба ul, а [1] отберет только первый из них.
Также я полагал, что во втором случае not(contains()) исключит из выборки первый ul, а [1] не испортит выборку, т.к. всё равно будет отобран только один ul.
И, наконец, в третьем случае not(contains()) исключил бы второй ul, а [1] отберет оставшийся первый ul.
Но во всех трех случаях XPath возвращает только первый ul.
Вопрос: подскажите, что я делаю не так?