如何用Capybara在两帧之间切换

我尝试在2帧内做一些事情,但每当我尝试在帧之间切换时错误就会boost。 例如:

# 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/fxdriver@googlecode.com/components/driver_component.js:6638:在“未知”中:无法找到frame:main(Selenium :: webdriver的::错误:: NoSuchFrameError)

问题是什么? 也许我在这里做错了什么?

如果我改变切换帧的顺序,那么首先尝试切换到’header’然后切换到’main’帧然后相同的错误引发,除了它说这次没有’main’帧:

 # 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/fxdriver@googlecode.com/components/driver_component.js:6638:在“未知”中:无法找到frame:main(Selenium :: webdriver的::错误:: NoSuchFrameError)

问题

问题是,当你执行page.driver.browser.switch_to.frame ,它会将页面的上下文切换到框架。 针对该页面的所有操作现在实际上都是针对该帧的。 因此,当您第二次切换帧时,您实际上是在“主”帧内找到“标题”框架(而不是我假设您想要的,主页面内的“标题”框架)。

解决方案 – Capybara within_frame(推荐):

在框架内工作时,您应该使用within_framewithin_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 

解决方案 – Selenium 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 

我找到了解决方案。 within_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 

我在文件https://github.com/jnicklas/capybara/blob/master/lib/capybara/selenium/driver.rb中找到了within_frame的源代码。 从第81行开始。

编辑:当我写这个答案时,@ JustinKo回答了问题,所以两个答案都是正确的但+1并接受了他的回答。