rails 3.1, capybara-webkit, как выполнить javascript внутри ссылки? - PullRequest
2 голосов
/ 23 января 2012

Могу ли я выполнить javascript в ссылке с капибарой click_link('next_page')?

Ссылка выглядит следующим образом:

<a onclick="$('#submit_direction').attr('value', '1');$('#quizForm').submit()" id="next_page" href="#">Next Question</a>

Я читаю на capybara на github, что я могу отправить формунажав на кнопку «Отправить» следующим образом:

click_on('Submit Answer')

Но в моем случае мне нужно отправить форму, используя javascript в ссылке, так, как проверить ссылку, которая содержит javascript внутри?click_link('next_page') недостаточно?

РЕДАКТИРОВАТЬ

после установки :js=> true мой тест выглядит следующим образом:

   it "should pass when answering all correct", :js=>true  do

    login_as(student, :scope => :student)
    visit ("/student_courses")

    #page.execute_script("$('#submit_direction').attr('value', '1');$('#quizForm').submit()")

    trace "HTML:------------", page.html

  end

До: js=> правда, я мог бы посещать страницу нормально, но я заметил, что страницу нельзя посетить после: js => true, вот ошибка, которую я получил после посещения страницы:

Начал GET "/ student_courses" для 127.0.0.1 в 2012-01-23 06:29:26 +0200 (5010.7ms) ОБНОВЛЕНИЕ "студентов" SET "last_sign_in_at" = '2012-01-23 04: 29: 26.274285', "current_sign_in_at "= '2012-01-23 04: 29: 26.274285'," last_sign_in_ip "= '127.0.0.1'," current_sign_in_ip "= '127.0.0.1'," sign_in_count "= 1," updated_at "= '2012-01-23 04: 29: 26.276279 'ГДЕ "студенты". "Id" = 1 SQLite3 :: BusyException: база данных заблокирована: ОБНОВЛЕНИЕ "студентов" SET "last_sign_in_at" =' 2012-01-23 04: 29: 26.274285 ', "current_sign_in_at "= '2012-01-23 04: 29: 26.274285'," last_sign_in_ip "= '127.0.0.1'," current_sign_in_ip "= '127.0.0.1'," sign_in_count "= 1," updated_at "= '2012-01-23 04: 29: 26.276279 «ГДЕ»студенты "." id "= 1 HTML: ------------ _ _ Внутренняя ошибка сервера

Внутренняя ошибка сервера

не удалось откатить транзакцию - выполняются операторы SQLWEBrick / 1.3.1 (Ruby / 1.9.3 / 2011-10-30) на 127.0.0.1:34718

, так почему SQLite3 :: BusyException: база данных заблокированасейчас?!

Ответы [ 3 ]

8 голосов
/ 07 марта 2013

Я потратил 8 часов на решение аналогичной проблемы и нашел решение. Исправление настолько простое, что я могу плакать.

Сначала диагноз

Причина, по которой вы получаете "SQLite3::BusyException: database is locked", заключается в том, что вы запускаете асинхронный поток, а именно отправку формы, которая в итоге проигрывает гонку "запись в базу данных" в основной поток вашего теста. По сути, поскольку ваш тест уже завершен и выполняется процедура очистки базы данных «после каждого» (определенная в вашем spec_helper), действие формы только что начало пытаться запустить бизнес-логику (которая опирается на данные, которые ваш тест после каждый крючок занят уничтожением).

Скорее всего, эта проблема возникает в тестах, которые щелкают по кнопке AJAX POST, а затем завершают работу, не сообщая что-либо об изменении представления.

Второе исправление

Как оказалось, Capybara предназначена для "синхронизации" всех ваших запросов. Но только если вы неявно позволите это. Обратите внимание, что после отправки формы у вас не будет Капибары, которая будет смотреть на вашу страницу. Поэтому он думает, что вы закончили, и выводит ваши данные из области видимости (в то время как поток отправки формы висит в фоновом режиме.)

Просто добавьте следующую строку кода в конец теста, и он должен неожиданно заработать:

page.should_not have_content "dude, you forgot to assert anything about the view"

В-третьих, сделай это красиво

Не используйте execute_script. Вот для чего Капибара. Но также не полагайтесь на "click_on", потому что это не очень хорошая абстракция. Вы должны знать слишком много о его внутренностях. Вместо этого используйте CSS-селекторы так:

page.find("#submit_button").click

И еще одна вещь - ваш тест не должен пытаться манипулировать DOM. Хороший тест Selenium предполагает выполнение тех же шагов, что и обычный пользователь.

Итак, в заключение

it "should pass when answering all correct", :js => true  do
    login_as(student, :scope => :student)
    visit ("/student_courses")
    page.find(".my-js-enabled-button").click
    page.find("#submit_button").click

    # Synchronizes your view to your database state before exiting test,
    # Therefore makes sure no threads remain unfinished before your teardown.
    page.should_not have_content "dude, you forgot to expect / assert anything."
end
1 голос
/ 23 января 2012

Чтобы расширить комментарий Алекса, Capybara не будет выполнять JS, если он явно не включен для заданных тестов.

Чтобы сделать это, используйте: js => true в блоке описания или отдельном тесте, например.

describe "in such and such a context", :js => true do
   # some stuff
end
0 голосов
/ 23 января 2012

должно работать.с капибарой вы по сути протестируете свое приложение через браузер, и оно будет вести себя так же.

...