pr0d1r2-capybara 0.3.7

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.
Files changed (87) hide show
  1. data/History.txt +71 -0
  2. data/README.rdoc +388 -0
  3. data/lib/capybara.rb +57 -0
  4. data/lib/capybara/cucumber.rb +32 -0
  5. data/lib/capybara/driver/base.rb +48 -0
  6. data/lib/capybara/driver/celerity_driver.rb +143 -0
  7. data/lib/capybara/driver/culerity_driver.rb +25 -0
  8. data/lib/capybara/driver/rack_test_driver.rb +271 -0
  9. data/lib/capybara/driver/selenium_driver.rb +161 -0
  10. data/lib/capybara/dsl.rb +60 -0
  11. data/lib/capybara/node.rb +60 -0
  12. data/lib/capybara/rails.rb +17 -0
  13. data/lib/capybara/save_and_open_page.rb +33 -0
  14. data/lib/capybara/searchable.rb +54 -0
  15. data/lib/capybara/server.rb +114 -0
  16. data/lib/capybara/session.rb +262 -0
  17. data/lib/capybara/spec/driver.rb +162 -0
  18. data/lib/capybara/spec/fixtures/capybara.jpg +0 -0
  19. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  20. data/lib/capybara/spec/public/jquery-ui.js +35 -0
  21. data/lib/capybara/spec/public/jquery.js +19 -0
  22. data/lib/capybara/spec/public/test.js +33 -0
  23. data/lib/capybara/spec/session.rb +81 -0
  24. data/lib/capybara/spec/session/all_spec.rb +69 -0
  25. data/lib/capybara/spec/session/attach_file_spec.rb +64 -0
  26. data/lib/capybara/spec/session/check_spec.rb +67 -0
  27. data/lib/capybara/spec/session/choose_spec.rb +26 -0
  28. data/lib/capybara/spec/session/click_button_spec.rb +236 -0
  29. data/lib/capybara/spec/session/click_link_spec.rb +108 -0
  30. data/lib/capybara/spec/session/click_spec.rb +24 -0
  31. data/lib/capybara/spec/session/current_url_spec.rb +8 -0
  32. data/lib/capybara/spec/session/fill_in_spec.rb +108 -0
  33. data/lib/capybara/spec/session/find_button_spec.rb +16 -0
  34. data/lib/capybara/spec/session/find_by_id_spec.rb +16 -0
  35. data/lib/capybara/spec/session/find_field_spec.rb +22 -0
  36. data/lib/capybara/spec/session/find_link_spec.rb +17 -0
  37. data/lib/capybara/spec/session/find_spec.rb +57 -0
  38. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  39. data/lib/capybara/spec/session/has_content_spec.rb +106 -0
  40. data/lib/capybara/spec/session/has_css_spec.rb +107 -0
  41. data/lib/capybara/spec/session/has_field_spec.rb +96 -0
  42. data/lib/capybara/spec/session/has_link_spec.rb +33 -0
  43. data/lib/capybara/spec/session/has_select_spec.rb +89 -0
  44. data/lib/capybara/spec/session/has_table_spec.rb +96 -0
  45. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  46. data/lib/capybara/spec/session/headers.rb +19 -0
  47. data/lib/capybara/spec/session/javascript.rb +204 -0
  48. data/lib/capybara/spec/session/locate_spec.rb +59 -0
  49. data/lib/capybara/spec/session/select_spec.rb +77 -0
  50. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  51. data/lib/capybara/spec/session/unselect_spec.rb +54 -0
  52. data/lib/capybara/spec/session/within_spec.rb +153 -0
  53. data/lib/capybara/spec/test_app.rb +75 -0
  54. data/lib/capybara/spec/views/buttons.erb +4 -0
  55. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  56. data/lib/capybara/spec/views/form.erb +234 -0
  57. data/lib/capybara/spec/views/frame_one.erb +8 -0
  58. data/lib/capybara/spec/views/frame_two.erb +8 -0
  59. data/lib/capybara/spec/views/postback.erb +13 -0
  60. data/lib/capybara/spec/views/tables.erb +122 -0
  61. data/lib/capybara/spec/views/with_html.erb +42 -0
  62. data/lib/capybara/spec/views/with_js.erb +39 -0
  63. data/lib/capybara/spec/views/with_scope.erb +36 -0
  64. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  65. data/lib/capybara/spec/views/within_frames.erb +10 -0
  66. data/lib/capybara/version.rb +3 -0
  67. data/lib/capybara/wait_until.rb +28 -0
  68. data/lib/capybara/xpath.rb +179 -0
  69. data/spec/capybara_spec.rb +18 -0
  70. data/spec/driver/celerity_driver_spec.rb +16 -0
  71. data/spec/driver/culerity_driver_spec.rb +12 -0
  72. data/spec/driver/rack_test_driver_spec.rb +11 -0
  73. data/spec/driver/remote_culerity_driver_spec.rb +23 -0
  74. data/spec/driver/remote_selenium_driver_spec.rb +18 -0
  75. data/spec/driver/selenium_driver_spec.rb +11 -0
  76. data/spec/dsl_spec.rb +140 -0
  77. data/spec/save_and_open_page_spec.rb +43 -0
  78. data/spec/searchable_spec.rb +66 -0
  79. data/spec/server_spec.rb +53 -0
  80. data/spec/session/celerity_session_spec.rb +27 -0
  81. data/spec/session/culerity_session_spec.rb +25 -0
  82. data/spec/session/rack_test_session_spec.rb +33 -0
  83. data/spec/session/selenium_session_spec.rb +25 -0
  84. data/spec/spec_helper.rb +19 -0
  85. data/spec/wait_until_spec.rb +28 -0
  86. data/spec/xpath_spec.rb +180 -0
  87. metadata +259 -0
