capybara-faraday 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,89 @@
1
+ Capybara-restfulie
2
+ ==================
3
+
4
+ This gems makes it possible to use [Faraday](http://github.com/technoweenie/faraday) for remote testing.
5
+
6
+ This gem is a [Capybara](http://github.com/jnicklas/capybara) extension. The structure of the gem is taken from the work done on [Capybara-mechanize](http://github.com/jeroenvandijk/capybara-mechanize).
7
+
8
+ ### Installation
9
+
10
+ gem install capybara-faraday
11
+
12
+ ### Usage without Cucumber
13
+
14
+ require 'capybara/faraday'
15
+
16
+ ### Usage with Cucumber and tags
17
+
18
+ A @faraday tag is added to your hooks when you add the following line to your env.rb
19
+
20
+ require 'capybara/faraday/cucumber'
21
+
22
+ The following scenario will then be using the Faraday driver
23
+
24
+ @faraday
25
+ Scenario: do something with the API
26
+ Given I send and accept JSON
27
+ When I send a GET request to /users
28
+
29
+ If you want to use a specific faraday supported adapter, you need to install the dependency and then specify the tag matching it:
30
+
31
+ To use Typhoeus
32
+
33
+ @faraday_typhoeus
34
+ Scenario: do something with the API
35
+ Given I send and accept JSON
36
+ When I send a GET request to /users
37
+
38
+ To use Patron
39
+
40
+ @faraday_patron
41
+ Scenario: do something with the API
42
+ Given I send and accept JSON
43
+ When I send a GET request to /users
44
+
45
+ ### Remote testing
46
+
47
+ When you want to use this driver to test a remote application. You have to set the app_host:
48
+
49
+ Capybara.app_host = "http://www.yourapp.com"
50
+
51
+ Note that I haven't tested this case for my self yet. The Capybara tests pass for this situation though so it should work! Please provide me with feedback if it doesn't.
52
+
53
+ ## Running tests
54
+
55
+ For the tests to make sense, you need to simulate a remote server, simply add this line to your hosts file:
56
+
57
+ 127.0.0.1 capybara-testapp.heroku.com
58
+
59
+ Run bundler
60
+
61
+ bundle install
62
+
63
+ Then you are ready to run the test like so
64
+
65
+ rake spec
66
+
67
+ Caveats
68
+ -------
69
+
70
+ The focus being to provide a working driver to test APIs, not all Capybara goodness are implemented.
71
+ Everything related to submitting forms, clicking buttons, clicking checkboxes or javascript will not work with this driver.
72
+
73
+ Todo
74
+ ----
75
+
76
+ Note on Patches/Pull Requests
77
+ -----------------------------
78
+
79
+ * Fork the project.
80
+ * Make your feature addition or bug fix.
81
+ * Add tests for it. This is important so I don't break it in a
82
+ future version unintentionally.
83
+ * Commit, do not mess with rakefile, version, or history.
84
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
85
+ * Send me a pull request. Bonus points for topic branches.
86
+
87
+ Copyright
88
+ ---------
89
+ Copyright (c) 2010 Tron Jonathan and HALTER Joseph. See LICENSE for details.
@@ -0,0 +1,185 @@
1
+ require "faraday"
2
+
3
+ class Capybara::Driver::Faraday < Capybara::Driver::Base
4
+ class Node < Capybara::RackTest::Node
5
+ def click
6
+ driver.process(:get, self[:href].to_s) if self[:href] && self[:href] != ""
7
+ end
8
+ end
9
+
10
+ attr_writer :as, :with_headers, :with_params, :with_options
11
+ attr_reader :app, :adapter, :rack_server, :options, :response, :login, :password
12
+
13
+ def client
14
+ @client ||= Faraday::Connection.new{|c| c.adapter adapter}
15
+ end
16
+
17
+ def initialize(app, options={})
18
+ @app = app
19
+ @adapter = options.delete(:adapter) || :net_http
20
+ @options = {
21
+ :timeout => 3, # 3 seconds
22
+ }.merge options
23
+ @rack_server = Capybara::Server.new(@app)
24
+ @rack_server.boot if Capybara.run_server
25
+ end
26
+
27
+ def visit(url, params = {})
28
+ reset_cache
29
+ process :get, url, params
30
+ end
31
+
32
+ def get(url, params = {}, headers = {})
33
+ reset_cache
34
+ process :get, url, params, headers
35
+ end
36
+
37
+ def post(url, params = {}, headers = {})
38
+ reset_cache
39
+ process :post, url, params, headers
40
+ end
41
+
42
+ def put(url, params = {}, headers = {})
43
+ reset_cache
44
+ process :put, url, params, headers
45
+ end
46
+
47
+ def delete(url, params = {}, headers = {})
48
+ reset_cache
49
+ process :delete, url, params, headers
50
+ end
51
+
52
+ def head(url, params = {}, headers = {})
53
+ reset_cache
54
+ process :head, url, params, headers
55
+ end
56
+
57
+ def patch(url, params = {}, headers = {})
58
+ reset_cache
59
+ process :patch, url, params, headers
60
+ end
61
+
62
+ def request(url, params = {}, headers = {})
63
+ reset_cache
64
+ process :request, url, params, headers
65
+ end
66
+
67
+ def submit(method, path, attributes)
68
+ path = request.path if not path or path.empty?
69
+ process method.to_sym, path, attributes
70
+ end
71
+
72
+ def find(selector)
73
+ dom.xpath(selector).map { |node| Node.new(self, node) }
74
+ end
75
+
76
+ def html
77
+ @html ||= Nokogiri::HTML body
78
+ end
79
+
80
+ def xml
81
+ @xml ||= Nokogiri::XML body
82
+ end
83
+
84
+ def json
85
+ @json ||= Yajl::Parser.parse body
86
+ end
87
+
88
+ def body
89
+ response.body
90
+ end
91
+ alias_method :source, :body
92
+
93
+ def response_headers
94
+ response.headers["Content-Type"] = response.headers["content-type"]
95
+ response.headers
96
+ end
97
+
98
+ def status_code
99
+ response.status
100
+ end
101
+
102
+ def current_url
103
+ @current_uri.to_s
104
+ end
105
+
106
+ def reset!
107
+ @client = nil
108
+ @response = nil
109
+ @current_uri = nil
110
+ @login = nil
111
+ @password = nil
112
+ reset_cache
113
+ end
114
+
115
+ def reset_with!
116
+ @with_headers = {}
117
+ @with_params = {}
118
+ @with_options = {}
119
+ end
120
+
121
+ def as
122
+ @as ||= "application/json"
123
+ end
124
+
125
+ def with_headers
126
+ @with_headers ||= {}
127
+ end
128
+
129
+ def with_params
130
+ @with_params ||= {}
131
+ end
132
+
133
+ def with_options
134
+ @with_options ||= {}
135
+ end
136
+
137
+ def authenticate_with(login, password)
138
+ @login, @password = login, password
139
+ end
140
+
141
+ def auth?
142
+ login && password
143
+ end
144
+
145
+ def process(method, path, params = {}, headers = {})
146
+ client.basic_auth login, password if auth?
147
+ response = client.send(method) do |req|
148
+ if method == :get
149
+ req.url url(path), params
150
+ else
151
+ req.url url(path)
152
+ req.body = params
153
+ end
154
+ req.headers.merge!(headers.merge("Content-Type" => as, "Accept" => as))
155
+ req.options = options
156
+ end
157
+ @current_uri = url(path)
158
+ @response = response
159
+ end
160
+
161
+ def url(path)
162
+ rack_server.url(path)
163
+ end
164
+
165
+ def dom
166
+ content_type = response_headers["Content-Type"]
167
+ case content_type.to_s[/\A[^;]+/]
168
+ when "application/xml", "text/xml"
169
+ xml
170
+ when "text/html"
171
+ html
172
+ else
173
+ raise "Content-Type: #{content_type} is not handling xpath search"
174
+ end
175
+ end
176
+
177
+ private
178
+
179
+ def reset_cache
180
+ @xml = nil
181
+ @html = nil
182
+ @json = nil
183
+ end
184
+
185
+ end
@@ -0,0 +1,27 @@
1
+ require "capybara"
2
+
3
+ module Capybara
4
+ module Driver
5
+ autoload :Faraday, 'capybara/driver/faraday_driver'
6
+ end
7
+ end
8
+
9
+ Capybara.register_driver :faraday do |app|
10
+ Capybara::Driver::Faraday.new(app) # Net::HTTP
11
+ end
12
+
13
+ Capybara.register_driver :faraday_excon do |app|
14
+ Capybara::Driver::Faraday.new(app, :adapter => :excon)
15
+ end
16
+
17
+ Capybara.register_driver :faraday_typhoeus do |app|
18
+ Capybara::Driver::Faraday.new(app, :adapter => :typhoeus)
19
+ end
20
+
21
+ Capybara.register_driver :faraday_patron do |app|
22
+ Capybara::Driver::Faraday.new(app, :adapter => :patron)
23
+ end
24
+
25
+ Capybara.register_driver :faraday_em_http do |app|
26
+ Capybara::Driver::Faraday.new(app, :adapter => :em_http)
27
+ end
@@ -0,0 +1,26 @@
1
+ require 'capybara/faraday'
2
+
3
+ Before('@faraday') do
4
+ Capybara.current_driver = :faraday
5
+ page.driver.reset_with!
6
+ end
7
+
8
+ Before('@faraday_excon') do
9
+ Capybara.current_driver = :faraday_excon
10
+ page.driver.reset_with!
11
+ end
12
+
13
+ Before('@faraday_typhoeus') do
14
+ Capybara.current_driver = :faraday_typhoeus
15
+ page.driver.reset_with!
16
+ end
17
+
18
+ Before('@faraday_patron') do
19
+ Capybara.current_driver = :faraday_patron
20
+ page.driver.reset_with!
21
+ end
22
+
23
+ Before('@faraday_em_http') do
24
+ Capybara.current_driver = :faraday_em_http
25
+ page.driver.reset_with!
26
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Driver::Faraday do
4
+ before do
5
+ @driver = described_class.new TestApp
6
+ end
7
+
8
+ context "in remote mode" do
9
+ it_should_behave_like "driver"
10
+ it_should_behave_like "driver with header support"
11
+ it_should_behave_like "driver with status code support"
12
+ # neither supports cookies nor follows redirect automatically
13
+ end
14
+
15
+ context "basic authentication" do
16
+ subject do
17
+ app = Sinatra.new do
18
+ use Rack::Auth::Basic do |username, password|
19
+ username=="admin" && password=="secret"
20
+ end
21
+ get("/"){ "Success!" }
22
+ end
23
+ described_class.new app
24
+ end
25
+
26
+ it "allow access with right credentials" do
27
+ subject.authenticate_with "admin", "secret"
28
+ subject.get "/"
29
+ subject.status_code.should be 200
30
+ subject.source.should == "Success!"
31
+ end
32
+
33
+ it "deny access with wrong credentials" do
34
+ subject.authenticate_with "admin", "admin"
35
+ subject.get "/"
36
+ subject.status_code.should be 401
37
+ end
38
+ end
39
+
40
+ context "timeout" do
41
+ context "default" do
42
+ subject do
43
+ driver = described_class.new TestApp
44
+ end
45
+
46
+ it "is 3 seconds" do
47
+ subject.options[:timeout].should == 3
48
+ end
49
+
50
+ it "is used during request" do
51
+ expect do
52
+ subject.get "/slow_response"
53
+ end.to_not raise_error
54
+ end
55
+ end
56
+
57
+ context "accepts custom timeout" do
58
+ subject do
59
+ driver = described_class.new TestApp, timeout: 1
60
+ end
61
+
62
+ it "is stored in options" do
63
+ subject.options[:timeout].should == 1
64
+ end
65
+
66
+ it "is used during request" do
67
+ expect do
68
+ subject.get "/slow_response"
69
+ end.to raise_error Faraday::Error::TimeoutError
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ module TestSessions
4
+ Faraday = Capybara::Session.new :faraday, TestApp
5
+ end
6
+
7
+ describe Capybara::Session do
8
+ context 'with faraday driver' do
9
+ before(:all) do
10
+ @session = TestSessions::Faraday
11
+ end
12
+
13
+ after do
14
+ @session.reset_session!
15
+ end
16
+
17
+ def extract_results(session)
18
+ YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text
19
+ end
20
+
21
+ describe '#driver' do
22
+ it "should be a typhoeus driver" do
23
+ @session.driver.should be_an_instance_of Capybara::Driver::Faraday
24
+ end
25
+ end
26
+
27
+ describe '#mode' do
28
+ it "should remember the mode" do
29
+ @session.mode.should == :faraday
30
+ end
31
+ end
32
+
33
+ describe '#app' do
34
+ it "should remember the application" do
35
+ @session.app.should == TestApp
36
+ end
37
+ end
38
+
39
+ describe '#visit' do
40
+ it "should fetch a response from the driver" do
41
+ @session.visit('/')
42
+ @session.body.should include('Hello world!')
43
+ @session.visit('/foo')
44
+ @session.body.should include('Another World')
45
+ end
46
+ end
47
+
48
+ describe '#body' do
49
+ it "should return the unmodified page body" do
50
+ @session.visit('/')
51
+ @session.body.should include('Hello world!')
52
+ end
53
+ end
54
+
55
+ describe '#source' do
56
+ it "should return the unmodified page source" do
57
+ @session.visit('/')
58
+ @session.source.should include('Hello world!')
59
+ end
60
+ end
61
+
62
+ it_should_behave_like "all"
63
+ it_should_behave_like "first"
64
+ it_should_behave_like "find_button"
65
+ it_should_behave_like "find_field"
66
+ it_should_behave_like "find_link"
67
+ it_should_behave_like "find_by_id"
68
+ it_should_behave_like "has_content"
69
+ it_should_behave_like "has_css"
70
+ it_should_behave_like "has_selector"
71
+ it_should_behave_like "has_xpath"
72
+ it_should_behave_like "has_link"
73
+ it_should_behave_like "has_button"
74
+ it_should_behave_like "has_field"
75
+ it_should_behave_like "has_select"
76
+ it_should_behave_like "has_table"
77
+ it_should_behave_like "current_url"
78
+ it_should_behave_like "session without javascript support"
79
+ it_should_behave_like "session with headers support"
80
+ it_should_behave_like "session with status code support"
81
+ end
82
+ end
@@ -0,0 +1,16 @@
1
+ require 'bundler/setup'
2
+ require 'capybara'
3
+ require 'capybara/faraday'
4
+ require 'capybara/spec/test_app'
5
+ require 'capybara/spec/driver'
6
+ require 'capybara/spec/session'
7
+
8
+ alias :running :lambda
9
+
10
+ Capybara.default_wait_time = 0 # less timeout so tests run faster
11
+
12
+ RSpec.configure do |config|
13
+ config.after do
14
+ Capybara.default_selector = :xpath
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capybara-faraday
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonathan Tron
9
+ - Joseph HALTER
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2010-10-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: capybara
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 1.1.2
31
+ - !ruby/object:Gem::Dependency
32
+ name: faraday
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - '='
37
+ - !ruby/object:Gem::Version
38
+ version: 0.8.7
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - '='
45
+ - !ruby/object:Gem::Version
46
+ version: 0.8.7
47
+ - !ruby/object:Gem::Dependency
48
+ name: yajl-ruby
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rspec
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rack
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sinatra
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ description: Faraday driver for Capybara, allowing testing of REST APIs
128
+ email: team@openhood.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - lib/capybara/driver/faraday_driver.rb
134
+ - lib/capybara/faraday/cucumber.rb
135
+ - lib/capybara/faraday.rb
136
+ - spec/driver/faraday_driver_spec.rb
137
+ - spec/session/faraday_spec.rb
138
+ - spec/spec_helper.rb
139
+ - README.md
140
+ homepage: http://github.com/openhood/capybara-faraday
141
+ licenses: []
142
+ post_install_message:
143
+ rdoc_options:
144
+ - --charset=UTF-8
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 1.8.23
162
+ signing_key:
163
+ specification_version: 3
164
+ summary: Faraday driver for Capybara
165
+ test_files: []