В Selenium не выбирается select: webdriver + RSpec

Подскажите пожалуйста, как правильно использовать select в Selenium (желательно, но не обязательно) на Ruby.
Пример:
сайт:
Screenshot by Lightshot - список скрыт
Screenshot by Lightshot - кликнул по списку и он открыт(я сам, селениум не кликает)
код селекта:
`

Aktualität status name Verkäufe ` мой код: `element = @driver.find_element xpath: ".//*[@id='list_order']" select = Selenium::WebDriver::Support::Select.new(element) select.select_by(:value, 'name') ` так же пробовал select_by(:text, "status") пробовал кликать по element перед созданием select

так же пробовал вариант:
element = @driver.find_element xpath: ".//*[@id='list_order']" all_options = element.find_elements(:tag_name, "option") all_options.each do |option| puts "Value is: " + option.attribute("value") option.click if option.attribute("value") == "status" end
Вывод:
Value is: campaign_id Value is: status Value is: name Value is: ordered_qty_sum
Т.е. он видит value, но не кликает по option
Не могу понять, что делаю не так

Руби я не знаю, но по идее тут отсутствует клик по element в логике. Обычное с селектом делаем так:

  1. нашли сам селект
  2. кликнули по нему => появились опции
  3. нашли все опции
  4. перебрали все опции в цикле и нашли нужную
  5. кликнули по опции

@MaximZaitsev, проблема в том, что вебдрайвер не кликает по списку. Т.е. как пользователь я могу кликнуть, но вебдрайвер этого не делает.

element = @driver.find_element xpath: ".//*[@id='list_order']"  
expect(element.nil?).to eq false  # проверка, что элемент найден
element.click  # после клика список должен раскрыться, но он не раскрывается.

далее

select = Selenium::WebDriver::Support::Select.new(element)
puts select.options
select.select_by(:value, 'status')

у объекта select нет метода click, по идее метод select_by должен кликать по найденной опции.

Вот с этого момента и нужно разбираться. Клик должен быть, и как результат: открытый список. Без этого смысла в дальнейших шагах нет.

@driver.find_element(:id, "list_order").find_element(:css,"option[value='name']").click

А обязательно использовать голый Webdriver?
Почему бы не воспользоваться Capybara, где это решается очень просто.

1 лайк

Надо смотреть ситуацию. Я бы подебажил по шагам. Может не тот элемент кликается, может не успевает что-то загрузиться… В онлайне этой страницы нет ?

@LeoRush, я пока не понял, как работать с Capybara. Только сегодня с ней знакомился, пока не нашел понятного материала для чайников. В основном туториалы на уровне “вы и так все это знаете, нафига я записываю ролик, сам не знаю…”
@LeoRush, если знаете книгу/туториал/статью подскажите пожалуйста.

Как понять, какой элемент кликается? Список даже не раскрывается.

С этими кликами вообще беда. Кликнуться может, что угодно. Для начала я бы проверил, что находится именно этот элемент. Проверьте в firepath. Точно ли один такой элемент на странице?

Руби знаю хреновато, поэтому попытаюсь помочь на основе Java и общей эрудиции :slight_smile:

  1. Давайте попробуем убедиться, что наш select вообще 1 на странице. Для этого выведем
    System.out.println(driver.findElements(By.xpath(".//*[@id=‘list_order’]")))
    Ожидаемый вывод: 1. Если получили больше - значит, элементов по данному xpath более 1. Какой из них подхватит вебдрайвер - будет загадкой. Если 0 - значит, наш xpath вообще неверен. Решение: написать такой xpath, по которому данный элемент будет 1.
  2. В Вашем тексте я вижу “status”, но на скриншоте вижу “Status”. Не исключаю, что капиталайзинг сделан с помощью CSS. Но также не исключаю перепечатки руками куска DOM и связанных с этим опечаток. Мой совет - проверьте такие моменты, как большие буквы, пробелы до или после названия и т.д. Вообще, во избежание такого типа ошибок, рекомендую написать ф-цию нормализации или воспользоваться готовой, если найдёте её реализацию в рубях. Задача функции: привести к ловеркейсу + убрать пробелы и табуляции сначала и в конце стринги, подставляемой в качестве параметра.
  3. Попробуйте использовать selectByIndex вместо selectByValue. Просто для проверки, что Ваш селект вообще подхватывается корректно.
  4. Ну и напоследок: Вы вряд ли увидите в тесте последовательность действий “селект раскрылся -> выбралось значение -> селект закрылся”. Скорее сменится выбранное в селекте значение. Проверьте - может, у Вас оно выбирается нормально, но Вы этого просто не замечаете?

Надеюсь, помог :slight_smile:

1 лайк

Этот cheat sheet по-моему всё прекрасно объясняет.

Ну и документация
http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara

Давайте разбираться.
Кликнуть по элементу <OPTION> просто так нельзя.
Сначала нужно найти его родительский <SELECT>.

# encoding: utf-8

require 'selenium-webdriver'

html = <<-HTML
  data:text/html,
  <select id="list_order">
    <option value="campaign_id">Aktualität</option>
    <option value="status" selected="">status</option>
    <option value="name">name</option>
    <option value="ordered_qty_sum">Verkäufe</option>
  </select>
HTML

begin
  driver = Selenium::WebDriver.for :phantomjs
  driver.get html

  select = driver['list_order']
  option = select.first :css, 'option[value="ordered_qty_sum"]'
  option.click
ensure
  driver.close
end

Или воспользоваться таким рецептом.

Навскидку пара грязных хаков: клик джаваскриптом иногда помогает и второй - добавление/изменение атрибута selected.

Зачем же так сложно? :slight_smile:

1 лайк

Ну, это просто и действенно, если не получается по-другому, то вполне имеет право на жизнь)

P.S: вспоминаю автоматизацию под ИЕ7, когда половина кликов нативных не проходила, ИЕ не поддерживал нормальные локаторы и приходилось кликать джаваскриптом по длиннющим локаторам в таблично-сверстанном индусами приложении…

Заковыристая тема - может работать а может не работать.
Вот так работает почти всегда -
Это я открываю селект, и рандомом выбираю один из элементов

        find(:xpath,'//*[@id="client_call_time_from_4i"]').click
        find(:xpath,"//*[@id=\"client_call_time_from_4i\"]/option[#{rand(2..25)}]").click

Конкретно в вашем случае :

find(:xpath , '//select[@id="list_order"]').click
find(:xpath , '//select[@id="list_order"]/option[1]').click

(выбираю первое значение, смотря с чего оно там у вас начинается)