mechwarrior 0.0.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.
- data/README.md +52 -0
- data/lib/capybara/mechanize/driver.rb +118 -0
- data/lib/capybara/mechanize/form.rb +43 -0
- data/lib/capybara/mechanize/node.rb +100 -0
- data/lib/capybara/mechanize.rb +13 -0
- data/lib/mechwarrior/cucumber.rb +5 -0
- data/lib/mechwarrior/version.rb +3 -0
- data/lib/mechwarrior.rb +5 -0
- data/spec/mechanize_driver_spec.rb +20 -0
- data/spec/mechanize_session_spec.rb +34 -0
- data/spec/spec_helper.rb +26 -0
- metadata +155 -0
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
Mechwarrior
|
2
|
+
===========
|
3
|
+
|
4
|
+
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.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
1. `gem install 'mechwarrior'`
|
10
|
+
|
11
|
+
2. `require 'mechwarrior/cucumber'` in cucumbers env.rb
|
12
|
+
|
13
|
+
3. Tag your steps with either @mechanize or @external
|
14
|
+
|
15
|
+
Dependencies
|
16
|
+
------------
|
17
|
+
capybara ">= 1.0.0"
|
18
|
+
mechanize "~> 2.0.0"
|
19
|
+
|
20
|
+
|
21
|
+
Licence
|
22
|
+
---------
|
23
|
+
|
24
|
+
Copyright (c) 2011, Chris Lowder, http://github.com/clowder
|
25
|
+
|
26
|
+
All rights reserved.
|
27
|
+
|
28
|
+
Redistribution and use in source and binary forms, with or without
|
29
|
+
modification, are permitted provided that the following conditions are met:
|
30
|
+
|
31
|
+
* Redistributions of source code must retain the above copyright notice, this
|
32
|
+
list of conditions and the following disclaimer.
|
33
|
+
|
34
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
35
|
+
this list of conditions and the following disclaimer in the documentation
|
36
|
+
and/or other materials provided with the distribution.
|
37
|
+
|
38
|
+
* Neither the name of http://github.com/clowder nor the names of its contributors may
|
39
|
+
be used to endorse or promote products derived from this software without
|
40
|
+
specific prior written permission.
|
41
|
+
|
42
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
43
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
44
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
45
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
46
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
47
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
48
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
49
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
50
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
51
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
52
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
|
3
|
+
class Capybara::Mechanize::Driver < Capybara::Driver::Base
|
4
|
+
attr_reader :app, :rack_server, :options
|
5
|
+
|
6
|
+
def initialize(app, options={})
|
7
|
+
raise ArgumentError, "Mechanize requires a rack application, but none was given" unless app
|
8
|
+
|
9
|
+
@app = app
|
10
|
+
@options = options
|
11
|
+
@rack_server = Capybara::Server.new(@app)
|
12
|
+
@rack_server.boot if Capybara.run_server
|
13
|
+
end
|
14
|
+
|
15
|
+
def browser
|
16
|
+
unless @browser
|
17
|
+
@browser = Mechanize.new
|
18
|
+
@browser.follow_meta_refresh
|
19
|
+
end
|
20
|
+
@browser
|
21
|
+
end
|
22
|
+
|
23
|
+
def visit(path)
|
24
|
+
browser.get(url(path))
|
25
|
+
end
|
26
|
+
|
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
|
37
|
+
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)
|
46
|
+
end
|
47
|
+
|
48
|
+
def current_url
|
49
|
+
current_page? ? current_page.uri.to_s : ''
|
50
|
+
end
|
51
|
+
|
52
|
+
def response_headers
|
53
|
+
current_page? ? current_page.header : {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def status_code
|
57
|
+
current_page? ? current_page.code.to_i : nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def find(selector)
|
61
|
+
dom.search(selector).map { |node| Capybara::Mechanize::Node.new(self, node) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def source
|
65
|
+
current_page? ? current_page.body : ''
|
66
|
+
end
|
67
|
+
alias :body :source
|
68
|
+
|
69
|
+
def dom
|
70
|
+
current_page? ? current_page.root : Nokogiri::HTML(nil)
|
71
|
+
end
|
72
|
+
|
73
|
+
def reset!
|
74
|
+
@browser = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
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
|
+
|
99
|
+
def make_absolute_url(path)
|
100
|
+
return path unless URI.parse(path).relative?
|
101
|
+
|
102
|
+
path = "#{ request_path }#{ path }" if is_query_string?(path)
|
103
|
+
|
104
|
+
if current_page? && current_page_is_external?
|
105
|
+
current_page.uri.merge(path).to_s
|
106
|
+
else
|
107
|
+
url(path)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def is_query_string?(path)
|
112
|
+
path.start_with?('?')
|
113
|
+
end
|
114
|
+
|
115
|
+
def is_javascript_hashy_path?(path)
|
116
|
+
path.gsub(/^#{request_path}/, '').start_with?('#')
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
|
3
|
+
class Capybara::Mechanize::Form < Mechanize::Form
|
4
|
+
|
5
|
+
def initialize(node, mech=nil, page=nil)
|
6
|
+
super(strip_disabled_nodes(node), mech, page)
|
7
|
+
normalize_uploads
|
8
|
+
end
|
9
|
+
|
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
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_dummy_fields
|
34
|
+
self.file_uploads.each do |upload|
|
35
|
+
file_path = upload.node["value"]
|
36
|
+
|
37
|
+
if !file_path.nil? && file_path != ''
|
38
|
+
new_field = Mechanize::Form::Field.new(upload.node, File.basename(file_path))
|
39
|
+
self.fields << new_field
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,100 @@
|
|
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
|
+
|
49
|
+
def click
|
50
|
+
if tag_name == 'a'
|
51
|
+
method = self["data-method"] || :get
|
52
|
+
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)
|
55
|
+
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
|
100
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
|
3
|
+
module Capybara
|
4
|
+
module Mechanize
|
5
|
+
autoload :Driver, 'capybara/mechanize/driver'
|
6
|
+
autoload :Node, 'capybara/mechanize/node'
|
7
|
+
autoload :Form, 'capybara/mechanize/form'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Capybara.register_driver :mechanize do |app|
|
12
|
+
Capybara::Mechanize::Driver.new(app)
|
13
|
+
end
|
data/lib/mechwarrior.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Capybara::Mechanize::Driver do
|
5
|
+
before do
|
6
|
+
@driver = TestSessions::Mechanize.driver
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should throw an error when no rack app is given" do
|
10
|
+
running do
|
11
|
+
Capybara::Mechanize::Driver.new(nil)
|
12
|
+
end.should raise_error(ArgumentError)
|
13
|
+
end
|
14
|
+
|
15
|
+
it_should_behave_like "driver"
|
16
|
+
it_should_behave_like "driver with header support"
|
17
|
+
it_should_behave_like "driver with status code support"
|
18
|
+
it_should_behave_like "driver with cookies support"
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara::Session do
|
4
|
+
context 'with Mechanize driver' do
|
5
|
+
before do
|
6
|
+
@session = TestSessions::Mechanize
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#driver' do
|
10
|
+
it "should be a Mechanize driver" do
|
11
|
+
@session.driver.should be_an_instance_of(Capybara::Mechanize::Driver)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#mode' do
|
16
|
+
it "should remember the mode" do
|
17
|
+
@session.mode.should == :mechanize
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#click_link' do
|
22
|
+
it "should use data-method if available" do
|
23
|
+
@session.visit "/with_html"
|
24
|
+
@session.click_link "A link with data-method"
|
25
|
+
@session.body.should include('The requested object was deleted')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it_should_behave_like "session"
|
30
|
+
it_should_behave_like "session without javascript support"
|
31
|
+
it_should_behave_like "session with headers support"
|
32
|
+
it_should_behave_like "session with status code support"
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require "bundler/setup"
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
require 'mechwarrior'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.before do
|
11
|
+
Capybara.configure do |config|
|
12
|
+
config.default_selector = :xpath
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'capybara/spec/driver'
|
18
|
+
require 'capybara/spec/session'
|
19
|
+
|
20
|
+
alias :running :lambda
|
21
|
+
|
22
|
+
Capybara.default_wait_time = 0 # less timeout so tests run faster
|
23
|
+
|
24
|
+
module TestSessions
|
25
|
+
Mechanize = Capybara::Session.new(:mechanize, TestApp)
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mechwarrior
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Lowder
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-25 00:00:00 +01:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: capybara
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.0
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mechanize
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.0.0
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: sinatra
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.9.4
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 2.0.0
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: launchy
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.3.5
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: yard
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.5.8
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: fuubar
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.0.1
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: cucumber
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0.10"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id008
|
104
|
+
description: A Mechanize based Capybara driver.
|
105
|
+
email:
|
106
|
+
- clowder@gmail.com
|
107
|
+
executables: []
|
108
|
+
|
109
|
+
extensions: []
|
110
|
+
|
111
|
+
extra_rdoc_files:
|
112
|
+
- README.md
|
113
|
+
files:
|
114
|
+
- lib/capybara/mechanize/driver.rb
|
115
|
+
- lib/capybara/mechanize/form.rb
|
116
|
+
- lib/capybara/mechanize/node.rb
|
117
|
+
- lib/capybara/mechanize.rb
|
118
|
+
- lib/mechwarrior/cucumber.rb
|
119
|
+
- lib/mechwarrior/version.rb
|
120
|
+
- lib/mechwarrior.rb
|
121
|
+
- spec/mechanize_driver_spec.rb
|
122
|
+
- spec/mechanize_session_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
- README.md
|
125
|
+
has_rdoc: true
|
126
|
+
homepage: http://github.com/clowder/mechwarrior
|
127
|
+
licenses: []
|
128
|
+
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options:
|
131
|
+
- --main
|
132
|
+
- README.md
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: "0"
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: "0"
|
147
|
+
requirements: []
|
148
|
+
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.6.2
|
151
|
+
signing_key:
|
152
|
+
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.
|
154
|
+
test_files: []
|
155
|
+
|