私は自分の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
カピバラでこれを行うにはどうすればよいですか?ありがとう!
代わりに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
デフォルトのCapybaraドライバーであるrack-testには、基本HTTP認証用のbasic_authorize
メソッド(エイリアスauthorize
)とダイジェストHTTP認証用のdigest_authorize
があります。ここでそれらを見つけることができます。 https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb
だからあなたはすることができます:
page.driver.browser.authorize 'login', 'password'
または、基本HTTP認証の簡単なヘルパーを作成できます。
def basic_auth(user, password)
encoded_login = ["#{user}:#{password}"].pack("m*")
page.driver.header 'Authorization', "Basic #{encoded_login}"
end
のどれも page.driver.*
ソリューションは私のために働いた。私はSeleniumではなくPoltergeistを使用しているので、それはそれと関係があるかもしれません。うまくいったことは次のとおりです。
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
これは最近のバージョンの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"
私はそれをヘッドレスで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
男、これらの解決策のどれも私のために働いていませんでした。
Pistosのソリューションは近づき、js: true
の機能仕様で機能しましたが、ヘッドレスの場合は失敗しました。
この以下の解決策は、両方ヘッドレスおよびjs: true
仕様で機能します。
spec/support/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