@@ -0,0 +1,42 @@
1
+ <h1>This is a test</h1>
2
+
3
+ <p id="first">
4
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
5
+ tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
6
+ et dolore magna aliqua. Ut enim ad minim veniam,
7
+ quis nostrud exercitation <a href="/foo" id="foo">ullamco</a> laboris nisi
8
+ ut aliquip ex ea commodo consequat.
9
+ <a href="/with_simple_html"><img src="http://www.foobar.sun/dummy_image.jpg" width="20" height="20" alt="awesome image" /></a>
10
+ </p>
11
+
12
+ <p id="second">
13
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
14
+ dolore eu fugiat <a href="/redirect" id="red">Redirect</a> pariatur. Excepteur sint occaecat cupidatat non proident,
15
+ sunt in culpa qui officia
16
+ text with
17
+ whitespace
18
+ id est laborum.
19
+ </p>
20
+
21
+ <p>
22
+ <input type="text" id="test_field" value="monkey"/>
23
+ <a href="/redirect_back">BackToMyself</a>
24
+ <a title="twas a fine link" href="/redirect">A link came first</a>
25
+ <a title="a fine link" href="/with_simple_html">A link</a>
26
+ <a title="a fine link with data method" data-method="delete" href="/delete">A link with data-method</a>
27
+ <a>No Href</a>
28
+ <a href="">Blank Href</a>
29
+ <a href="#">Blank Anchor</a>
30
+ <a href="#anchor">Anchor</a>
31
+ <a href="/with_simple_html#anchor">Anchor on different page</a>
32
+ <a href="/with_html#anchor">Anchor on same page</a>
33
+ <input type="text" value="" id="test_field">
34
+ <input type="text" checked="checked" id="checked_field">
35
+ <a href="/redirect"><img src="http://www.foobar.sun/dummy_image.jpg" width="20" height="20" alt="very fine image" /></a>
36
+ <a href="/with_simple_html"><img src="http://www.foobar.sun/dummy_image.jpg" width="20" height="20" alt="fine image" /></a>
37
+ </p>
38
+
39
+ <div id="hidden" style="display: none;">
40
+ <div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
41
+ <a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
42
+ </div>
@@ -0,0 +1,39 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
2
+ <head>
3
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
+ <title>with_js</title>
5
+ <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
6
+ <script src="/jquery-ui.js" type="text/javascript" charset="utf-8"></script>
7
+ <script src="/test.js" type="text/javascript" charset="utf-8"></script>
8
+ </head>
9
+
10
+ <body id="with_js">
11
+ <h1>FooBar</h1>
12
+
13
+ <p id="change">This is text</p>
14
+ <div id="drag">
15
+ <p>This is a draggable element.</p>
16
+ </div>
17
+ <div id="drop">
18
+ <p>It should be dropped here.</p>
19
+ </div>
20
+
21
+ <p><a href="#" id="clickable">Click me</a></p>
22
+
23
+ <p>
24
+ <select id="waiter">
25
+ <option>Foo</option>
26
+ <option>My Waiting Option</option>
27
+ </select>
28
+ </p>
29
+
30
+ <p>
31
+ <input type="text" name="with_focus_event" value="" id="with_focus_event"/>
32
+ </p>
33
+
34
+ <p>
35
+ <input type="checkbox" id="checkbox_with_event"/>
36
+ </p>
37
+ </body>
38
+ </html>
39
+
@@ -0,0 +1,36 @@
1
+ <h1>This page is used for testing various scopes</h1>
2
+
3
+ <p id="for_foo">
4
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
5
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia.
6
+ <a href="/redirect">Go</a>
7
+ </p>
8
+
9
+ <div id="for_bar">
10
+ <ul>
11
+ <li>With Simple HTML: <a href="/with_simple_html">Go</a>
12
+ <form action="/redirect" method="post" accept-charset="utf-8">
13
+ <p>
14
+ <label for="simple_first_name">First Name</label>
15
+ <input type="text" name="first_name" value="John" id="simple_first_name"/>
16
+ </p>
17
+ <p><input type="submit" value="Go"/></p>
18
+ </form>
19
+ </li>
20
+ <li>Bar: <a href="/foo">Go</a>
21
+ <form action="/form" method="post" accept-charset="utf-8">
22
+ <p>
23
+ <label for="bar_first_name">First Name</label>
24
+ <input type="text" name="form[first_name]" value="Peter" id="bar_first_name"/>
25
+ </p>
26
+ <p><input type="submit" value="Go"/></p>
27
+ </form>
28
+ </li>
29
+ </ul>
30
+ </div>
31
+
32
+ <div id="another_foo">
33
+ <ul>
34
+ <li>With Simple HTML: <a href="/">Go</a>
35
+ </ul>
36
+ </div>
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ <title>With Frames</title>
4
+ </head>
5
+ <body>
6
+ <div id="divInMainWindow">This is the text for divInMainWindow</div>
7
+ <iframe src="/frame_one" id="frameOne"></iframe>
8
+ <iframe src="/frame_two" id="frameTwo"></iframe>
9
+ </body>
10
+ </html>
@@ -0,0 +1,3 @@
1
+ module Capybara
2
+ VERSION = '0.3.7'
3
+ end
@@ -0,0 +1,28 @@
1
+ module Capybara
2
+ #Provides timeout similar to standard library Timeout, but avoids threads
3
+ class WaitUntil
4
+
5
+ class << self
6
+
7
+ def timeout(seconds = 1, driver = nil, &block)
8
+ start_time = Time.now
9
+
10
+ result = nil
11
+
12
+ until result
13
+ return result if result = yield
14
+
15
+ delay = seconds - (Time.now - start_time)
16
+ if delay <= 0
17
+ raise TimeoutError
18
+ end
19
+
20
+ driver && driver.wait_until(delay)
21
+
22
+ sleep(0.05)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,179 @@
1
+ module Capybara
2
+ # this is a class for generating XPath queries, use it like this:
3
+ # Xpath.text_field('foo').link('blah').to_s
4
+ # this will generate an XPath that matches either a text field or a link
5
+ class XPath
6
+
7
+ class << self
8
+ def escape(string)
9
+ if string.include?("'")
10
+ string = string.split("'", -1).map do |substr|
11
+ "'#{substr}'"
12
+ end.join(%q{,"'",})
13
+ "concat(#{string})"
14
+ else
15
+ "'#{string}'"
16
+ end
17
+ end
18
+
19
+ def wrap(path)
20
+ if path.is_a?(self)
21
+ path
22
+ else
23
+ new(path.to_s)
24
+ end
25
+ end
26
+
27
+ def respond_to?(method)
28
+ new.respond_to?(method)
29
+ end
30
+
31
+ def method_missing(*args)
32
+ new.send(*args)
33
+ end
34
+ end
35
+
36
+ attr_reader :paths
37
+
38
+ def initialize(*paths)
39
+ @paths = paths
40
+ end
41
+
42
+ def scope(scope)
43
+ XPath.new(*paths.map { |p| scope + p })
44
+ end
45
+
46
+ def to_s
47
+ @paths.join(' | ')
48
+ end
49
+
50
+ def append(path)
51
+ XPath.new(*[@paths, XPath.wrap(path).paths].flatten)
52
+ end
53
+
54
+ def prepend(path)
55
+ XPath.new(*[XPath.wrap(path).paths, @paths].flatten)
56
+ end
57
+
58
+ def from_css(css)
59
+ append(Nokogiri::CSS.xpath_for(css).first)
60
+ end
61
+ alias_method :for_css, :from_css
62
+
63
+ def field(locator, options={})
64
+ if options[:with]
65
+ fillable_field(locator, options)
66
+ else
67
+ xpath = fillable_field(locator)
68
+ xpath = xpath.input_field(:file, locator, options)
69
+ xpath = xpath.checkbox(locator, options)
70
+ xpath = xpath.radio_button(locator, options)
71
+ xpath.select(locator, options)
72
+ end
73
+ end
74
+
75
+ def fillable_field(locator, options={})
76
+ text_area(locator, options).text_field(locator, options)
77
+ end
78
+
79
+ def content(locator)
80
+ append("/descendant-or-self::*[contains(normalize-space(.),#{s(locator)})]")
81
+ end
82
+
83
+ def table(locator, options={})
84
+ conditions = ""
85
+ if options[:rows]
86
+ row_conditions = options[:rows].map do |row|
87
+ row = row.map { |column| "*[self::td or self::th][text()=#{s(column)}]" }.join(sibling)
88
+ "tr[./#{row}]"
89
+ end.join(sibling)
90
+ conditions << "[.//#{row_conditions}]"
91
+ end
92
+ append("//table[@id=#{s(locator)} or contains(caption,#{s(locator)})]#{conditions}")
93
+ end
94
+
95
+ def fieldset(locator)
96
+ append("//fieldset[@id=#{s(locator)} or contains(legend,#{s(locator)})]")
97
+ end
98
+
99
+ def link(locator)
100
+ xpath = append("//a[@href][@id=#{s(locator)} or contains(.,#{s(locator)}) or contains(@title,#{s(locator)}) or img[contains(@alt,#{s(locator)})]]")
101
+ xpath.prepend("//a[@href][text()=#{s(locator)} or @title=#{s(locator)} or img[@alt=#{s(locator)}]]")
102
+ end
103
+
104
+ def button(locator)
105
+ xpath = append("//input[@type='submit' or @type='image' or @type='button'][@id=#{s(locator)} or contains(@value,#{s(locator)})]")
106
+ xpath = xpath.append("//button[@id=#{s(locator)} or contains(@value,#{s(locator)}) or contains(.,#{s(locator)})]")
107
+ xpath = xpath.prepend("//input[@type='submit' or @type='image' or @type='button'][@value=#{s(locator)}]")
108
+ xpath = xpath.prepend("//input[@type='image'][@alt=#{s(locator)} or contains(@alt,#{s(locator)})]")
109
+ xpath = xpath.prepend("//button[@value=#{s(locator)} or text()=#{s(locator)}]")
110
+ end
111
+
112
+ def text_field(locator, options={})
113
+ options = options.merge(:value => options[:with]) if options.has_key?(:with)
114
+ add_field(locator, "//input[@type!='radio' and @type!='checkbox' and @type!='hidden']", options)
115
+ end
116
+
117
+ def text_area(locator, options={})
118
+ options = options.merge(:text => options[:with]) if options.has_key?(:with)
119
+ add_field(locator, "//textarea", options)
120
+ end
121
+
122
+ def select(locator, options={})
123
+ add_field(locator, "//select", options)
124
+ end
125
+
126
+ def checkbox(locator, options={})
127
+ input_field(:checkbox, locator, options)
128
+ end
129
+
130
+ def radio_button(locator, options={})
131
+ input_field(:radio, locator, options)
132
+ end
133
+
134
+ def file_field(locator, options={})
135
+ input_field(:file, locator, options)
136
+ end
137
+
138
+ protected
139
+
140
+ def input_field(type, locator, options={})
141
+ options = options.merge(:value => options[:with]) if options.has_key?(:with)
142
+ add_field(locator, "//input[@type='#{type}']", options)
143
+ end
144
+
145
+ # place this between to nodes to indicate that they should be siblings
146
+ def sibling
147
+ '/following-sibling::*[1]/self::'
148
+ end
149
+
150
+ def add_field(locator, field, options={})
151
+ postfix = extract_postfix(options)
152
+ xpath = append("#{field}[@id=#{s(locator)}]#{postfix}")
153
+ xpath = xpath.append("#{field}[@name=#{s(locator)}]#{postfix}")
154
+ xpath = xpath.append("#{field}[@id=//label[contains(.,#{s(locator)})]/@for]#{postfix}")
155
+ xpath = xpath.append("//label[contains(.,#{s(locator)})]#{field}#{postfix}")
156
+ xpath.prepend("#{field}[@id=//label[text()=#{s(locator)}]/@for]#{postfix}")
157
+ end
158
+
159
+ def extract_postfix(options)
160
+ options.inject("") do |postfix, (key, value)|
161
+ case key
162
+ when :value then postfix += "[@value=#{s(value)}]"
163
+ when :text then postfix += "[text()=#{s(value)}]"
164
+ when :checked then postfix += "[@checked]"
165
+ when :unchecked then postfix += "[not(@checked)]"
166
+ when :options then postfix += value.map { |o| "[./option/text()=#{s(o)}]" }.join
167
+ when :selected then postfix += [value].flatten.map { |o| "[./option[@selected]/text()=#{s(o)}]" }.join
168
+ end
169
+ postfix
170
+ end
171
+ end
172
+
173
+ # Sanitize a String for putting it into an xpath query
174
+ def s(string)
175
+ XPath.escape(string)
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ require 'capybara'
4
+
5
+ describe Capybara do
6
+
7
+ describe 'default_wait_time' do
8
+ after do
9
+ Capybara.default_wait_time = 2
10
+ end
11
+
12
+ it "should be changeable" do
13
+ Capybara.default_wait_time = 5
14
+ Capybara.default_wait_time.should == 5
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ if RUBY_PLATFORM =~ /java/
4
+ describe Capybara::Driver::Celerity do
5
+ before(:all) do
6
+ @driver = Capybara::Driver::Celerity.new(TestApp)
7
+ end
8
+
9
+ it_should_behave_like "driver"
10
+ it_should_behave_like "driver with javascript support"
11
+ it_should_behave_like "driver with header support"
12
+
13
+ end
14
+ else
15
+ puts "#{File.basename(__FILE__)} requires JRuby; skipping.."
16
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Capybara::Driver::Culerity do
4
+ before(:all) do
5
+ @driver = Capybara::Driver::Culerity.new(TestApp)
6
+ end
7
+
8
+ it_should_behave_like "driver"
9
+ it_should_behave_like "driver with javascript support"
10
+ it_should_behave_like "driver with header support"
11
+
12
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Capybara::Driver::RackTest do
4
+ before do
5
+ @driver = Capybara::Driver::RackTest.new(TestApp)
6
+ end
7
+
8
+ it_should_behave_like "driver"
9
+ it_should_behave_like "driver with header support"
10
+
11
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Capybara::Driver::Culerity do
4
+ before(:all) do
5
+ Capybara.app_host = "http://capybara-testapp.heroku.com"
6
+ Capybara.run_server = false
7
+ @driver = Capybara::Driver::Culerity.new(TestApp)
8
+ end
9
+
10
+ after(:all) do
11
+ Capybara.app_host = nil
12
+ Capybara.run_server = true
13
+ end
14
+
15
+ it "should navigate to a fully qualified remote page" do
16
+ @driver.visit('http://elabs.se/contact')
17
+ @driver.body.should include('Edithouse eLabs AB')
18
+ end
19
+
20
+ it_should_behave_like "driver"
21
+ it_should_behave_like "driver with javascript support"
22
+ it_should_behave_like "driver with header support"
23
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Capybara::Driver::Selenium do
4
+ before(:all) do
5
+ Capybara.app_host = "http://capybara-testapp.heroku.com"
6
+ end
7
+
8
+ after(:all) do
9
+ Capybara.app_host = nil
10
+ end
11
+
12
+ before do
13
+ @driver = Capybara::Driver::Selenium.new(TestApp)
14
+ end
15
+
16
+ it_should_behave_like "driver"
17
+ it_should_behave_like "driver with javascript support"
18
+ end