mechwarrior 0.0.1 → 0.0.2

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,50 @@
1
+ require 'mechanize'
2
+
3
+ class Capybara::Mechanize::Browser
4
+ attr_reader :agent
5
+
6
+ def initialize
7
+ @agent = Mechanize.new do |config|
8
+ config.follow_meta_refresh = true
9
+ config.redirection_limit = 5
10
+ end
11
+ end
12
+
13
+ def get(url)
14
+ referrer = been_somewhere? ? self.url : nil
15
+ @agent.get(url, [], referrer)
16
+ end
17
+
18
+ def post(url); @agent.post(url); end
19
+ def put(url); @agent.get(url); end
20
+ def delete(url); @agent.delete(url); end
21
+ def submit(form); @agent.submit(form); end
22
+
23
+ def uri
24
+ been_somewhere? ? @agent.current_page.uri : nil
25
+ end
26
+
27
+ def url
28
+ uri.nil? ? '' : uri.to_s
29
+ end
30
+
31
+ def headers
32
+ been_somewhere? ? @agent.current_page.header : {}
33
+ end
34
+
35
+ def status_code
36
+ been_somewhere? ? @agent.current_page.code.to_i : nil
37
+ end
38
+
39
+ def dom
40
+ been_somewhere? ? @agent.current_page.root : Nokogiri::HTML(nil)
41
+ end
42
+
43
+ def source
44
+ been_somewhere? ? @agent.current_page.body : ''
45
+ end
46
+
47
+ def been_somewhere?
48
+ !@agent.current_page.nil?
49
+ end
50
+ end
@@ -1,5 +1,3 @@
1
- require 'mechanize'
2
-
3
1
  class Capybara::Mechanize::Driver < Capybara::Driver::Base
4
2
  attr_reader :app, :rack_server, :options
5
3
 
@@ -13,48 +11,37 @@ class Capybara::Mechanize::Driver < Capybara::Driver::Base
13
11
  end
14
12
 
15
13
  def browser
16
- unless @browser
17
- @browser = Mechanize.new
18
- @browser.follow_meta_refresh
19
- end
20
- @browser
14
+ @browser ||= Capybara::Mechanize::Browser.new
21
15
  end
22
16
 
23
17
  def visit(path)
24
18
  browser.get(url(path))
25
19
  end
26
20
 
27
- def follow(_method, path, attributes={})
28
- return if is_javascript_hashy_path?(path)
29
-
30
- absolute_url = make_absolute_url(path)
31
-
32
- if _method == :get
33
- browser.get(absolute_url, [], self.current_url)
34
- else
35
- browser.send(_method, absolute_url, attributes)
36
- end
21
+ def follow(_method, path)
22
+ return if is_fragment?(path)
23
+ browser.send(_method, make_absolute_url(path))
37
24
  end
38
-
39
- def submit(form_node, button_node)
40
- form = Capybara::Mechanize::Form.new(form_node, browser)
41
- button = Mechanize::Form::Button.new(button_node)
42
-
43
- form.action = form.action || self.current_url
44
-
45
- browser.submit(form, button)
25
+
26
+ def get(url); follow(:get, url); end
27
+ def post(url); follow(:post, url); end
28
+ def put(url); follow(:put, url); end
29
+ def delete(url); follow(:delete, url); end
30
+
31
+ def submit(form)
32
+ browser.submit(form)
46
33
  end
47
34
 
48
35
  def current_url
49
- current_page? ? current_page.uri.to_s : ''
36
+ browser.url
50
37
  end
51
38
 
52
39
  def response_headers
53
- current_page? ? current_page.header : {}
40
+ browser.headers
54
41
  end
55
42
 
56
43
  def status_code
57
- current_page? ? current_page.code.to_i : nil
44
+ browser.status_code
58
45
  end
59
46
 
60
47
  def find(selector)
@@ -62,12 +49,12 @@ class Capybara::Mechanize::Driver < Capybara::Driver::Base
62
49
  end
63
50
 
64
51
  def source
65
- current_page? ? current_page.body : ''
52
+ browser.source
66
53
  end
67
54
  alias :body :source
68
55
 
69
56
  def dom
70
- current_page? ? current_page.root : Nokogiri::HTML(nil)
57
+ browser.dom
71
58
  end
72
59
 
73
60
  def reset!
@@ -75,44 +62,36 @@ class Capybara::Mechanize::Driver < Capybara::Driver::Base
75
62
  end
