Как я могу переключаться между двумя кадрами с Capybara
Я пытаюсь сделать что-то внутри 2 кадров, но ошибка возникает каждый раз, когда я пытаюсь переключаться между кадрами.
Например:
# encoding: utf-8
require "capybara/dsl"
Capybara.run_server = false
Capybara.current_driver = :selenium
Capybara.app_host = 'https://hb.posted.co.rs/posted'
class Account
include Capybara::DSL
def check_balance
visit('/')
page.driver.browser.switch_to.frame 'main'
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
page.driver.browser.switch_to.frame 'header'
click_on 'Stanje'
end
end
account = Account.new
account.check_balance
Ошибка:
[удаленный сервер] Файл:///tmp/webdriver-profile20120810-9163-xy6dtm/extensions/[email protected]/components/driver_component.js: 6638: в `unknown ': невозможно найти фрейм: main (Селен:: WebDriver:: Error:: NoSuchFrameError)
В чем проблема? Может, я здесь что-то не так?
Если я меняю порядок переключения кадров, попробуйте сначала переключиться на "заголовок", а затем переключитесь на "основной" кадр, а затем повторите ту же ошибку, за исключением того, что в нем указано, что на этот раз нет "основного" кадра:
# encoding: utf-8
require "capybara/dsl"
Capybara.run_server = false
Capybara.current_driver = :selenium
Capybara.app_host = 'https://hb.posted.co.rs/posted'
class Account
include Capybara::DSL
def check_balance
visit('/')
page.driver.browser.switch_to.frame 'header'
click_on 'Stanje'
page.driver.browser.switch_to.frame 'main'
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
end
end
account = Account.new
account.check_balance
Ошибка:
[удаленный сервер] Файл:///tmp/webdriver-profile20120810-9247-w3o5hj/extensions/[email protected]/components/driver_component.js: 6638: в `unknown ': невозможно найти фрейм: main (Селен:: WebDriver:: Error:: NoSuchFrameError)
Ответы
Ответ 1
Проблема
Проблема заключается в том, что когда вы выполняете page.driver.browser.switch_to.frame
, он переключает контекст страницы в фрейм. Все действия против страницы теперь фактически против фрейма. Поэтому, когда вы переключаете фреймы во второй раз, вы на самом деле говорите, что находите кадр заголовка внутри основного фона (вместо того, что я предполагаю, вы хотите, кадр заголовка на главной странице).
Решение - Capybara inside_frame (рекомендуется):
При работе внутри рамки вы должны использовать метод Capybara within_frame
. Вы бы хотели:
def check_balance
visit('/')
within_frame('main'){
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
}
within_frame('header'){
click_on 'Stanje'
}
end
Решение - Селен switch_to:
Если вы хотите самостоятельно управлять кадром (т.е. не использовать встроенный метод Capybara), вы можете переключить контекст страницы обратно в браузер, а затем во второй кадр. Это будет выглядеть следующим образом. Хотя я бы предложил использовать встроенный метод Capybara.
def check_balance
visit('/')
page.driver.browser.switch_to.frame 'header'
click_on 'Stanje'
#Switch page context back to the main browser
page.driver.browser.switch_to.default_content
page.driver.browser.switch_to.frame 'main'
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
end
Ответ 2
Я нашел решение. in_frame работает как ожидалось:
# encoding: utf-8
require "capybara/dsl"
Capybara.run_server = false
Capybara.current_driver = :selenium
Capybara.app_host = 'https://hb.posted.co.rs/posted'
class Account
include Capybara::DSL
def check_balance
visit('/')
within_frame 'main' do
fill_in 'korisnik', :with => 'foo'
fill_in 'lozinka', :with => 'bar'
click_button 'Potvrda unosa'
end
within_frame 'header' do
click_on 'Stanje'
end
end
end
account = Account.new
account.check_balance
Я нашел исходный код для inside_frame в файле https://github.com/jnicklas/capybara/blob/master/lib/capybara/selenium/driver.rb. начиная с строки 81.
EDIT:
В то время как я написал этот ответ, @JustinKo ответил на вопрос, поэтому оба ответа верны, но +1 и принятый для него ответ.