mechwarrior 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-