2010-10-06 4 views
17

Кажется, у меня проблемы с тестированием пятнистых javascript, которые я делаю с jQuery при использовании Capybara и Selenium. Ожидаемое поведение заключается в том, что форма динамически генерируется, когда пользователь нажимает ссылку «добавить ресурс». Capybara сможет щелкнуть ссылку, но не сможет распознать новые элементы формы (т. Е. «Ресурс [имя]»).Capybara не распознает динамически добавленные элементы DOM?

Есть ли способ перезагрузить DOM для Capybara, или есть какой-то элемент этого драгоценного камня, о котором я еще не узнал?

Заранее благодарен!

== Edit ==

В настоящее время пытаются мое счастье с селена:

wait_for_element 

метод.

== Edit ==

Я постоянно получаю "неопределенный метод«wait_for_element` для класса Нилл" при попытке выполнить следующие действия:

@selenium.wait_for_element 

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

ответ

17

Я использую драйвер Webdriver для Capybara в RSpec, который я настраиваю и использую как это, и он определенно обрабатывает JS и не нуждается в перезагрузке dom. Ключ использует wait_until и условие, которое будет истинным, когда ваш ответ AJAX закончен.

before(:each) do 
    select_driver(example) 
    logout 
    login('databanks') 
end 

def select_driver(example) 
    if example.metadata[:js] 
    Capybara.current_driver = :selenium 
    else 
    Capybara.use_default_driver 
    end 
end 

it "should let me delete a scenario", :js=>true do 
    select("Mysite Search", :from=>'scenario_id') 
    wait_until{ page.has_content?('mysite_searchterms')}  
    click_on "delete"  
    wait_until{ !page.has_content?('mysite_searchterms')} 
    visit '/databanks' 
    page.should_not have_content('Mysite Search') 
    end 

Я также понял, хак, чтобы замедлить WebDriver прошлой ночью, как это, если вы хотите посмотреть вещи в Сло-мо:

#set a command delay 
    require 'selenium-webdriver' 

    module ::Selenium::WebDriver::Remote 
    class Bridge 
     def execute(*args) 
     res = raw_execute(*args)['value'] 
     sleep 0.5 
     res 
     end 
    end 
    end 

Как кто-то говорил, если вы получаете время ожидания элемента, вы можете посмотреть на это:

Capybara.default_wait_time = 10 
+0

спасибо @ebeland. теперь, после многих месяцев использования чего-то подобного в наших тестах на работе, метод 'wait_until', без сомнения, правильный путь: –

+4

' wait_until' был удален из Capybara 2.0.0. [См. Это сообщение в блоге] (http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara) –

7

Из документов водосвинку:

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

Вы можете иметь некоторые удачи увеличение времени ожидания:

Capybara.default_wait_time = 10 

Если это не поможет, то я бы encorage вас связаться кто-нибудь из проекта на GitHub, напишите в список рассылки или отправить отчет о проблеме.

+3

+1 здесь. Capybara использует это время ожидания по умолчанию для вызовов методов, таких как 'has_selector?' 'Has_css?' И так далее. Поэтому вы можете использовать эти методы, чтобы дождаться появления элемента, используя что-то вроде: 'has_css? (« A # myinput »,: visible => true)', который будет ждать, пока элемент не появится на экране перед продолжением. – bergyman

+0

где я должен положить 'Capybara.default_wait_time = 10'? –

+1

@AlexanderSupertramp в вашем 'spec/rails_helper.rb', если он у вас есть, иначе ваш' spec/spec_helper.rb'. – thomasfedb

0

Даже wait_until удален из Capybara 2.0.Тем не менее это полезно и взять код снизу:

def wait_until(delay = 1) 
seconds_waited = 0 
while ! yield && seconds_waited < Capybara.default_wait_time  
    sleep delay  
    seconds_waited += 1 
    end 
    raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield 
end 
Смежные вопросы