waitForElement с огурцом + селен - PullRequest
1 голос
/ 18 мая 2011

Привет всем, я пытаюсь исправить мои многочисленные сценарии, которые тестируют страницы с помощью расширенного AJAX и построения экрана на стороне клиента через JQuery и имеют массу проблем.

В основном у меня возникают проблемы с определением, когда выполняются определенные запросы AJAX. Я пытался просто включить задержки сна, но это плохая идея в долгосрочной перспективе. Я также попробовал пару методов, которые я нашел в Интернете, чтобы проверить, все ли вызовы AJAX выполнены, но эти методы кажутся недостаточно стабильными.

Я начал больше изучать Selenium и нашел функции waitForXXX. Взволнованный, я бросил их в свои огуречные шаги, но не повезло. Мой текущий тестовый пример - это динамически загружаемая сетка, которая получает данные через AJAX. (Плагин Jquery Datagrid). Я ищу данные, чтобы найти первую строку без заголовка, а затем щелкаю по ней. Код для щелчка элемента:

page.all(:css, "#{arg1} tr")[1].click();

Иногда это работает, часто - нет, потому что строка еще не загружена. Итак, я пытался:

waitForElementPresent("css=#{arg1} tr:nth-child(1)")

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

stack level too deep (SystemStackError)

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

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

Ответы [ 3 ]

1 голос
/ 23 мая 2011

Я склонен вызывать метод has_css?, прежде чем пытаться взаимодействовать с элементом, например,

page.should have_css("#{arg1} tr")

Capybara будет повторять попытки, пока не истечет (настраиваемое) время ожидания по умолчанию.После того, как этот шаг пройден, вы сможете щелкнуть по элементу, как и ожидалось - в противном случае шаг завершится неудачей, если элемент не появится до истечения времени ожидания.

1 голос
/ 18 мая 2011

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

When /^I wait for the AJAX call to finish$/ do
  keep_looping = true
  while keep_looping do
    sleep 0.10
    begin
      count = page.evaluate_script('window.running_ajax_calls')
      keep_looping = false if count.respond_to?(:to_i) && count.to_i == 0
    rescue => e
      raise e
    end
  end
  sleep 0.20
end

Возможно, вам придется настроить циклспать и после сна.Эти значения прекрасно работают для Mac Pro, который одновременно запускает 12 ядер тестов.При очень небольшом числе обстоятельств мы добавили дополнительное 1-секундное ожидание.

0 голосов
/ 24 мая 2011

Благодаря подсказке Алистара о page.should have_css я разработал общий пример.Это, вероятно, не сработает, если одновременно работает несколько AJAX, но для меня это довольно просто.

В моем application.html.erb я включил простой пустой div:

<div id="ready"/>

Затем в своем файле javascript, который загружается при запуске приложения, я добавил эту строку, чтобы скрыть div, когда происходит вызов AJAX.

$('#ready').ajaxStart(function(){$(this).hide();}).ajaxStop(function(){$(this).show();});

Затем в моих общих шагах для Cucumber яочень простое определение шага «Wait for AJAX»:

When /^I wait for AJAX$/ do
page.should have_css("#ready")

end

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...