pr0d1r2-capybara 0.3.7

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