capybara-rails-2-2 0.4.1.1

Sign up to get free protection for your applications and to get access to all the features.
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 +74 -0
  9. data/lib/capybara/driver/rack_test_driver.rb +303 -0
  10. data/lib/capybara/driver/selenium_driver.rb +161 -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 +178 -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 +16 -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 +360 -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,178 @@
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 inspect
171
+ %(#<Capybara::Element tag="#{tag_name}" path="#{path}">)
172
+ rescue NotSupportedByDriverError
173
+ %(#<Capybara::Element tag="#{tag_name}">)
174
+ end
175
+
176
+ end
177
+ end
178
+ end