nimboids-capybara 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/History.txt +289 -0
  2. data/README.rdoc +722 -0
  3. data/lib/capybara.rb +252 -0
  4. data/lib/capybara/cucumber.rb +28 -0
  5. data/lib/capybara/driver/base.rb +64 -0
  6. data/lib/capybara/driver/node.rb +74 -0
  7. data/lib/capybara/dsl.rb +168 -0
  8. data/lib/capybara/node/actions.rb +162 -0
  9. data/lib/capybara/node/base.rb +63 -0
  10. data/lib/capybara/node/document.rb +25 -0
  11. data/lib/capybara/node/element.rb +201 -0
  12. data/lib/capybara/node/finders.rb +197 -0
  13. data/lib/capybara/node/matchers.rb +417 -0
  14. data/lib/capybara/node/simple.rb +132 -0
  15. data/lib/capybara/rack_test/browser.rb +121 -0
  16. data/lib/capybara/rack_test/driver.rb +80 -0
  17. data/lib/capybara/rack_test/form.rb +80 -0
  18. data/lib/capybara/rack_test/node.rb +105 -0
  19. data/lib/capybara/rails.rb +17 -0
  20. data/lib/capybara/rspec.rb +26 -0
  21. data/lib/capybara/rspec/features.rb +22 -0
  22. data/lib/capybara/rspec/matchers.rb +154 -0
  23. data/lib/capybara/selector.rb +89 -0
  24. data/lib/capybara/selenium/driver.rb +163 -0
  25. data/lib/capybara/selenium/node.rb +91 -0
  26. data/lib/capybara/server.rb +90 -0
  27. data/lib/capybara/session.rb +321 -0
  28. data/lib/capybara/spec/driver.rb +301 -0
  29. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  30. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  31. data/lib/capybara/spec/public/test.js +43 -0
  32. data/lib/capybara/spec/session.rb +154 -0
  33. data/lib/capybara/spec/session/all_spec.rb +78 -0
  34. data/lib/capybara/spec/session/attach_file_spec.rb +73 -0
  35. data/lib/capybara/spec/session/check_spec.rb +65 -0
  36. data/lib/capybara/spec/session/choose_spec.rb +26 -0
  37. data/lib/capybara/spec/session/click_button_spec.rb +304 -0
  38. data/lib/capybara/spec/session/click_link_or_button_spec.rb +36 -0
  39. data/lib/capybara/spec/session/click_link_spec.rb +119 -0
  40. data/lib/capybara/spec/session/current_host_spec.rb +68 -0
  41. data/lib/capybara/spec/session/current_url_spec.rb +15 -0
  42. data/lib/capybara/spec/session/fill_in_spec.rb +125 -0
  43. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  44. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  45. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  46. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  47. data/lib/capybara/spec/session/find_spec.rb +149 -0
  48. data/lib/capybara/spec/session/first_spec.rb +105 -0
  49. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  50. data/lib/capybara/spec/session/has_content_spec.rb +106 -0
  51. data/lib/capybara/spec/session/has_css_spec.rb +243 -0
  52. data/lib/capybara/spec/session/has_field_spec.rb +192 -0
  53. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  54. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  55. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  56. data/lib/capybara/spec/session/has_table_spec.rb +96 -0
  57. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  58. data/lib/capybara/spec/session/headers.rb +19 -0
  59. data/lib/capybara/spec/session/javascript.rb +289 -0
  60. data/lib/capybara/spec/session/response_code.rb +19 -0
  61. data/lib/capybara/spec/session/select_spec.rb +113 -0
  62. data/lib/capybara/spec/session/text_spec.rb +19 -0
  63. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  64. data/lib/capybara/spec/session/unselect_spec.rb +61 -0
  65. data/lib/capybara/spec/session/within_spec.rb +178 -0
  66. data/lib/capybara/spec/test_app.rb +142 -0
  67. data/lib/capybara/spec/views/buttons.erb +4 -0
  68. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  69. data/lib/capybara/spec/views/form.erb +365 -0
  70. data/lib/capybara/spec/views/frame_one.erb +8 -0
  71. data/lib/capybara/spec/views/frame_two.erb +8 -0
  72. data/lib/capybara/spec/views/header_links.erb +7 -0
  73. data/lib/capybara/spec/views/host_links.erb +12 -0
  74. data/lib/capybara/spec/views/popup_one.erb +8 -0
  75. data/lib/capybara/spec/views/popup_two.erb +8 -0
  76. data/lib/capybara/spec/views/postback.erb +13 -0
  77. data/lib/capybara/spec/views/tables.erb +122 -0
  78. data/lib/capybara/spec/views/with_html.erb +78 -0
  79. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  80. data/lib/capybara/spec/views/with_js.erb +48 -0
  81. data/lib/capybara/spec/views/with_scope.erb +36 -0
  82. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  83. data/lib/capybara/spec/views/within_frames.erb +10 -0
  84. data/lib/capybara/spec/views/within_popups.erb +25 -0
  85. data/lib/capybara/util/save_and_open_page.rb +44 -0
  86. data/lib/capybara/util/timeout.rb +27 -0
  87. data/lib/capybara/version.rb +3 -0
  88. data/spec/basic_node_spec.rb +77 -0
  89. data/spec/capybara_spec.rb +46 -0
  90. data/spec/driver/rack_test_driver_spec.rb +89 -0
  91. data/spec/driver/selenium_driver_spec.rb +50 -0
  92. data/spec/dsl_spec.rb +253 -0
  93. data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
  94. data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
  95. data/spec/rspec/features_spec.rb +45 -0
  96. data/spec/rspec/matchers_spec.rb +495 -0
  97. data/spec/rspec_spec.rb +53 -0
  98. data/spec/save_and_open_page_spec.rb +155 -0
  99. data/spec/server_spec.rb +89 -0
  100. data/spec/session/rack_test_session_spec.rb +55 -0
  101. data/spec/session/selenium_session_spec.rb +26 -0
  102. data/spec/spec_helper.rb +30 -0
  103. data/spec/string_spec.rb +77 -0
  104. data/spec/timeout_spec.rb +28 -0
  105. metadata +346 -0
