capybara-ui 0.10.0 → 1.0.0

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 (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