Selenium, Java: выбрать элемент выпадающего списка, если на странице он представлен одновременно select и ul li, и Selenium не видит их оба

350
04 февраля 2019, 00:50

Использую Selenium, java. Задача: получить список элементов для двух выпадающих списков и кликнуть на один из полученных элементов в обоих списках. Однако если с первым списком select name="ppw-expirationDate_month" никаких проблем не возникло, выбрала нужную опцию с помощью класса Select, то со вторым возникла странная проблема: сначала показалось, что он точно так же, как и первый, представлен селектом: select name="ppw-expirationDate_year", однако при попытке обработать его так же, как и первый, я получила ошибку "Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element:" При этом при наведении на option-ы для этого списка в Инструментах разработчика они не выделялись в открытом списке.

<div class="a-section a-spacing-none pmts-expiry pmts-date-width"> 
      <label for="pp-YP-43" id="pp-YP-44" class="a-form-label">Expiration date</label> 
      <span class="a-dropdown-container"> 
      <select name="ppw-expirationDate_month" autocomplete="off" data-a-native-class="pmts-native-dropdown" id="pp-YP-43" tabindex="-1" class="a-native-dropdown pmts-native-dropdown"> 
        <option value="1" selected="">01</option> 
        <option value="2">02</option> 
        <option value="3">03</option> 
        <option value="4">04</option> 
        <option value="5">05</option> 
        <option value="6">06</option> 
        <option value="7">07</option> 
        <option value="8">08</option> 
        <option value="9">09</option> 
        <option value="10">10</option> 
        <option value="11">11</option> 
        <option value="12">12</option> 
      </select> 
      <span tabindex="-1" id="pp-YP-46" data-pmts-component-id="pp-YP-29" data-a-class="pmts-expiry-month pmts-portal-component pmts-portal-components-pp-YP-29" class="a-button a-button-dropdown pmts-expiry-month pmts-portal-component pmts-portal-components-pp-YP-29" style="min-width: 0.166667%;"> 
      <span class="a-button-inner"> 
      <span class="a-button-text a-declarative" data-action="a-dropdown-button" role="button" tabindex="0" aria-hidden="true"> 
      <span class="a-dropdown-prompt">03</span> 
      </span> 
      <i 
        class="a-icon a-icon-dropdown"></i> 
      </span> 
      </span> 
      </span> 
      <span class="a-letter-space"></span> 
      <span class="a-dropdown-container"> 
        <select name="ppw-expirationDate_year" autocomplete="off" data-a-native-class="pmts-native-dropdown" id="pp-YP-45" tabindex="-1" class="a-native-dropdown pmts-native-dropdown"> 
          <option value="2018" selected="">2018</option> 
          <option value="2019">2019</option> 
          <option value="2020">2020</option> 
          <option value="2021">2021</option> 
          <option value="2022">2022</option> 
          <option value="2023">2023</option> 
          <option value="2024">2024</option> 
          <option value="2025">2025</option> 
          <option value="2026">2026</option> 
        </select> 
        <span tabindex="-1" id="pp-YP-47" data-pmts-component-id="pp-YP-29" data-a-class="pmts-expiry-year pmts-portal-component pmts-portal-components-pp-YP-29" class="a-button a-button-dropdown pmts-expiry-year pmts-portal-component pmts-portal-components-pp-YP-29" style="min-width: 0%;"> 
        <span class="a-button-inner"> 
        <span class="a-button-text a-declarative" data-action="a-dropdown-button" role="button" tabindex="0" aria-hidden="true"> 
        <span class="a-dropdown-prompt">2018</span> 
        </span> 
        <i 
          class="a-icon a-icon-dropdown"></i> 
          </span> 
          </span> 
          </span> 
    </div>

При дальнейшем рассмотрении страницы обнаружила, что на ней есть дублирующий список для этой кнопки, и его можно найти, если открыть список и проинспектировать элементы внутри, но представлен он на странице ниже список ul li:

<div class="a-popover a-dropdown a-dropdown-common a-declarative" data-action="a-popover-a11y" id="a-popover-3" aria-hidden="false" style="z-index: 299; visibility: visible; top: 129px; left: 401.25px;"><span tabindex="0" role="dialog" class="a-popover-start a-popover-a11y-offscreen"></span> 
  <div class="a-popover-wrapper"> 
    <div class="a-popover-inner" style="height: auto; overflow-y: auto; min-width: 71px; width: auto;"> 
      <ul tabindex="-1" class="a-nostyle a-list-link" role="listbox" aria-multiselectable="false"> 
        <li tabindex="0" role="option" aria-checked="true" aria-labelledby="pp-YP-45_0" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2018&quot;}" id="pp-YP-45_0" class="a-dropdown-link a-active">2018</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_1" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2019&quot;}" id="pp-YP-45_1" class="a-dropdown-link">2019</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_2" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2020&quot;}" id="pp-YP-45_2" class="a-dropdown-link">2020</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_3" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2021&quot;}" id="pp-YP-45_3" class="a-dropdown-link">2021</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_4" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2022&quot;}" id="pp-YP-45_4" class="a-dropdown-link">2022</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_5" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2023&quot;}" id="pp-YP-45_5" class="a-dropdown-link">2023</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_6" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2024&quot;}" id="pp-YP-45_6" class="a-dropdown-link">2024</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_7" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2025&quot;}" id="pp-YP-45_7" class="a-dropdown-link">2025</a></li> 
        <li tabindex="0" role="option" aria-labelledby="pp-YP-45_8" class="a-dropdown-item"><a tabindex="-1" href="javascript:void(0)" data-value="{&quot;stringVal&quot;:&quot;2026&quot;}" id="pp-YP-45_8" class="a-dropdown-link">2026</a></li> 
    </div> 
  </div><span tabindex="0" class="a-popover-end a-popover-a11y-offscreen"></span></div>

И вот если наводиться на элементы в нем в Инструментах разработчика, то они выделяются на странице. Попыталась получить список элементов следующим образом:

driver.findElement(By.xpath("//select[@name="ppw-expirationDate_year"]/following-sibling::span")).click();
    WebElement ulElement = driver.findElement(By.xpath("\"//ul[@role=\"listbox\"]"));
    List<WebElement> listbox = ulElement.findElements(By.tagName("li"));

Но получаю ошибку Exception in thread "main" org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression "//ul[@role="listbox"] because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '"//ul[@role="listbox"]' is not a valid XPath expression.

С первым списком, с которым не было проблем, справилась так:

WebElement selectMonth = driver.findElement(By.xpath("//select[@name=\"ppw-expirationDate_month\"]"));
    Select select = new Select(selectMonth);
    select.selectByVisibleText("03");

Что я делаю не так со вторым списком и почему на странице вообще он представлен одновременно селектом и ul li?

Answer 1

Решение всего:

WebDriverWait ulWait = new WebDriverWait(driver, 30);
    ulWait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[@role=\"listbox\"]")));
    driver.findElement(By.linkText("2020")).click();
READ ALSO
extends не работает

extends не работает

Ругается ошибкой на extends, по книжке всё должно работатьВ чём проблема?

274
Lombok ошибка сборки при помощи Gradle в Docker

Lombok ошибка сборки при помощи Gradle в Docker

Сборка приложения на машине происходит успешно, а вот в Docker контейнере нетСразу напрашивается вопрос, чего-то нахватает, но чего?

201
Двумерный массив ArrayList

Двумерный массив ArrayList

Использовал для своего кода стандартный массив по типу:

189
Преобразование в Map c помощью stream api

Преобразование в Map c помощью stream api

Есть список logList состоящий из элементов класса

233