capybara-ui 0.10.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/lib/capybara/ui.rb +33 -0
  3. data/lib/capybara/ui/assertions.rb +21 -0
  4. data/lib/{capybara-ui → capybara/ui}/capybara.rb +0 -0
  5. data/lib/capybara/ui/checkpoint.rb +113 -0
  6. data/lib/capybara/ui/conversions.rb +33 -0
  7. data/lib/capybara/ui/cucumber.rb +5 -0
  8. data/lib/capybara/ui/dsl.rb +109 -0
  9. data/lib/capybara/ui/instance_conversions.rb +21 -0
  10. data/lib/{capybara-ui → capybara/ui}/matchers.rb +4 -4
  11. data/lib/capybara/ui/optional_dependencies.rb +7 -0
  12. data/lib/capybara/ui/rails.rb +5 -0
  13. data/lib/capybara/ui/rails/role.rb +11 -0
  14. data/lib/capybara/ui/role.rb +21 -0
  15. data/lib/capybara/ui/text_table.rb +109 -0
  16. data/lib/capybara/ui/text_table/cell_text.rb +9 -0
  17. data/lib/capybara/ui/text_table/mapping.rb +42 -0
  18. data/lib/capybara/ui/text_table/transformations.rb +15 -0
  19. data/lib/capybara/ui/text_table/void_mapping.rb +10 -0
  20. data/lib/capybara/ui/version.rb +5 -0
  21. data/lib/capybara/ui/widgets.rb +63 -0
  22. data/lib/capybara/ui/widgets/check_box.rb +28 -0
  23. data/lib/capybara/ui/widgets/cucumber_methods.rb +75 -0
  24. data/lib/capybara/ui/widgets/document.rb +21 -0
  25. data/lib/capybara/ui/widgets/dsl.rb +49 -0
  26. data/lib/capybara/ui/widgets/field.rb +24 -0
  27. data/lib/capybara/ui/widgets/field_group.rb +331 -0
  28. data/lib/capybara/ui/widgets/form.rb +28 -0
  29. data/lib/capybara/ui/widgets/list.rb +202 -0
  30. data/lib/capybara/ui/widgets/list_item.rb +24 -0
  31. data/lib/capybara/ui/widgets/parts/container.rb +48 -0
  32. data/lib/capybara/ui/widgets/parts/struct.rb +119 -0
  33. data/lib/capybara/ui/widgets/radio_button.rb +64 -0
  34. data/lib/capybara/ui/widgets/select.rb +59 -0
  35. data/lib/capybara/ui/widgets/string_value.rb +45 -0
  36. data/lib/capybara/ui/widgets/table.rb +78 -0
  37. data/lib/capybara/ui/widgets/text_field.rb +29 -0
  38. data/lib/capybara/ui/widgets/widget.rb +394 -0
  39. data/lib/capybara/ui/widgets/widget/node_filter.rb +50 -0
  40. data/lib/capybara/ui/widgets/widget_class.rb +13 -0
  41. data/lib/capybara/ui/widgets/widget_name.rb +58 -0
  42. metadata +47 -43
  43. data/lib/capybara-ui.rb +0 -31
  44. data/lib/capybara-ui/assertions.rb +0 -19
  45. data/lib/capybara-ui/checkpoint.rb +0 -111
  46. data/lib/capybara-ui/conversions.rb +0 -31
  47. data/lib/capybara-ui/cucumber.rb +0 -5
  48. data/lib/capybara-ui/dsl.rb +0 -107
  49. data/lib/capybara-ui/instance_conversions.rb +0 -19
  50. data/lib/capybara-ui/optional_dependencies.rb +0 -5
  51. data/lib/capybara-ui/rails.rb +0 -5
  52. data/lib/capybara-ui/rails/role.rb +0 -9
  53. data/lib/capybara-ui/role.rb +0 -19
  54. data/lib/capybara-ui/text_table.rb +0 -107
  55. data/lib/capybara-ui/text_table/cell_text.rb +0 -7
  56. data/lib/capybara-ui/text_table/mapping.rb +0 -40
  57. data/lib/capybara-ui/text_table/transformations.rb +0 -13
  58. data/lib/capybara-ui/text_table/void_mapping.rb +0 -8
  59. data/lib/capybara-ui/version.rb +0 -3
  60. data/lib/capybara-ui/widgets.rb +0 -61
  61. data/lib/capybara-ui/widgets/check_box.rb +0 -26
  62. data/lib/capybara-ui/widgets/cucumber_methods.rb +0 -73
  63. data/lib/capybara-ui/widgets/document.rb +0 -19
  64. data/lib/capybara-ui/widgets/dsl.rb +0 -47
  65. data/lib/capybara-ui/widgets/field.rb +0 -22
  66. data/lib/capybara-ui/widgets/field_group.rb +0 -329
  67. data/lib/capybara-ui/widgets/form.rb +0 -26
  68. data/lib/capybara-ui/widgets/list.rb +0 -200
  69. data/lib/capybara-ui/widgets/list_item.rb +0 -22
  70. data/lib/capybara-ui/widgets/parts/container.rb +0 -46
  71. data/lib/capybara-ui/widgets/parts/struct.rb +0 -117
  72. data/lib/capybara-ui/widgets/radio_button.rb +0 -62
  73. data/lib/capybara-ui/widgets/select.rb +0 -57
  74. data/lib/capybara-ui/widgets/string_value.rb +0 -43
  75. data/lib/capybara-ui/widgets/table.rb +0 -76
  76. data/lib/capybara-ui/widgets/text_field.rb +0 -27
  77. data/lib/capybara-ui/widgets/widget.rb +0 -392
  78. data/lib/capybara-ui/widgets/widget/node_filter.rb +0 -48
  79. data/lib/capybara-ui/widgets/widget_class.rb +0 -11
  80. data/lib/capybara-ui/widgets/widget_name.rb +0 -56
