我正在为我的Rails 3应用程序编写一些RSpec测试,并尝试从Webrat切换到Capybara。到目前为止一直很好,但应用程序使用HTTP基本身份验证来授权我的管理员用户,任何想法我怎么能用Capybara测试?
这是我目前的Webrat步骤:
it 'should authenticate for admin' do
basic_auth('user', 'secret')
visit '/admin'
response.status.should eql 200
response.status.should_not eql 401
end
我如何与Capybara一起做这件事?谢谢!
答案 0 :(得分:42)
我使用page.driver.basic_authorize(name, password)
代替
更新:
目前,在升级Capybara之后,我正在使用这一堆解决方法:
if page.driver.respond_to?(:basic_auth)
page.driver.basic_auth(name, password)
elsif page.driver.respond_to?(:basic_authorize)
page.driver.basic_authorize(name, password)
elsif page.driver.respond_to?(:browser) && page.driver.browser.respond_to?(:basic_authorize)
page.driver.browser.basic_authorize(name, password)
else
raise "I don't know how to log in!"
end
答案 1 :(得分:25)
默认的Capybara驱动程序,机架测试,有一个basic_authorize
方法(别名authorize
)用于基本HTTP身份验证,digest_authorize
用于摘要HTTP身份验证,在这里您可以找到它们:https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb
所以你可以这样做:
page.driver.browser.authorize 'login', 'password'
或者您可以为Basic HTTP Auth写一个简单的帮助:
def basic_auth(user, password)
encoded_login = ["#{user}:#{password}"].pack("m*")
page.driver.header 'Authorization', "Basic #{encoded_login}"
end
答案 2 :(得分:4)
page.driver.*
解决方案都没有为我工作。我使用的是Poltergeist,而不是Selenium,因此可能与它有关。这是做了什么工作:
RSpec.shared_context "When authenticated" do
before do
username = 'yourusername'
password = 'yourpassword'
visit "http://#{username}:#{password}@#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}/"
end
end
然后,在您的规范中:
feature "Your feature", js: true do
include_context "When authenticated"
# Your test code here...
end
答案 3 :(得分:2)
最近版本的cucumber-rails(我使用1.0.2)已经改变了。
cucumber-rails默认使用Rack / Test驱动程序,因此如果您没有更改,则以下说明将有效。
创建features / step_definitions / authorize.rb:
Given /^I am logged in as "([^\"]*)" with "([^\"]*)"$/ do |username, password|
authorize username, password
end
现在您可以在功能中使用它:
Given I am logged in as "admin" with "password"
答案 4 :(得分:1)
我不得不做这个可怕的黑客,让它的工作值得无头和javascript
Given /^I am logged in$/ do
if page.driver.respond_to?(:basic_authorize)
page.driver.basic_authorize('admin', 'password')
else
# FIXME for this to work you need to add pref("network.http.phishy-userpass-length", 255); to /Applications/Firefox.app/Contents/MacOS/defaults/pref/firefox.js
page.driver.visit('/')
page.driver.visit("http://admin:password@#{page.driver.current_url.gsub(/^http\:\/\//, '')}")
end
end
答案 5 :(得分:0)
男人,这些解决方案都不适合我。
Pistos'解决方案接近并用于js: true
的功能规范,但在无头时失败。
以下解决方案适用于 无头和js: true
规格。
<强>规格/支持/ when_authenticated.rb 强>
RSpec.shared_context 'When authenticated' do
background do
authenticate
end
def authenticate
if page.driver.browser.respond_to?(:authorize)
# When headless
page.driver.browser.authorize(username, password)
else
# When javascript test
visit "http://#{username}:#{password}@#{host}:#{port}/"
end
end
def username
# Your value here. Replace with string or config location
Rails.application.secrets.http_auth_username
end
def password
# Your value here. Replace with string or config location
Rails.application.secrets.http_auth_password
end
def host
Capybara.current_session.server.host
end
def port
Capybara.current_session.server.port
end
end
然后,在您的规范中:
feature 'User does something' do
include_context 'When authenticated'
# test examples
end