@@ -0,0 +1,162 @@
1
+ module Capybara
2
+ module Node
3
+ module Actions
4
+
5
+ ##
6
+ #
7
+ # Finds a button or link by id, text or value and clicks it. Also looks at image
8
+ # alt text inside the link.
9
+ #
10
+ # @param [String] locator Text, id or value of link or button
11
+ #
12
+ def click_link_or_button(locator)
13
+ msg = "no link or button '#{locator}' found"
14
+ find(:xpath, XPath::HTML.link_or_button(locator), :message => msg).click
15
+ end
16
+ alias_method :click_on, :click_link_or_button
17
+
18
+ ##
19
+ #
20
+ # Finds a link by id or text and clicks it. Also looks at image
21
+ # alt text inside the link.
22
+ #
23
+ # @param [String] locator Text, id or text of link
24
+ #
25
+ def click_link(locator)
26
+ msg = "no link with title, id or text '#{locator}' found"
27
+ find(:xpath, XPath::HTML.link(locator), :message => msg).click
28
+ end
29
+
30
+ ##
31
+ #
32
+ # Finds a button by id, text or value and clicks it.
33
+ #
34
+ # @param [String] locator Text, id or value of button
35
+ #
36
+ def click_button(locator)
37
+ msg = "no button with value or id or text '#{locator}' found"
38
+ find(:xpath, XPath::HTML.button(locator), :message => msg).click
39
+ end
40
+
41
+ ##
42
+ #
43
+ # Locate a text field or text area and fill it in with the given text
44
+ # The field can be found via its name, id or label text.
45
+ #
46
+ # page.fill_in 'Name', :with => 'Bob'
47
+ #
48
+ # @param [String] locator Which field to fill in
49
+ # @param [Hash{:with => String}] The value to fill in
50
+ #
51
+ def fill_in(locator, options={})
52
+ msg = "cannot fill in, no text field, text area or password field with id, name, or label '#{locator}' found"
53
+ raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with)
54
+ find(:xpath, XPath::HTML.fillable_field(locator), :message => msg).set(options[:with])
55
+ end
56
+
57
+ ##
58
+ #
59
+ # Find a radio button and mark it as checked. The radio button can be found
60
+ # via name, id or label text.
61
+ #
62
+ # page.choose('Male')
63
+ #
64
+ # @param [String] locator Which radio button to choose
65
+ #
66
+ def choose(locator)
67
+ msg = "cannot choose field, no radio button with id, name, or label '#{locator}' found"
68
+ find(:xpath, XPath::HTML.radio_button(locator), :message => msg).set(true)
69
+ end
70
+
71
+ ##
72
+ #
73
+ # Find a check box and mark it as checked. The check box can be found
74
+ # via name, id or label text.
75
+ #
76
+ # page.check('German')
77
+ #
78
+ # @param [String] locator Which check box to check
79
+ #
80
+ def check(locator)
81
+ msg = "cannot check field, no checkbox with id, name, or label '#{locator}' found"
82
+ find(:xpath, XPath::HTML.checkbox(locator), :message => msg).set(true)
83
+ end
84
+
85
+ ##
86
+ #
87
+ # Find a check box and mark uncheck it. The check box can be found
88
+ # via name, id or label text.
89
+ #
90
+ # page.uncheck('German')
91
+ #
92
+ # @param [String] locator Which check box to uncheck
93
+ #
94
+ def uncheck(locator)
95
+ msg = "cannot uncheck field, no checkbox with id, name, or label '#{locator}' found"
96
+ find(:xpath, XPath::HTML.checkbox(locator), :message => msg).set(false)
97
+ end
98
+
99
+ ##
100
+ #
101
+ # Find a select box on the page and select a particular option from it. If the select
102
+ # box is a multiple select, +select+ can be called multiple times to select more than
103
+ # one option. The select box can be found via its name, id or label text.
104
+ #
105
+ # page.select 'March', :from => 'Month'
106
+ #
107
+ # @param [String] value Which option to select
108
+ # @param [Hash{:from => String}] The id, name or label of the select box
109
+ #
110
+ def select(value, options={})
111
+ if options.has_key?(:from)
112
+ no_select_msg = "cannot select option, no select box with id, name, or label '#{options[:from]}' found"
113
+ no_option_msg = "cannot select option, no option with text '#{value}' in select box '#{options[:from]}'"
114
+ select = find(:xpath, XPath::HTML.select(options[:from]), :message => no_select_msg)
115
+ select.find(:xpath, XPath::HTML.option(value), :message => no_option_msg).select_option
116
+ else
117
+ no_option_msg = "cannot select option, no option with text '#{value}'"
118
+ find(:xpath, XPath::HTML.option(value), :message => no_option_msg).select_option
119
+ end
120
+ end
121
+
122
+ ##
123
+ #
124
+ # Find a select box on the page and unselect a particular option from it. If the select
125
+ # box is a multiple select, +unselect+ can be called multiple times to unselect more than
126
+ # one option. The select box can be found via its name, id or label text.
127
+ #
128
+ # page.unselect 'March', :from => 'Month'
129
+ #
130
+ # @param [String] value Which option to unselect
131
+ # @param [Hash{:from => String}] The id, name or label of the select box
132
+ #
133
+ def unselect(value, options={})
134
+ if options.has_key?(:from)
135
+ no_select_msg = "cannot unselect option, no select box with id, name, or label '#{options[:from]}' found"
136
+ no_option_msg = "cannot unselect option, no option with text '#{value}' in select box '#{options[:from]}'"
137
+ select = find(:xpath, XPath::HTML.select(options[:from]), :message => no_select_msg)
138
+ select.find(:xpath, XPath::HTML.option(value), :message => no_option_msg).unselect_option
139
+ else
140
+ no_option_msg = "cannot unselect option, no option with text '#{value}'"
141
+ find(:xpath, XPath::HTML.option(value), :message => no_option_msg).unselect_option
142
+ end
143
+ end
144
+
145
+ ##
146
+ #
147
+ # Find a file field on the page and attach a file given its path. The file field can
148
+ # be found via its name, id or label text.
149
+ #
150
+ # page.attach_file(locator, '/path/to/file.png')
151
+ #
152
+ # @param [String] locator Which field to attach the file to
153
+ # @param [String] path The path of the file that will be attached
154
+ #
155
+ def attach_file(locator, path)
156
+ raise Capybara::FileNotFound, "cannot attach file, #{path} does not exist" unless File.exist?(path.to_s)
157
+ msg = "cannot attach file, no file field with id, name, or label '#{locator}' found"
158
+ find(:xpath, XPath::HTML.file_field(locator), :message => msg).set(path)
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,63 @@
1
+ module Capybara
2
+ module Node
3
+
4
+ ##
5
+ #
6
+ # A {Capybara::Node::Base} represents either an element on a page through the subclass
7
+ # {Capybara::Node::Element} or a document through {Capybara::Node::Document}.
8
+ #
9
+ # Both types of Node share the same methods, used for interacting with the
10
+ # elements on the page. These methods are divided into three categories,
11
+ # finders, actions and matchers. These are found in the modules
12
+ # {Capybara::Node::Finders}, {Capybara::Node::Actions} and {Capybara::Node::Matchers}
13
+ # respectively.
14
+ #
15
+ # A {Capybara::Session} exposes all methods from {Capybara::Node::Document} directly:
16
+ #
17
+ # session = Capybara::Session.new(:rack_test, my_app)
18
+ # session.visit('/')
19
+ # session.fill_in('Foo', :with => 'Bar') # from Capybara::Node::Actions
20
+ # bar = session.find('#bar') # from Capybara::Node::Finders
21
+ # bar.select('Baz', :from => 'Quox') # from Capybara::Node::Actions
22
+ # session.has_css?('#foobar') # from Capybara::Node::Matchers
23
+ #
24
+ class Base
25
+ attr_reader :session, :base, :parent
26
+
27
+ include Capybara::Node::Finders
28
+ include Capybara::Node::Actions
29
+ include Capybara::Node::Matchers
30
+
31
+ def initialize(session, base)
32
+ @session = session
33
+ @base = base
34
+ end
35
+
36
+ def reload
37
+ self
38
+ end
39
+
40
+ protected
41
+
42
+ def wait_until(seconds=Capybara.default_wait_time)
43
+ start_time = Time.now
44
+
45
+ begin
46
+ yield
47
+ rescue => e
48
+ raise e unless driver.wait?
49
+ raise e unless (driver.respond_to?(:invalid_element_errors) and driver.invalid_element_errors.include?(e.class)) or e.is_a?(Capybara::ElementNotFound)
50
+ raise e if (Time.now - start_time) >= seconds
51
+ sleep(0.05)
52
+ raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
53
+ reload if Capybara.automatic_reload
54
+ retry
55
+ end
56
+ end
57
+
58
+ def driver
59
+ session.driver
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,25 @@
1
+ module Capybara
2
+ module Node
3
+
4
+ ##
5
+ #
6
+ # A {Capybara::Document} represents an HTML document. Any operation
7
+ # performed on it will be performed on the entire document.
8
+ #
9
+ # @see Capybara::Node
10
+ #
11
+ class Document < Base
12
+ def inspect
13
+ %(#<Capybara::Document>)
14
+ end
15
+
16
+ ##
17
+ #
18
+ # @return [String] The text of the document
19
+ #
20
+ def text
21
+ find(:xpath, '/html').text
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,201 @@
1
+ module Capybara
2
+ module Node
3
+
4
+ ##
5
+ #
6
+ # A {Capybara::Element} represents a single element on the page. It is possible
7
+ # to interact with the contents of this element the same as with a document:
8
+ #
9
+ # session = Capybara::Session.new(:rack_test, my_app)
10
+ #
11
+ # bar = session.find('#bar') # from Capybara::Node::Finders
12
+ # bar.select('Baz', :from => 'Quox') # from Capybara::Node::Actions
13
+ #
14
+ # {Capybara::Element} also has access to HTML attributes and other properties of the
15
+ # element:
16
+ #
17
+ # bar.value
18
+ # bar.text
19
+ # bar[:title]
20
+ #
21
+ # @see Capybara::Node
22
+ #
23
+ class Element < Base
24
+
25
+ def initialize(session, base, parent, selector)
26
+ super(session, base)
27
+ @parent = parent
28
+ @selector = selector
29
+ end
30
+
31
+ ##
32
+ #
33
+ # @return [Object] The native element from the driver, this allows access to driver specific methods
34
+ #
35
+ def native
36
+ wait_until { base.native }
37
+ end
38
+
39
+ ##
40
+ #
41
+ # @return [String] The text of the element
42
+ #
43
+ def text
44
+ wait_until { base.text }
45
+ end
46
+
47
+ ##
48
+ #
49
+ # Retrieve the given attribute
50
+ #
51
+ # element[:title] # => HTML title attribute
52
+ #
53
+ # @param [Symbol] attribute The attribute to retrieve
54
+ # @return [String] The value of the attribute
55
+ #
56
+ def [](attribute)
57
+ wait_until { base[attribute] }
58
+ end
59
+
60
+ ##
61
+ #
62
+ # @return [String] The value of the form element
63
+ #
64
+ def value
65
+ wait_until { base.value }
66
+ end
67
+
68
+ ##
69
+ #
70
+ # Set the value of the form element to the given value.
71
+ #
72
+ # @param [String] value The new value
73
+ #
74
+ def set(value)
75
+ wait_until { base.set(value) }
76
+ end
77
+
78
+ ##
79
+ #
80
+ # Select this node if is an option element inside a select tag
81
+ #
82
+ def select_option
83
+ wait_until { base.select_option }
84
+ end
85
+
86
+ ##
87
+ #
88
+ # Unselect this node if is an option element inside a multiple select tag
89
+ #
90
+ def unselect_option
91
+ wait_until { base.unselect_option }
92
+ end
93
+
94
+ ##
95
+ #
96
+ # Click the Element
97
+ #
98
+ def click
99
+ wait_until { base.click }
100
+ end
101
+
102
+ ##
103
+ #
104
+ # @return [String] The tag name of the element
105
+ #
106
+ def tag_name
107
+ wait_until { base.tag_name }
108
+ end
109
+
110
+ ##
111
+ #
112
+ # Whether or not the element is visible. Not all drivers support CSS, so
113
+ # the result may be inaccurate.
114
+ #
115
+ # @return [Boolean] Whether the element is visible
116
+ #
117
+ def visible?
118
+ wait_until { base.visible? }
119
+ end
120
+
121
+ ##
122
+ #
123
+ # Whether or not the element is checked.
124
+ #
125
+ # @return [Boolean] Whether the element is checked
126
+ #
127
+ def checked?
128
+ wait_until { base.checked? }
129
+ end
130
+
131
+ ##
132
+ #
133
+ # Whether or not the element is selected.
134
+ #
135
+ # @return [Boolean] Whether the element is selected
136
+ #
137
+ def selected?
138
+ wait_until { base.selected? }
139
+ end
140
+
141
+ ##
142
+ #
143
+ # An XPath expression describing where on the page the element can be found
144
+ #
145
+ # @return [String] An XPath expression
146
+ #
147
+ def path
148
+ wait_until { base.path }
149
+ end
150
+
151
+ ##
152
+ #
153
+ # Trigger any event on the current element, for example mouseover or focus
154
+ # events. Does not work in Selenium.
155
+ #
156
+ # @param [String] event The name of the event to trigger
157
+ #
158
+ def trigger(event)
159
+ wait_until { base.trigger(event) }
160
+ end
161
+
162
+ ##
163
+ #
164
+ # Drag the element to the given other element.
165
+ #
166
+ # source = page.find('#foo')
167
+ # target = page.find('#bar')
168
+ # source.drag_to(target)
169
+ #
170
+ # @param [Capybara::Element] node The element to drag to
171
+ #
172
+ def drag_to(node)
173
+ wait_until { base.drag_to(node.base) }
174
+ end
175
+
176
+ def find(*args)
177
+ wait_until { super }
178
+ end
179
+
180
+ def first(*args)
181
+ wait_until { super }
182
+ end
183
+
184
+ def all(*args)
185
+ wait_until { super }
186
+ end
187
+
188
+ def reload
189
+ reloaded = parent.reload.first(@selector.name, @selector.locator, @selector.options)
190
+ @base = reloaded.base if reloaded
191
+ self
192
+ end
193
+
194
+ def inspect
195
+ %(#<Capybara::Element tag="#{tag_name}" path="#{path}">)
196
+ rescue NotSupportedByDriverError
197
+ %(#<Capybara::Element tag="#{tag_name}">)
198
+ end
199
+ end
200
+ end
201
+ end