Как я могу облегчить проблемы со временем/AJAX, используя Capybara/Capybara Webkit/RSpec click_button и page.select?

Ради простоты я пропустил большую часть своего теста и включил только проблемный код. Это:

click_button('Search')  
page.select 'Preferred', :from => 'ticket_service_type'  

Когда я запускаю это, я получаю следующее:

Failure/Error: page.select 'Preferred', :from => 'ticket_service_type'
Capybara::ElementNotFound:
  cannot select option, no select box with id, name, or label 'ticket_service_type' found`

Запрос AJAX, вызывающий триггеры события нажатия кнопки, не имеет ничего общего с тегом select, поэтому изменение порядка в тесте приводит к тому, что тест проходит. Я знаю, что время ожидания Capybara по умолчанию составляет 2 секунды, поэтому я изменил его на 10 с помощью:

Capybara.default_wait_time = 10

Это не приводит к прохождению теста. Как я могу заставить эти два метода хорошо сочетаться друг с другом и работать в том порядке, в котором пользователь будет работать с веб-страницей?

(Если бы я разместил код из своей спецификации, держу пари, проблема была бы решена быстро.)


person Tass    schedule 25.08.2011    source источник


Ответы (2)


Из Книги об огурцах (выделено мной):

К счастью, Capybara знает, как легко справиться с этой ситуацией. Если мы добавим явный вызов для поиска, передав селектор CSS для элемента DOM на странице, которой еще не существует, Capybara немного подождет (50 мс) и повторит попытку, пока элемент не появится. Если он не появится через некоторое время (две секунды по умолчанию, хотя это настраивается), он вызовет исключение, что приведет к сбою определения шага.

Итак, пусть ваш AJAX напишет что-то в DOM, а затем найдет() это в вашем определении шага. Это не идеально. В моем случае я ввожу (скрытый) элемент DOM только для облегчения тестирования, но другого способа я не нашел.

person Chris    schedule 09.01.2012
comment
Я думаю, возможно, вы не улавливаете то, что я бросаю. ;-) Утверждение не имеет ничего общего с этим запросом AJAX. Когда страница загружается, элемент присутствует и подтверждается, что он существует. После того, как щелчок кнопки инициирован внутри спецификации, утверждение, находящее тот же элемент, никогда не пройдет. Как и любые последующие утверждения. Это моя дилемма. - person Tass; 13.01.2012
comment
Да, я не поднимаю его. Вы говорите, что #ticket_service_type существует на странице как до, так и после click_button('Search') -- но -- page.select не может найти его, если вы сначала click_button('Search')? - person Chris; 14.01.2012
comment
Совершенно верно, Крис. Не так уж и весело, если честно. Я могу выполнять действия как человек и видеть результаты, но тестирование этой штуки без головы не совсем работает. - person Tass; 14.01.2012
comment
Я не сталкивался с поведением, которое вы описываете. На ум приходят только две вещи: 1) у вас есть тег @javascript в сценарии? и 2) как выглядит содержимое save_and_open_page после click_button('Search')? Действительно ли элемент #ticket_service_type все еще находится в DOM? - person Chris; 15.01.2012
comment
Я совсем забыл о save_and_open_page! Проверим это. Спасибо за напоминание, Крис. - person Tass; 16.01.2012
comment
Я бы попробовал две вещи: 1) закомментировать весь код JS, который происходит, когда вы нажимаете «Поиск». Если это решит проблему, добавляйте обратно JS, пока не найдете точную строку, которая вызывает проблему. 2) измените click_button('Search') на что-то вроде: page.find(#btn_search).click (это просто выстрел в темноте, я бы хотел попробовать). - person Chris; 17.01.2012
comment
Ух ты. Я пропустил тег javascript в своей спецификации. Новая спецификация: pastie.org/3202056 (строка 4 — это то, на чем человек должен сосредоточиться, объявление javascript ). Большое спасибо за помощь, @Chris. - person Tass; 17.01.2012
comment
А, я использую Cucumber и ранее спрашивал, есть ли у вас тег @javascript в вашем сценарии. Думаю, это эквивалент RSpec. Рад, что разобрался. - person Chris; 17.01.2012
comment
Я тоже, @Chris. Я должен тебе пиво. - person Tass; 17.01.2012

Обязательно добавьте :js => true к интеграционным тестам, которые зависят от JavaScript.

person Tass    schedule 30.12.2013