76
63
 
77
64
  private
78
-
79
- def url(path)
80
- rack_server.url(path)
81
- end
82
-
83
- def current_page
84
- browser.current_page
85
- end
86
-
87
- def current_page?
88
- !browser.current_page.nil?
89
- end
90
-
91
- def current_page_is_external?
92
- current_page.uri.host != (Capybara.app_host || rack_server.host)
93
- end
94
-
95
- def request_path
96
- browser.current_page.uri.path
97
- end
98
-
65
+
99
66
  def make_absolute_url(path)
100
67
  return path unless URI.parse(path).relative?
101
68
 
102
- path = "#{ request_path }#{ path }" if is_query_string?(path)
69
+ path = "#{ browser.uri.path }#{ path }" if is_query_string?(path)
103
70
 
104
- if current_page? && current_page_is_external?
105
- current_page.uri.merge(path).to_s
71
+ if browser.been_somewhere? && current_page_is_external?
72
+ external_url(path)
106
73
  else
107
74
  url(path)
108
75
  end
109
76
  end
110
77
 
78
+ def external_url(path)
79
+ browser.uri.merge(path).to_s
80
+ end
81
+
82
+ def url(path)
83
+ rack_server.url(path)
84
+ end
85
+
86
+ def current_page_is_external?
87
+ browser.uri.host != (rack_server.host || URI.parse(Capybara.app_host).host)
88
+ end
89
+
111
90
  def is_query_string?(path)
112
- path.start_with?('?')
91
+ browser.been_somewhere? && path.start_with?('?')
113
92
  end
114
93
 