@@ -1,73 +0,0 @@
1
- module CapybaraUI
2
- module CucumberMethods
3
- begin
4
- require 'cucumber/ast/table'
5
-
6
- # Compares this widget with the given Cucumber +table+.
7
- #
8
- # === Example
9
- #
10
- # Then(/^some step that takes in a cucumber table$/) do |table|
11
- # widget(:my_widget).diff table
12
- # end
13
- #
14
- # Pass +ignore_case: true+, for a case-insensitive table match
15
- #
16
- # === Example
17
- #
18
- # Then(/^some step that takes in a cucumber table$/) do |table|
19
- # widget(:my_widget).diff table, ignore_case: true
20
- # end
21
- #
22
- def diff(table, wait_time = Capybara.default_max_wait_time, ignore_case: false)
23
- to_table = self.to_table
24
-
25
- if ignore_case == true
26
- table = downcase_table(table)
27
- to_table = downcase_array(to_table)
28
- end
29
-
30
- table.diff!(to_table) || true
31
- end
32
-
33
- private
34
-
35
- def downcase_table(table)
36
- new_cucumber_table downcase_array(table.raw)
37
- end
38
-
39
- def downcase_array(array)
40
- array.map do |item|
41
- case item
42
- when String
43
- item.downcase
44
- when Array
45
- downcase_array(item)
46
- when Hash
47
- downcase_hash(item)
48
- end
49
- end
50
- end
51
-
52
- def downcase_hash(hash)
53
- hash.each do |k, v|
54
- case v
55
- when String
56
- hash[k] = v.downcase
57
- when Array
58
- downcase_array(v)
59
- when Hash
60
- downcase_hash(v)
61
- end
62
- end
63
- end
64
-
65
- def new_cucumber_table(table)
66
- Cucumber::Ast::Table.new(table)
67
- end
68
-
69
- rescue LoadError
70
- # *crickets*
71
- end
72
- end
73
- end
@@ -1,19 +0,0 @@
1
- module CapybaraUI
2
- class Document
3
- include WidgetParts::Container
4
-
5
- def initialize(widget_lookup_scope)
6
- self.widget_lookup_scope = widget_lookup_scope or raise 'No scope given'
7
- end
8
-
9
- def root
10
- Capybara.current_session
11
- end
12
-
13
- def body
14
- xml = Nokogiri::HTML(Capybara.page.body).to_xml
15
-
16
- Nokogiri::XML(xml, &:noblanks).to_xhtml
17
- end
18
- end
19
- end
@@ -1,47 +0,0 @@
1
- module CapybaraUI
2
- module Widgets
3
- module DSL
4
- # Declares a new form widget.
5
- #
6
- # See features/role.feature.
7
- def form(name, *rest, &block)
8
- widget name, *rest, CapybaraUI::Form, &block
9
- end
10
-
11
- # Declares a new list widget.
12
- #
13
- # See features/roles/list.feature.
14
- def list(name, *rest, &block)
15
- widget name, *rest, CapybaraUI::List, &block
16
- end
17
-
18
- # Declares a new child widget.
19
- #
20
- # See https://github.com/mojotech/capybara-ui/blob/master/features/roles/widget.feature
21
- def widget(name, selector_or_parent, parent = Widget, &block)
22
- raise ArgumentError, "`#{name}' is a reserved name" \
23
- if WidgetParts::Container.instance_methods.include?(name.to_sym)
24
-
25
- case selector_or_parent
26
- when String, Array, Proc
27
- selector, type = selector_or_parent, parent
28
- when Class
29
- selector, type = selector_or_parent.selector, selector_or_parent
30
- else
31
- raise ArgumentError, "wrong number of arguments (#{rest.size} for 1)"
32
- end
33
-
34
- raise TypeError, "can't convert `#{type}' to Widget" \
35
- unless type.methods.include?(:selector)
36
-
37
- raise ArgumentError, "missing selector" unless selector || type.selector
38
-
39
- child = WidgetClass.new(selector, type, &block)
40
-
41
- const_set(CapybaraUI::WidgetName.new(name).to_sym, child)
42
-
43
- child
44
- end
45
- end
46
- end
47
- end
@@ -1,22 +0,0 @@
1
- module CapybaraUI
2
- # A form field.
3
- class Field < Widget
4
- def self.root(selector)
5
- super String === selector ? [:field, selector] : selector
6
- end
7
-
8
- # @return This field's value.
9
- #
10
- # Override this to get the actual value.
11
- def get
12
- raise NotImplementedError
13
- end
14
-
15
- # Sets the field value.
16
- #
17
- # Override this to set the value.
18
- def set(value)
19
- raise NotImplementedError
20
- end
21
- end
22
- end
@@ -1,329 +0,0 @@
1
- module CapybaraUI
2
- # A group of form fields.
3
- #
4
- # @todo Explain how to use locators when defining fields, including what
5
- # happens when locators are omitted.
6
- class FieldGroup < Widget
7
- root 'fieldset'
8
-
9
- def self.default_locator(type = nil, &block)
10
- alias_method :name_to_locator, type if type
11
-
12
- define_method :name_to_locator, &block if block
13
- end
14
-
15
- # The names of all the fields that belong to this field group.
16
- #
17
- # Field names are automatically added to this group as long as you use
18
- # the field definition macros.
19
- #
20
- # @return [Set] the field names.
21
- #
22
- # @see field
23
- def self.field_names
24
- @field_names ||= Set.new
25
- end
26
-
27
- # @!group Field definition macros
28
-
29
- # Creates a new checkbox accessor.
30
- #
31
- # Adds the following methods to the widget:
32
- #
33
- # <name>:: Gets the current checkbox state, as a boolean. Returns +true+
34
- # if the corresponding check box is checked, +false+ otherwise.
35
- # <name>=:: Sets the current checkbox state. Pass +true+ to check the
36
- # checkbox, +false+ otherwise.
37
- #
38
- # @example
39
- # # Given the following HTML:
40
- # #
41
- # # <form>
42
- # # <p>
43
- # # <label for="checked-box">
44
- # # <input type="checkbox" value="1" id="checked-box" checked>
45
- # # </p>
46
- # # <p>
47
- # # <label for="unchecked-box">
48
- # # <input type="checkbox" value="1" id="unchecked-box">
49
- # # </p>
50
- # # </form>
51
- # class MyFieldGroup < CapybaraUI::FieldGroup
52
- # root 'form'
53
- #
54
- # check_box :checked_box, 'checked-box'
55
- # check_box :unchecked_box, 'unchecked-box'
56
- # end
57
- #
58
- # form = widget(:my_field_group)
59
- #
60
- # form.checked_box #=> true
61
- # form.unchecked_box #=> false
62
- #
63
- # form.unchecked_box = true
64
- # form.unchecked_box #=> true
65
- #
66
- # @param name the name of the checkbox accessor.
67
- # @param locator the locator for the checkbox. If +nil+ the locator will
68
- # be derived from +name+.
69
- #
70
- # @todo Handle checkbox access when the field is disabled (raise an
71
- # exception?)
72
- def self.check_box(name, locator = nil)
73
- field name, locator, CheckBox
74
- end
75
-
76
- # Defines a new field.
77
- #
78
- # @param name the name of the field accessor.
79
- # @param locator the field locator.
80
- # @param type the field class name.
81
- #
82
- # @api private
83
- def self.field(name, locator, type)
84
- raise TypeError, "can't convert `#{name}' to Symbol" \
85
- unless name.respond_to?(:to_sym)
86
-
87
- field_names << name.to_sym
88
-
89
- label = name.to_s.gsub(/_/, ' ').capitalize
90
- locator ||= label
91
-
92
- widget name, locator, type do
93
- define_method :label do
94
- label
95
- end
96
- end
97
-
98
- define_method "#{name}=" do |val|
99
- widget(name).set val
100
- end
101
-
102
- define_method name do
103
- widget(name).get
104
- end
105
- end
106
-
107
- # Creates a new select accessor.
108
- #
109
- # Adds the following methods to the widget:
110
- #
111
- # <name>:: Gets the text of the current selected option, or +nil+,
112
- # if no option is selected.
113
- # <name>_value:: Gets the value of the current selected option, or
114
- # +nil+, if no option is selected.
115
- # <name>=:: Selects an option on the current select. Pass the text or
116
- # value of the option you want to select.
117
- #
118
- # @example
119
- # # Given the following HTML:
120
- # #
121
- # # <form>
122
- # # <p>
123
- # # <label for="selected">
124
- # # <select id="selected">
125
- # # <option value ="1s" selected>Selected option</option>
126
- # # <option value ="2s">Selected option two</option>
127
- # # </select>
128
- # # </p>
129
- # # <p>
130
- # # <label for="unselected">
131
- # # <select id="unselected">
132
- # # <option value="1u">Unselected option</option>
133
- # # <option value="2u">Unselected option two</option>
134
- # # </select>
135
- # # </p>
136
- # # </form>
137
- # class MyFieldGroup < CapybaraUI::FieldGroup
138
- # root 'form'
139
- #
140
- # select :selected, 'selected'
141
- # select :unselected, 'unselected'
142
- # end
143
- #
144
- # form = widget(:my_field_group)
145
- #
146
- # form.selected #=> "Selected option"
147
- # form.selected_value #=> "1s"
148
- #
149
- # # Select by text
150
- # form.unselected #=> nil
151
- # form.unselected = "Unselected option"
152
- # form.unselected #=> "Unselected option"
153
- #
154
- # # Select by value
155
- # form.unselected = "2u"
156
- # form.unselected #=> "Unselected option two"
157
- # form.unselected_value #=> "2u"
158
- #
159
- # @param name the name of the select accessor.
160
- # @param locator the locator for the select. If +nil+ the locator will
161
- # be derived from +name+.
162
- #
163
- # @todo Handle select access when the field is disabled (raise an
164
- # exception?)
165
- # @todo Raise an exception when an option doesn't exist.
166
- # @todo Allow passing the option value to set an option.
167
- # @todo Ensure an option with no text returns the empty string.
168
- # @todo What to do when +nil+ is passed to the writer?
169
- def self.select(name, locator = nil)
170
- field name, locator, Select
171
-
172
- define_method "#{name}_value" do
173
- widget(name).value
174
- end
175
- end
176
-
177
- # Creates a new radio button group accessor.
178
- #
179
- # Adds the following methods to the widget:
180
- #
181
- # <name>:: Gets the text of the current checked button, or +nil+,
182
- # if no button is checked.
183
- # <name>_value:: Gets the value of the current checked button, or +nil+,
184
- # if no button is checked.
185
- # <name>=:: Checks a button in the current container. Pass the text of
186
- # the label or the id or value of the button you want to choose.
187
- #
188
- # @example
189
- # # Given the following HTML:
190
- # #
191
- # # <form>
192
- # # <p class='checked'>
193
- # # <label for="checked">Checked button</label>
194
- # # <input type="radio" id="checked" name="c" value="checked_value" checked>
195
- # # <label for="checked_two">Checked button two</label>
196
- # # <input type="radio" id="checked_two" name="c" value="checked_two_value">
197
- # # </p>
198
- # # <p class='unchecked'>
199
- # # <label for="unchecked">Unchecked button</label>
200
- # # <input type="radio" id="unchecked" name="u" value="unchecked_value_one">
201
- # # <label for="unchecked_two">Unchecked button two</label>
202
- # # <input type="radio" id="unchecked_two" name="u" value="unchecked_value_two">
203
- # # </p>
204
- # # </form>
205
- # class MyFieldGroup < CapybaraUI::FieldGroup
206
- # root 'form'
207
- #
208
- # radio_button :checked, '.checked'
209
- # radio_button :unchecked, '.unchecked'
210
- # end
211
- #
212
- # form = widget(:my_field_group)
213
- #
214
- # form.checked #=> "Checked button"
215
- # form.unchecked #=> nil
216
- #
217
- # form.unchecked = "Unchecked button" # Choose by label text
218
- # form.unchecked #=> "Unchecked button"
219
- # form.unchecked_value #=> "unchecked_value_one"
220
- #
221
- # form.unchecked = "unchecked_two" # Choose by id
222
- # form.unchecked #=> "Unchecked button two"
223
- # form.unchecked_value #=> "unchecked_value_two"
224
- #
225
- # form.unchecked = "unchecked_value_one" # Choose by value
226
- # form.unchecked #=> "Unchecked button"
227
- #
228
- # @param name the name of the radio_button group accessor.
229
- # @param locator the locator for the radio_button group.
230
- #
231
- def self.radio_button(name, locator = nil)
232
- field name, locator, RadioButton
233
-
234
- define_method "#{name}_value" do
235
- widget(name).value
236
- end
237
- end
238
-
239
- # Creates a new text field accessor.
240
- #
241
- # Adds the following methods to the widget:
242
- #
243
- # <name>:: Returns the current text field value, or +nil+ if no value
244
- # has been set.
245
- # <name>=:: Sets the current text field value.
246
- # <name>? Returns +true+ if the current text field has content or
247
- # +false+ otherwise
248
- #
249
- # @example
250
- # # Given the following HTML:
251
- # #
252
- # # <form>
253
- # # <p>
254
- # # <label for="text-field">
255
- # # <input type="text" value="Content" id="text-field">
256
- # # </p>
257
- # # <p>
258
- # # <label for="empty-field">
259
- # # <input type="text" id="empty-field">
260
- # # </p>
261
- # # </form>
262
- # class MyFieldGroup < CapybaraUI::FieldGroup
263
- # root 'form'
264
- #
265
- # text_field :filled_field, 'text-field'
266
- # text_field :empty_field, 'empty-field'
267
- # end
268
- #
269
- # form = widget(:my_field_group)
270
- #
271
- # form.filled_field #=> "Content"
272
- # form.empty_field #=> nil
273
- #
274
- # form.filled_field? #=> true
275
- # form.empty_field? #=> false
276
- #
277
- # form.empty_field = "Not anymore"
278
- # form.empty_field #=> "Not anymore"
279
- #
280
- # @param name the name of the text field accessor.
281
- # @param locator the locator for the text field. If +nil+ the locator
282
- # will be derived from +name+.
283
- #
284
- # @todo Handle text field access when the field is disabled (raise an
285
- # exception?)
286
- def self.text_field(name, locator = nil)
287
- define_method "#{name}?" do
288
- widget(name).content?
289
- end
290
-
291
- field name, locator, TextField
292
- end
293
-
294
- # @!endgroup
295
-
296
- # @return This field group's field widgets.
297
- def fields
298
- self.class.field_names.map { |name| widget(name) }
299
- end
300
-
301
- # Sets the given form attributes.
302
- #
303
- # @param attributes [Hash] the attributes and values we want to set.
304
- #
305
- # @return the current widget.
306
- def set(attributes)
307
- attributes.each do |k, v|
308
- send "#{k}=", v
309
- end
310
-
311
- self
312
- end
313
-
314
- # Converts the current field group into a table suitable for diff'ing
315
- # with Cucumber::Ast::Table.
316
- #
317
- # Field labels are determined by the widget name.
318
- #
319
- # Field values correspond to the return value of each field's +to_s+.
320
- #
321
- # @return [Array<Array>] the table.
322
- def to_table
323
- headers = fields.map { |field| field.label.downcase }
324
- body = fields.map { |field| field.to_s.downcase }
325
-
326
- [headers, body]
327
- end
328
- end
329
- end