rcarvalho-capybara 0.4.1.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.
Files changed (100) hide show
  1. data/History.txt +202 -0
  2. data/README.rdoc +540 -0
  3. data/lib/capybara.rb +231 -0
  4. data/lib/capybara/cucumber.rb +32 -0
  5. data/lib/capybara/driver/base.rb +60 -0
  6. data/lib/capybara/driver/celerity_driver.rb +164 -0
  7. data/lib/capybara/driver/culerity_driver.rb +26 -0
  8. data/lib/capybara/driver/node.rb +78 -0
  9. data/lib/capybara/driver/rack_test_driver.rb +303 -0
  10. data/lib/capybara/driver/selenium_driver.rb +165 -0
  11. data/lib/capybara/dsl.rb +109 -0
  12. data/lib/capybara/node/actions.rb +160 -0
  13. data/lib/capybara/node/base.rb +47 -0
  14. data/lib/capybara/node/document.rb +17 -0
  15. data/lib/capybara/node/element.rb +182 -0
  16. data/lib/capybara/node/finders.rb +201 -0
  17. data/lib/capybara/node/matchers.rb +391 -0
  18. data/lib/capybara/node/simple.rb +116 -0
  19. data/lib/capybara/rails.rb +17 -0
  20. data/lib/capybara/rspec.rb +18 -0
  21. data/lib/capybara/selector.rb +70 -0
  22. data/lib/capybara/server.rb +90 -0
  23. data/lib/capybara/session.rb +281 -0
  24. data/lib/capybara/spec/driver.rb +243 -0
  25. data/lib/capybara/spec/fixtures/capybara.jpg +0 -0
  26. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  27. data/lib/capybara/spec/public/jquery-ui.js +35 -0
  28. data/lib/capybara/spec/public/jquery.js +19 -0
  29. data/lib/capybara/spec/public/test.js +33 -0
  30. data/lib/capybara/spec/session.rb +110 -0
  31. data/lib/capybara/spec/session/all_spec.rb +78 -0
  32. data/lib/capybara/spec/session/attach_file_spec.rb +70 -0
  33. data/lib/capybara/spec/session/check_spec.rb +65 -0
  34. data/lib/capybara/spec/session/choose_spec.rb +26 -0
  35. data/lib/capybara/spec/session/click_button_spec.rb +252 -0
  36. data/lib/capybara/spec/session/click_link_or_button_spec.rb +36 -0
  37. data/lib/capybara/spec/session/click_link_spec.rb +113 -0
  38. data/lib/capybara/spec/session/current_url_spec.rb +15 -0
  39. data/lib/capybara/spec/session/fill_in_spec.rb +119 -0
  40. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  41. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  42. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  43. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  44. data/lib/capybara/spec/session/find_spec.rb +121 -0
  45. data/lib/capybara/spec/session/first_spec.rb +72 -0
  46. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  47. data/lib/capybara/spec/session/has_content_spec.rb +106 -0
  48. data/lib/capybara/spec/session/has_css_spec.rb +213 -0
  49. data/lib/capybara/spec/session/has_field_spec.rb +156 -0
  50. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  51. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  52. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  53. data/lib/capybara/spec/session/has_table_spec.rb +96 -0
  54. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  55. data/lib/capybara/spec/session/headers.rb +19 -0
  56. data/lib/capybara/spec/session/javascript.rb +223 -0
  57. data/lib/capybara/spec/session/response_code.rb +19 -0
  58. data/lib/capybara/spec/session/select_spec.rb +105 -0
  59. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  60. data/lib/capybara/spec/session/unselect_spec.rb +61 -0
  61. data/lib/capybara/spec/session/within_spec.rb +160 -0
  62. data/lib/capybara/spec/test_app.rb +117 -0
  63. data/lib/capybara/spec/views/buttons.erb +4 -0
  64. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  65. data/lib/capybara/spec/views/form.erb +348 -0
  66. data/lib/capybara/spec/views/frame_one.erb +8 -0
  67. data/lib/capybara/spec/views/frame_two.erb +8 -0
  68. data/lib/capybara/spec/views/popup_one.erb +8 -0
  69. data/lib/capybara/spec/views/popup_two.erb +8 -0
  70. data/lib/capybara/spec/views/postback.erb +13 -0
  71. data/lib/capybara/spec/views/tables.erb +122 -0
  72. data/lib/capybara/spec/views/with_html.erb +69 -0
  73. data/lib/capybara/spec/views/with_js.erb +39 -0
  74. data/lib/capybara/spec/views/with_scope.erb +36 -0
  75. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  76. data/lib/capybara/spec/views/within_frames.erb +10 -0
  77. data/lib/capybara/spec/views/within_popups.erb +25 -0
  78. data/lib/capybara/util/save_and_open_page.rb +40 -0
  79. data/lib/capybara/util/timeout.rb +27 -0
  80. data/lib/capybara/version.rb +3 -0
  81. data/spec/basic_node_spec.rb +77 -0
  82. data/spec/capybara_spec.rb +46 -0
  83. data/spec/driver/celerity_driver_spec.rb +13 -0
  84. data/spec/driver/culerity_driver_spec.rb +14 -0
  85. data/spec/driver/rack_test_driver_spec.rb +84 -0
  86. data/spec/driver/remote_culerity_driver_spec.rb +22 -0
  87. data/spec/driver/remote_selenium_driver_spec.rb +16 -0
  88. data/spec/driver/selenium_driver_spec.rb +14 -0
  89. data/spec/dsl_spec.rb +157 -0
  90. data/spec/rspec_spec.rb +47 -0
  91. data/spec/save_and_open_page_spec.rb +159 -0
  92. data/spec/server_spec.rb +85 -0
  93. data/spec/session/celerity_session_spec.rb +24 -0
  94. data/spec/session/culerity_session_spec.rb +26 -0
  95. data/spec/session/rack_test_session_spec.rb +44 -0
  96. data/spec/session/selenium_session_spec.rb +26 -0
  97. data/spec/spec_helper.rb +40 -0
  98. data/spec/string_spec.rb +77 -0
  99. data/spec/timeout_spec.rb +28 -0
  100. metadata +343 -0