115
- def is_javascript_hashy_path?(path)
116
- path.gsub(/^#{request_path}/, '').start_with?('#')
94
+ def is_fragment?(path)
95
+ browser.been_somewhere? && path.gsub(/^#{browser.uri.path}/, '').start_with?('#')
117
96
  end
118
97
  end
@@ -2,42 +2,42 @@ require 'mechanize'
2
2
 
3
3
  class Capybara::Mechanize::Form < Mechanize::Form
4
4
 
5
- def initialize(node, mech=nil, page=nil)
6
- super(strip_disabled_nodes(node), mech, page)
7
- normalize_uploads
5
+ def initialize(driver, form_node)
6
+ @driver = driver
7
+ form_node = form_node.clone
8
+
9
+ form_node.search('*[disabled=disabled]').remove
10
+
11
+ super(form_node, @driver.browser.agent)
8
12
  end
9
13
 
10
- private
11
-
12
- def strip_disabled_nodes(form_node)
13
- stripped_form_node = form_node.clone
14
- stripped_form_node.search('*[disabled=disabled]').remove
15
- stripped_form_node
16
- end
17
-
18
- def normalize_uploads
19
- if self.enctype.downcase =~ /^multipart\/form-data/
20
- assign_files_to_uploads
21
- else
22
- create_dummy_fields
23
- end
24
- end
25
-
26
- def assign_files_to_uploads
27
- self.file_uploads.each do |upload|
28
- file_path = upload.node["value"]
29
- upload.file_name = file_path if !file_path.nil? && file_path != ''
30
- end
14
+ def submit(button_node)
15
+ button = Mechanize::Form::Button.new(button_node)
16
+ self.action ||= @driver.current_url
17
+
18
+ self.normalize_uploads!
19
+ self.add_button_to_query(button)
20
+
21
+ @driver.submit(self)
31
22
  end
32
23
 
33
- def create_dummy_fields
24
+ protected
25
+
26
+ def normalize_uploads!
34
27
  self.file_uploads.each do |upload|
35
28
  file_path = upload.node["value"]
29
+ next if file_path.nil? || file_path == ''
36
30
 
37
- if !file_path.nil? && file_path != ''
31
+ if self.multipart?
32
+ upload.file_name = file_path
33
+ else
38
34
  new_field = Mechanize::Form::Field.new(upload.node, File.basename(file_path))
39
35
  self.fields << new_field
40
36
  end
41
- end
37
+ end
42
38
  end
39
+
40
+ def multipart?
41
+ !!(self.enctype.downcase =~ /^multipart\/form-data/)
42
+ end
43
43
  end
@@ -1,100 +1,11 @@
1
- class Capybara::Mechanize::Node < Capybara::Driver::Node
2
- def text
3
- native.text
4
- end
5
-
6
- def [](name)
7
- string_node[name]
8
- end
9
-
10
- def value
11
- string_node.value
12
- end
13
-
14
- def set(value)
15
- if tag_name == 'input' and type == 'radio'
16
- other_radios_xpath = XPath.generate { |x| x.anywhere(:input)[x.attr(:name).equals(self[:name])] }.to_s
17
- driver.dom.xpath(other_radios_xpath).each { |node| node.remove_attribute("checked") }
18
- native['checked'] = 'checked'
19
- elsif tag_name == 'input' and type == 'checkbox'
20
- if value && !native['checked']
21
- native['checked'] = 'checked'
22
- elsif !value && native['checked']
23
- native.remove_attribute('checked')
24
- end
25
- elsif tag_name == 'input'
26
- if (type == 'text' || type == 'password') && self[:maxlength]
27
- value = value[0...self[:maxlength].to_i]
28
- end
29
- native['value'] = value.to_s
30
- elsif tag_name == "textarea"
31
- native.content = value.to_s
32
- end
33
- end
34
-
35
- def select_option
36
- if select_node['multiple'] != 'multiple'
37
- select_node.find(".//option[@selected]").each { |node| node.native.remove_attribute("selected") }
38
- end
39
- native["selected"] = 'selected'
40
- end
41
-
42
- def unselect_option
43
- if select_node['multiple'] != 'multiple'
44
- raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
45
- end
46
- native.remove_attribute('selected')
47
- end
48
-
1
+ class Capybara::Mechanize::Node < Capybara::RackTest::Node
49
2
  def click
50
3
  if tag_name == 'a'
51
4
  method = self["data-method"] || :get
52
5
  driver.follow(method, self[:href].to_s)
53
- elsif (tag_name == 'input' && %w(submit image).include?(type)) || ((tag_name == 'button') && type.nil? || type == "submit")
54
- driver.submit(form, self)
6
+ elsif (tag_name == 'input' and %w(submit image).include?(type)) or
7
+ ((tag_name == 'button') and type.nil? or type == "submit")
8
+ Capybara::Mechanize::Form.new(driver, form).submit(self)
55
9
  end
56
- end
57
-
58
- def tag_name
59
- native.node_name
60
- end
61
-
62
- def visible?
63
- string_node.visible?
64
- end
65
-
66
- def checked?
67
- string_node.checked?
68
- end
69
-
70
- def selected?
71
- string_node.selected?
72
- end
73
-
74
- def path
75
- native.path
76
- end
77
-
78
- def find(locator)
79
- native.xpath(locator).map { |n| self.class.new(driver, n) }
80
- end
81
-
82
- private
83
-
84
- def string_node
85
- @string_node ||= Capybara::Node::Simple.new(native)
86
- end
87
-
88
- # a reference to the select node if this is an option node
89
- def select_node
90
- find('./ancestor::select').first
91
- end
92
-
93
- def type
94
- native[:type]
95
- end
96
-
97
- def form
98
- native.ancestors('form').first
99
- end
10
+ end
100
11
  end
@@ -2,6 +2,7 @@ require 'capybara'
2
2
 
3
3
  module Capybara
4
4
  module Mechanize
5
+ autoload :Browser, 'capybara/mechanize/browser'
5
6
  autoload :Driver, 'capybara/mechanize/driver'
6
7
  autoload :Node, 'capybara/mechanize/node'
7
8
  autoload :Form, 'capybara/mechanize/form'
@@ -1,3 +1,3 @@
1
1
  module Mechwarrior
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -12,6 +12,12 @@ describe Capybara::Mechanize::Driver do
12
12
  end.should raise_error(ArgumentError)
13
13
  end
14
14
 
15
+ it "should not follow more than 5 redirects" do
16
+ running do
17
+ @driver.visit('/redirect/6/times')
18
+ end.should raise_error(Mechanize::RedirectLimitReachedError)
19
+ end
20
+
15
21
  it_should_behave_like "driver"
16
22
  it_should_behave_like "driver with header support"
17
23
  it_should_behave_like "driver with status code support"
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,7 @@ require "bundler/setup"
5
5
 
6
6
  require 'rspec'
7
7
  require 'mechwarrior'
8
+ require 'mechanize'
8
9
 
9
10
  RSpec.configure do |config|
10
11
  config.before do
metadata CHANGED
@@ -1,116 +1,113 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mechwarrior
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
4
5
  prerelease:
5
- version: 0.0.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Chris Lowder
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-07-25 00:00:00 +01:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-01 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: capybara
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2168495700 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
24
21
  version: 1.0.0
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: mechanize
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2168495700
25
+ - !ruby/object:Gem::Dependency
26
+ name: mechanize
27
+ requirement: &2168494920 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
29
+ requirements:
33
30
  - - ~>
34
- - !ruby/object:Gem::Version
31
+ - !ruby/object:Gem::Version
35
32
  version: 2.0.0
36
33
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: sinatra
40
34
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2168494920
36
+ - !ruby/object:Gem::Dependency
37
+ name: sinatra
38
+ requirement: &2168494200 !ruby/object:Gem::Requirement
42
39
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
46
43
  version: 0.9.4
47
44
  type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: rspec
51
45
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2168494200
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &2168493580 !ruby/object:Gem::Requirement
53
50
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
57
54
  version: 2.0.0
58
55
  type: :development
59
- version_requirements: *id004
60
- - !ruby/object:Gem::Dependency
61
- name: launchy
62
56
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *2168493580
58
+ - !ruby/object:Gem::Dependency
59
+ name: launchy
60
+ requirement: &2168493000 !ruby/object:Gem::Requirement
64
61
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
68
65
  version: 0.3.5
69
66
  type: :development
70
- version_requirements: *id005
71
- - !ruby/object:Gem::Dependency
72
- name: yard
73
67
  prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *2168493000
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: &2168491920 !ruby/object:Gem::Requirement
75
72
  none: false
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
79
76
  version: 0.5.8
80
77
  type: :development
81
- version_requirements: *id006
82
- - !ruby/object:Gem::Dependency
83
- name: fuubar
84
78
  prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
79
+ version_requirements: *2168491920
80
+ - !ruby/object:Gem::Dependency
81
+ name: fuubar
82
+ requirement: &2155958500 !ruby/object:Gem::Requirement
86
83
  none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
90
87
  version: 0.0.1
91
88
  type: :development
92
- version_requirements: *id007
93
- - !ruby/object:Gem::Dependency
94
- name: cucumber
95
89
  prerelease: false
96
- requirement: &id008 !ruby/object:Gem::Requirement
90
+ version_requirements: *2155958500
91
+ - !ruby/object:Gem::Dependency
92
+ name: cucumber
93
+ requirement: &2155957920 !ruby/object:Gem::Requirement
97
94
  none: false
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- version: "0.10"
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0.10'
102
99
  type: :development
103
- version_requirements: *id008
100
+ prerelease: false
101
+ version_requirements: *2155957920
104
102
  description: A Mechanize based Capybara driver.
105
- email:
103
+ email:
106
104
  - clowder@gmail.com
107
105
  executables: []
108
-
109
106
  extensions: []
110
-
111
- extra_rdoc_files:
107
+ extra_rdoc_files:
112
108
  - README.md
113
- files:
109
+ files:
110
+ - lib/capybara/mechanize/browser.rb
114
111
  - lib/capybara/mechanize/driver.rb
115
112
  - lib/capybara/mechanize/form.rb
116
113
  - lib/capybara/mechanize/node.rb
@@ -122,34 +119,31 @@ files:
122
119
  - spec/mechanize_session_spec.rb
123
120
  - spec/spec_helper.rb
124
121
  - README.md
125
- has_rdoc: true
126
122
  homepage: http://github.com/clowder/mechwarrior
127
123
  licenses: []
128
-
129
124
  post_install_message:
130
- rdoc_options:
125
+ rdoc_options:
131
126
  - --main
132
127
  - README.md
133
- require_paths:
128
+ require_paths:
134
129
  - lib
135
- required_ruby_version: !ruby/object:Gem::Requirement
130
+ required_ruby_version: !ruby/object:Gem::Requirement
136
131
  none: false
137
- requirements:
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- version: "0"
141
- required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
137
  none: false
143
- requirements:
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- version: "0"
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
147
142
  requirements: []
148
-
149
143
  rubyforge_project:
150
- rubygems_version: 1.6.2
144
+ rubygems_version: 1.8.7
151
145
  signing_key:
152
146
  specification_version: 3
153
- summary: A Mechanize based Capybara driver, designed to get round the rack-test limitation of not being able to visit external (i.e. not the app your testing) websites.
147
+ summary: A Mechanize based Capybara driver, designed to get round the rack-test limitation
148
+ of not being able to visit external (i.e. not the app your testing) websites.
154
149
  test_files: []
155
-