我正在尝试在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/fxdriver@googlecode.com/components/driver_component.js:6638:在 `unknown':无法找到frame:main (硒::的webdriver ::错误:: 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/fxdriver@googlecode.com/components/driver_component.js:6638:在 `unknown':无法找到frame:main (硒::的webdriver ::错误:: NoSuchFrameError)
答案 0 :(得分:21)
<强>问题强>
问题是当你执行page.driver.browser.switch_to.frame
时,它会将页面的上下文切换到框架。针对该页面的所有操作现在实际上都是针对该帧的。因此,当您第二次切换帧时,您实际上是在“主”框架内找到“标题”框架(而不是我假设您想要的,主页面内的“标题”框架。)
解决方案 - Capybara within_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
解决方案 - 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
答案 1 :(得分:2)
我找到了解决方案。 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并接受了答案。