@@ -0,0 +1,109 @@
1
+ require 'capybara'
2
+
3
+ module Capybara
4
+ class << self
5
+ attr_writer :default_driver, :current_driver, :javascript_driver
6
+
7
+ attr_accessor :app
8
+
9
+ ##
10
+ #
11
+ # @return [Symbol] The name of the driver to use by default
12
+ #
13
+ def default_driver
14
+ @default_driver || :rack_test
15
+ end
16
+
17
+ ##
18
+ #
19
+ # @return [Symbol] The name of the driver currently in use
20
+ #
21
+ def current_driver
22
+ @current_driver || default_driver
23
+ end
24
+ alias_method :mode, :current_driver
25
+
26
+ ##
27
+ #
28
+ # @return [Symbol] The name of the driver used when JavaScript is needed
29
+ #
30
+ def javascript_driver
31
+ @javascript_driver || :selenium
32
+ end
33
+
34
+ ##
35
+ #
36
+ # Use the default driver as the current driver
37
+ #
38
+ def use_default_driver
39
+ @current_driver = nil
40
+ end
41
+
42
+ ##
43
+ #
44
+ # Yield a block using a specific driver
45
+ #
46
+ def using_driver(driver)
47
+ Capybara.current_driver = driver
48
+ yield
49
+ ensure
50
+ Capybara.use_default_driver
51
+ end
52
+
53
+ ##
54
+ #
55
+ # The current Capybara::Session base on what is set as Capybara.app and Capybara.current_driver
56
+ #
57
+ # @return [Capybara::Session] The currently used session
58
+ #
59
+ def current_session
60
+ session_pool["#{current_driver}#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
61
+ end
62
+
63
+ ##
64
+ #
65
+ # Reset sessions, cleaning out the pool of sessions. This will remove any session information such
66
+ # as cookies.
67
+ #
68
+ def reset_sessions!
69
+ session_pool.each { |mode, session| session.reset! }
70
+ end
71
+ alias_method :reset!, :reset_sessions!
72
+
73
+ private
74
+
75
+ def session_pool
76
+ @session_pool ||= {}
77
+ end
78
+ end
79
+
80
+ extend(self)
81
+
82
+ ##
83
+ #
84
+ # Shortcut to accessing the current session. This is useful when Capybara is included in a
85
+ # class or module.
86
+ #
87
+ # class MyClass
88
+ # include Capybara
89
+ #
90
+ # def has_header?
91
+ # page.has_css?('h1')
92
+ # end
93
+ # end
94
+ #
95
+ # @return [Capybara::Session] The current session object
96
+ #
97
+ def page
98
+ Capybara.current_session
99
+ end
100
+
101
+ Session::DSL_METHODS.each do |method|
102
+ class_eval <<-RUBY, __FILE__, __LINE__+1
103
+ def #{method}(*args, &block)
104
+ page.#{method}(*args, &block)
105
+ end
106
+ RUBY
107
+ end
108
+
109
+ end
@@ -0,0 +1,160 @@
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] locator Which check box to uncheck
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 select a particular option from it. If the select
125
+ # box is a multiple select, +select+ can be called multiple times to select more than
126
+ # one option. The select box can be found via its name, id or label text.
127
+ #
128
+ # page.uncheck('German')
129
+ #
130
+ # @param [String] locator Which check box to uncheck
131
+ #
132
+ def unselect(value, options={})
133
+ if options.has_key?(:from)
134
+ no_select_msg = "cannot unselect option, no select box with id, name, or label '#{options[:from]}' found"
135
+ no_option_msg = "cannot unselect option, no option with text '#{value}' in select box '#{options[:from]}'"
136
+ select = find(:xpath, XPath::HTML.select(options[:from]), :message => no_select_msg)
137
+ select.find(:xpath, XPath::HTML.option(value), :message => no_option_msg).unselect_option
138
+ else
139
+ no_option_msg = "cannot unselect option, no option with text '#{value}'"
140
+ find(:xpath, XPath::HTML.option(value), :message => no_option_msg).unselect_option
141
+ end
142
+ end
143
+
144
+ ##
145
+ #
146
+ # Find a file field on the page and attach a file given its path. The file field can
147
+ # be found via its name, id or label text.
148
+ #
149
+ # page.attach_file(locator, '/path/to/file.png')
150
+ #
151
+ # @param [String] locator Which field to attach the file to
152
+ # @param [String] path The path of the file that will be attached
153
+ #
154
+ def attach_file(locator, path)
155
+ msg = "cannot attach file, no file field with id, name, or label '#{locator}' found"
156
+ find(:xpath, XPath::HTML.file_field(locator), :message => msg).set(path)
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,47 @@
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
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
+ protected
37
+
38
+ def wait?
39
+ driver.wait?
40
+ end
41
+
42
+ def driver
43
+ session.driver
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,17 @@
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
+ end
16
+ end
17
+ end
@@ -0,0 +1,182 @@
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
+ ##
26
+ #
27
+ # @return [Object] The native element from the driver, this allows access to driver specific methods
28
+ #
29
+ def native
30
+ base.native
31
+ end
32
+
33
+ ##
34
+ #
35
+ # @return [String] The text of the element
36
+ #
37
+ def text
38
+ base.text
39
+ end
40
+
41
+ ##
42
+ #
43
+ # Retrieve the given attribute
44
+ #
45
+ # element[:title] # => HTML title attribute
46
+ #
47
+ # @param [Symbol] attribute The attribute to retrieve
48
+ # @return [String] The value of the attribute
49
+ #
50
+ def [](attribute)
51
+ base[attribute]
52
+ end
53
+
54
+ ##
55
+ #
56
+ # @return [String] The value of the form element
57
+ #
58
+ def value
59
+ base.value
60
+ end
61
+
62
+ ##
63
+ #
64
+ # Set the value of the form element to the given value.
65
+ #
66
+ # @param [String] value The new value
67
+ #
68
+ def set(value)
69
+ base.set(value)
70
+ end
71
+
72
+ ##
73
+ #
74
+ # Select this node if is an option element inside a select tag
75
+ #
76
+ def select_option
77
+ base.select_option
78
+ end
79
+
80
+ ##
81
+ #
82
+ # Unselect this node if is an option element inside a multiple select tag
83
+ #
84
+ def unselect_option
85
+ base.unselect_option
86
+ end
87
+
88
+ ##
89
+ #
90
+ # Click the Element
91
+ #
92
+ def click
93
+ base.click
94
+ end
95
+
96
+ ##
97
+ #
98
+ # @return [String] The tag name of the element
99
+ #
100
+ def tag_name
101
+ base.tag_name
102
+ end
103
+
104
+ ##
105
+ #
106
+ # Whether or not the element is visible. Not all drivers support CSS, so
107
+ # the result may be inaccurate.
108
+ #
109
+ # @return [Boolean] Whether the element is visible
110
+ #
111
+ def visible?
112
+ base.visible?
113
+ end
114
+
115
+ ##
116
+ #
117
+ # Whether or not the element is checked.
118
+ #
119
+ # @return [Boolean] Whether the element is checked
120
+ #
121
+ def checked?
122
+ base.checked?
123
+ end
124
+
125
+ ##
126
+ #
127
+ # Whether or not the element is selected.
128
+ #
129
+ # @return [Boolean] Whether the element is selected
130
+ #
131
+ def selected?
132
+ base.selected?
133
+ end
134
+
135
+ ##
136
+ #
137
+ # An XPath expression describing where on the page the element can be found
138
+ #
139
+ # @return [String] An XPath expression
140
+ #
141
+ def path
142
+ base.path
143
+ end
144
+
145
+ ##
146
+ #
147
+ # Trigger any event on the current element, for example mouseover or focus
148
+ # events. Does not work in Selenium.
149
+ #
150
+ # @param [String] event The name of the event to trigger
151
+ #
152
+ def trigger(event)
153
+ base.trigger(event)
154
+ end
155
+
156
+ ##
157
+ #
158
+ # Drag the element to the given other element.
159
+ #
160
+ # source = page.find('#foo')
161
+ # target = page.find('#bar')
162
+ # source.drag_to(target)
163
+ #
164
+ # @param [Capybara::Element] node The element to drag to
165
+ #
166
+ def drag_to(node)
167
+ base.drag_to(node.base)
168
+ end
169
+
170
+ def drag_to_location(right,down)
171
+ base.drag_to_location(right,down)
172
+ end
173
+
174
+ def inspect
175
+ %(#<Capybara::Element tag="#{tag_name}" path="#{path}">)
176
+ rescue NotSupportedByDriverError
177
+ %(#<Capybara::Element tag="#{tag_name}">)
178
+ end
179
+
180
+ end
181
+ end
182
+ end