Захват динамического списка в массив с использованием Ruby

Я переписал этот вопрос, чтобы он стал более понятным.

Есть ли способ включить Ruby для прослушивания недавно созданного (динамического) списка выбора на веб-странице и сохранить этот список в массив?

Это будет сценарий:

  1. Пользователь выбирает номер филиала, 02
  2. Пользователь выбирает тип человека, миссионер
  3. Создается новый динамический список выбора миссионерских имен

Ruby должен был бы захватить динамически созданный список имен и сохранить их в массив. Это код на данный момент:

missionaries = Array.new

browser.select_list(:id,'branch_select').select_value('02')
browser.select_list(:id,'user_type_select').select_value('1') # 1 = Missionary
browser.select_list(:index,2).click # <-This is the dynamically created list
missionaries = browser.select_list(:index,2) # <-This is just a guess, doesn't work
puts "Missionary List: " + missionaires.to_s # <-Prints to verify list saved

На самом деле это выводит на экран:

 Missionary List: #<Watir::Select:0x147e54e>

4 ответа

Решение

Хорошо, я понял это. Список динамически заполнялся вызовом JSON. Мне нужно было сначала выяснить, что происходит, когда выбирается второй элемент списка (в данном случае, миссионеры). Как только это было выбрано, был отправлен запрос GET, а затем была получена строка JSON.

Строка должна была быть захвачена Руби с помощью библиотеки / гем open-uri. Затем проанализировали с помощью JSON Gem. После этого я использовал регулярное выражение для подсчета количества раз, когда был найден новый идентификатор. Вот новый код:

browser.select_list(:id,'branch_select').select_value('01')
browser.select_list(:id,'user_type_select').select_value('1') 
browser.select_list(:index,2).click
json = open("http://10.5.26.9:8080/MissionaryLetters/getUsers?branchID=01&userTypeID=1").read
json = JSON.parse(json)
puts json
missionaries = json.to_s.scan(/id\d/).length
puts missionaries

Это напечатало бы количество миссионеров, найденных в Отделении, в данном случае 16.

Существует много разных способов собрать информацию в массив (например, собирать и т. Д.), Вот один из них:

@myArray = Array.new

@browser.select_list(:how, what).options.each do |option|
  @myArray << option
end

Поскольку "options" дает вам все параметры в формате Array, вы также можете (и, вероятно, должны) просто сделать:

@myArray = @browser.select_list.options

Обновление на основе вашего комментария - этот код сформировал список, который вы искали, но вы не указали, что вы собираетесь с ним делать. Вывод, который вы видите - это формат списка объектов Ruby. Таким же образом, как мы перебирали элементы выше, вы можете перебирать опции вашего массива:

@num = 0
@myArray.each do |option|
   @num += 1
   puts "#{@num}. option"
end
  • Вывод будет выглядеть так:
    1. Бейсбол
    2. Баскетбол
    3. Подводное плетение корзин

Вы можете записать их в файл, консоль, сохранить их и т. Д. Это простые вещи Ruby. Надеюсь, это поможет!

Обновление № 2 на основе вашего комментария: я считаю, что вам нужно упростить, как вы думаете о приложении. Мы больше не говорим о миссионерах, баскетболах или даже о веб-страницах. Поскольку мы определили объект, к которому вам нужно получить доступ (список_выборов), и извлекли его данные в массив, теперь мы можем выполнять над ним действия.

У нас есть массив. Мы знаем, что этот массив содержит все отдельные параметры из списка select_list. Затем мы можем использовать любые методы Ruby Array, чтобы что- то сделать с этими данными. Если мы хотим общее количество вариантов:

@myArray.length
(basically, @browser.select_list.options.length)

Точно так же вы можете удалить delete_at с этим массивом, переупорядочить его содержимое или вы можете отобразить каждый элемент, как я делал в обновлении № 1.

Попробуй это:

missionaries = Array.new

browser.select_list(:id,'branch_select').select_value('02')
browser.select_list(:id,'user_type_select').select_value('1') # 1 = Missionary
browser.select_list(:index,2).click # <-Assuming this is the dynamic list
missionaries = browser.select_list(:index,2).options.collect{ |x| x.text } #Create an array containing the text of each option in the dynamic list
puts "Missionary List: " + missionaires.to_s # <-Prints to verify list saved
puts missionaires.length # <-Prints number of options in dynamic list

Обратите внимание, что это в основном предложение Адама с некоторыми уточнениями, основанными на следующих предположениях:

  1. Вас не интересует коллекция опций. Вместо этого вы хотите массив, содержащий текст динамического раскрывающегося списка.
  2. На основании вашего вывода в missionaires.to_sвы используете Watir-Webdriver, а не классический Watir. Из того, что я тестировал, OptionCollection.to_s дает разные результаты между Watir и Watir-Webdriver.

Чтобы продолжить мой комментарий, я нашел пример проблемы, которую, я думаю, вы испытываете, когда получаете количество вариантов, которые вам возвращают

б мой экземпляр браузера, потому что я ленивый.

b.goto("http://remysharp.com/wp-content/uploads/2007/01/select.html")
b.select_list(:id => "ctlJob").select("Developer")
puts b.select_list(:id => "ctlPerson").options.count
=> 3

Таким образом, в моем примере выше выводится 3 (я ожидаю 2), потому что в то время динамический список не успел обновить. Обновление содержимого часто занимает секунду или больше. Если я настрою пример, чтобы подождать, он должен (и делает) вернуть правильный номер для меня.

b.goto("http://remysharp.com/wp-content/uploads/2007/01/select.html")
b.select_list(:id => "ctlJob").select("Developer")
sleep 5
puts b.select_list(:id => "ctlPerson").options.count
=> 2

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

Но давайте посмотрим правде в глаза, сны дьявол. По моему опыту, разумно не использовать сны, кроме "у меня проблемы со временем?" отладочная ситуация.

Итак, как мы можем улучшить поведение сценария выше? Дайте ему условие подождать, прежде чем считать количество вариантов.

b.goto("http://remysharp.com/wp-content/uploads/2007/01/select.html")
original_option = b.select_list(:id => "ctlPerson").options[1].text
b.select_list(:id => "ctlJob").select("Developer")
# Pay attention to the line below
b.wait_until{b.select_list(:id => "ctlPerson").options[1].text != original_option}
puts b.select_list(:id => "ctlPerson").options.count

Таким образом, в приведенном выше примере он ждет, пока текст первого параметра не изменится, прежде чем он будет считать количество параметров в списке. Я выбрал options[1], потому что часто есть опция "Select..." по умолчанию, поэтому, если вы используете 0, во многих случаях она будет ждать, пока не истечет время ожидания.

Так что да, я думаю, что многие другие ответы на этой странице возвращали вам 0 для счетчика, потому что список выбора был действительно пуст, когда Ватир смотрел на него, и только после того, как страница динамически обновляла список.

Редактировать:

Так что для примера того, как вы могли бы сделать это на основе вашего предоставленного примера

browser.select_list(:id,'branch_select').select_value('02')
browser.select_list(:id,'user_type_select').select_value('1') # 1 = Missionary
# Im not sure you need to click here at all
browser.select_list(:index,2).click # <-This is the dynamically created list
# As the other answers were all returning zero, lets wait until the option count is higher
browser.wait_until{browser.select_list(:index,2).options.count > 0}
missionaries = browser.select_list(:index,2).options.count
# Potentially minus 1 if there's a "Select..." option
assert(missionaries == number_im_expecting)
Другие вопросы по тегам