dill 0.5.2 → 0.6.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.
- data/lib/dill.rb +3 -15
- data/lib/dill/capybara.rb +7 -0
- data/lib/dill/checkpoint.rb +52 -34
- data/lib/dill/conversions.rb +2 -0
- data/lib/dill/dsl.rb +15 -5
- data/lib/dill/version.rb +1 -1
- data/lib/dill/widgets.rb +56 -0
- data/lib/dill/{auto_table.rb → widgets/auto_table.rb} +5 -3
- data/lib/dill/{base_table.rb → widgets/base_table.rb} +0 -0
- data/lib/dill/widgets/check_box.rb +26 -0
- data/lib/dill/widgets/document.rb +13 -0
- data/lib/dill/widgets/field.rb +26 -0
- data/lib/dill/{field_group.rb → widgets/field_group.rb} +0 -86
- data/lib/dill/{form.rb → widgets/form.rb} +9 -0
- data/lib/dill/{list.rb → widgets/list.rb} +40 -6
- data/lib/dill/{list_item.rb → widgets/list_item.rb} +0 -0
- data/lib/dill/widgets/parts/container.rb +29 -0
- data/lib/dill/widgets/parts/struct.rb +117 -0
- data/lib/dill/widgets/select.rb +29 -0
- data/lib/dill/{table.rb → widgets/table.rb} +1 -1
- data/lib/dill/widgets/text_field.rb +23 -0
- data/lib/dill/widgets/widget.rb +404 -0
- data/lib/dill/{widget_class.rb → widgets/widget_class.rb} +0 -0
- data/lib/dill/{widget_name.rb → widgets/widget_name.rb} +0 -0
- metadata +53 -16
- data/lib/dill/document.rb +0 -14
- data/lib/dill/node_text.rb +0 -9
- data/lib/dill/widget.rb +0 -516
- data/lib/dill/widget_checkpoint.rb +0 -30
- data/lib/dill/widget_container.rb +0 -23
File without changes
|
File without changes
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: dill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.6.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Leal
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -123,6 +123,38 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 1.3.0
|
125
125
|
none: false
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
none: false
|
133
|
+
name: pry
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
requirement: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
none: false
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
version_requirements: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
none: false
|
149
|
+
name: pry-nav
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
requirement: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ! '>='
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
none: false
|
126
158
|
description: See https://github.com/mojotech/dill/README.md
|
127
159
|
email:
|
128
160
|
- dleal@mojotech.com
|
@@ -131,31 +163,36 @@ extensions: []
|
|
131
163
|
extra_rdoc_files: []
|
132
164
|
files:
|
133
165
|
- lib/dill.rb
|
134
|
-
- lib/dill/
|
135
|
-
- lib/dill/base_table.rb
|
166
|
+
- lib/dill/capybara.rb
|
136
167
|
- lib/dill/checkpoint.rb
|
137
168
|
- lib/dill/conversions.rb
|
138
169
|
- lib/dill/cucumber.rb
|
139
|
-
- lib/dill/document.rb
|
140
170
|
- lib/dill/dsl.rb
|
141
|
-
- lib/dill/field_group.rb
|
142
|
-
- lib/dill/form.rb
|
143
171
|
- lib/dill/instance_conversions.rb
|
144
|
-
- lib/dill/list.rb
|
145
|
-
- lib/dill/list_item.rb
|
146
|
-
- lib/dill/node_text.rb
|
147
|
-
- lib/dill/table.rb
|
148
172
|
- lib/dill/text_table.rb
|
149
173
|
- lib/dill/text_table/cell_text.rb
|
150
174
|
- lib/dill/text_table/mapping.rb
|
151
175
|
- lib/dill/text_table/transformations.rb
|
152
176
|
- lib/dill/text_table/void_mapping.rb
|
153
177
|
- lib/dill/version.rb
|
154
|
-
- lib/dill/
|
155
|
-
- lib/dill/
|
156
|
-
- lib/dill/
|
157
|
-
- lib/dill/
|
158
|
-
- lib/dill/
|
178
|
+
- lib/dill/widgets.rb
|
179
|
+
- lib/dill/widgets/auto_table.rb
|
180
|
+
- lib/dill/widgets/base_table.rb
|
181
|
+
- lib/dill/widgets/check_box.rb
|
182
|
+
- lib/dill/widgets/document.rb
|
183
|
+
- lib/dill/widgets/field.rb
|
184
|
+
- lib/dill/widgets/field_group.rb
|
185
|
+
- lib/dill/widgets/form.rb
|
186
|
+
- lib/dill/widgets/list.rb
|
187
|
+
- lib/dill/widgets/list_item.rb
|
188
|
+
- lib/dill/widgets/parts/container.rb
|
189
|
+
- lib/dill/widgets/parts/struct.rb
|
190
|
+
- lib/dill/widgets/select.rb
|
191
|
+
- lib/dill/widgets/table.rb
|
192
|
+
- lib/dill/widgets/text_field.rb
|
193
|
+
- lib/dill/widgets/widget.rb
|
194
|
+
- lib/dill/widgets/widget_class.rb
|
195
|
+
- lib/dill/widgets/widget_name.rb
|
159
196
|
homepage: https://github.com/mojotech/dill
|
160
197
|
licenses:
|
161
198
|
- MIT
|
data/lib/dill/document.rb
DELETED
data/lib/dill/node_text.rb
DELETED
data/lib/dill/widget.rb
DELETED
@@ -1,516 +0,0 @@
|
|
1
|
-
module Dill
|
2
|
-
class Widget
|
3
|
-
extend Forwardable
|
4
|
-
|
5
|
-
include WidgetContainer
|
6
|
-
|
7
|
-
class Removed < StandardError; end
|
8
|
-
|
9
|
-
# @!group Widget macros
|
10
|
-
|
11
|
-
# Defines a new action.
|
12
|
-
#
|
13
|
-
# This is a shortcut to help defining a widget and a method that clicks
|
14
|
-
# on that widget. You can then send a widget instance the message given
|
15
|
-
# by +name+.
|
16
|
-
#
|
17
|
-
# You can access the underlying widget by appending "_widget" to the
|
18
|
-
# action name.
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
# # Consider the widget will encapsulate the following HTML
|
22
|
-
# #
|
23
|
-
# # <div id="profile">
|
24
|
-
# # <a href="/profiles/1/edit" rel="edit">Edit</a>
|
25
|
-
# # </div>
|
26
|
-
# class PirateProfile < Dill::Widget
|
27
|
-
# root "#profile"
|
28
|
-
#
|
29
|
-
# # Declare the action
|
30
|
-
# action :edit, '[rel = edit]'
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# pirate_profile = widget(:pirate_profile)
|
34
|
-
#
|
35
|
-
# # Access the action widget
|
36
|
-
# action_widget = pirate_profile.widget(:edit_widget)
|
37
|
-
# action_widget = pirate_profile.edit_widget
|
38
|
-
#
|
39
|
-
# # Click the link
|
40
|
-
# pirate_profile.edit
|
41
|
-
#
|
42
|
-
# @param name the name of the action
|
43
|
-
# @param selector the selector for the widget that will be clicked
|
44
|
-
def self.action(name, selector)
|
45
|
-
wname = :"#{name}_widget"
|
46
|
-
|
47
|
-
widget wname, selector
|
48
|
-
|
49
|
-
define_method name do
|
50
|
-
widget(wname).click
|
51
|
-
|
52
|
-
self
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Declares a new child widget.
|
57
|
-
#
|
58
|
-
# Child widgets are accessible inside the container widget using the
|
59
|
-
# {#widget} message, or by sending a message +name+. They
|
60
|
-
# are automatically scoped to the parent widget's root node.
|
61
|
-
#
|
62
|
-
# @example Defining a widget
|
63
|
-
# # Given the following HTML:
|
64
|
-
# #
|
65
|
-
# # <div id="root">
|
66
|
-
# # <span id="child">Child</span>
|
67
|
-
# # </div>
|
68
|
-
# class Container < Dill::Widget
|
69
|
-
# root '#root'
|
70
|
-
#
|
71
|
-
# widget :my_widget, '#child'
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# container = widget(:container)
|
75
|
-
#
|
76
|
-
# # accessing using #widget
|
77
|
-
# my_widget = container.widget(:my_widget)
|
78
|
-
#
|
79
|
-
# # accessing using #my_widget
|
80
|
-
# my_widget = container.my_widget
|
81
|
-
#
|
82
|
-
# @overload widget(name, selector, type = Widget)
|
83
|
-
#
|
84
|
-
# The most common form, it allows you to pass in a selector as well as a
|
85
|
-
# type for the child widget. The selector will override +type+'s
|
86
|
-
# root selector, if +type+ has one defined.
|
87
|
-
#
|
88
|
-
# @param name the child widget's name.
|
89
|
-
# @param selector the child widget's selector. You can pass either a
|
90
|
-
# String or, if you want to use a composite selector, an Array.
|
91
|
-
# @param type the child widget's parent class.
|
92
|
-
#
|
93
|
-
# @overload widget(name, type)
|
94
|
-
#
|
95
|
-
# This form allows you to omit +selector+ from the arguments. It will
|
96
|
-
# reuse +type+'s root selector.
|
97
|
-
#
|
98
|
-
# @param name the child widget's name.
|
99
|
-
# @param type the child widget's parent class.
|
100
|
-
#
|
101
|
-
# @raise ArgumentError if +type+ has no root selector defined.
|
102
|
-
#
|
103
|
-
# @yield A block allowing you to further customize the widget behavior.
|
104
|
-
#
|
105
|
-
# @see #widget
|
106
|
-
def self.widget(name, *rest, &block)
|
107
|
-
raise ArgumentError, "`#{name}' is a reserved name" \
|
108
|
-
if WidgetContainer.instance_methods.include?(name.to_sym)
|
109
|
-
|
110
|
-
case rest.first
|
111
|
-
when Class
|
112
|
-
arg_count = rest.size + 1
|
113
|
-
raise ArgumentError, "wrong number of arguments (#{arg_count} for 2)" \
|
114
|
-
unless arg_count == 2
|
115
|
-
|
116
|
-
type = rest.first
|
117
|
-
raise TypeError, "can't convert `#{type}' to Widget" \
|
118
|
-
unless type.methods.include?(:selector)
|
119
|
-
raise ArgumentError, "missing root selector for `#{type}'" \
|
120
|
-
unless type.selector
|
121
|
-
|
122
|
-
selector = type.selector
|
123
|
-
when String, Array
|
124
|
-
arg_count = rest.size + 1
|
125
|
-
|
126
|
-
case arg_count
|
127
|
-
when 0, 1
|
128
|
-
raise ArgumentError, "wrong number of arguments (#{arg_count} for 2)"
|
129
|
-
when 2
|
130
|
-
selector, type = [*rest, Widget]
|
131
|
-
when 3
|
132
|
-
selector, type = rest
|
133
|
-
|
134
|
-
raise TypeError, "can't convert `#{type}' to Widget" \
|
135
|
-
unless Class === type
|
136
|
-
else
|
137
|
-
raise ArgumentError, "wrong number of arguments (#{arg_count} for 3)"
|
138
|
-
end
|
139
|
-
else
|
140
|
-
raise ArgumentError, "unknown method signature: #{rest.inspect}"
|
141
|
-
end
|
142
|
-
|
143
|
-
child = WidgetClass.new(selector, type, &block)
|
144
|
-
|
145
|
-
const_set(Dill::WidgetName.new(name).to_sym, child)
|
146
|
-
|
147
|
-
define_method name do
|
148
|
-
widget(name)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
# Creates a delegator for one child widget message.
|
153
|
-
#
|
154
|
-
# Since widgets are accessed through {WidgetContainer#widget}, we can't
|
155
|
-
# use {Forwardable} to delegate messages to widgets.
|
156
|
-
#
|
157
|
-
# @param name the name of the receiver child widget
|
158
|
-
# @param widget_message the name of the message to be sent to the child widget
|
159
|
-
# @param method_name the name of the delegator. If +nil+ the method will
|
160
|
-
# have the same name as the message it will send.
|
161
|
-
def self.widget_delegator(name, widget_message, method_name = nil)
|
162
|
-
method_name = method_name || widget_message
|
163
|
-
|
164
|
-
class_eval <<-RUBY
|
165
|
-
def #{method_name}(*args)
|
166
|
-
if args.size == 1
|
167
|
-
widget(:#{name}).#{widget_message} args.first
|
168
|
-
else
|
169
|
-
widget(:#{name}).#{widget_message} *args
|
170
|
-
end
|
171
|
-
end
|
172
|
-
RUBY
|
173
|
-
end
|
174
|
-
|
175
|
-
# @!endgroup
|
176
|
-
|
177
|
-
# Finds a single instance of the current widget in +node+.
|
178
|
-
#
|
179
|
-
# @param node the node we want to search in
|
180
|
-
#
|
181
|
-
# @return a new instance of the current widget class.
|
182
|
-
#
|
183
|
-
# @raise [Capybara::ElementNotFoundError] if the widget can't be found
|
184
|
-
def self.find_in(node)
|
185
|
-
new(node.find(*selector))
|
186
|
-
end
|
187
|
-
|
188
|
-
# Determines if an instance of this widget class exists in
|
189
|
-
# +parent_node+.
|
190
|
-
#
|
191
|
-
# @param parent_node [Capybara::Node] the node we want to search in
|
192
|
-
#
|
193
|
-
# @return +true+ if a widget instance is found, +false+ otherwise.
|
194
|
-
def self.present_in?(parent_node)
|
195
|
-
parent_node.has_selector?(*selector)
|
196
|
-
end
|
197
|
-
|
198
|
-
# Sets this widget's default selector.
|
199
|
-
#
|
200
|
-
# You can pass more than one argument to it, or a single Array. Any valid
|
201
|
-
# Capybara selector accepted by Capybara::Node::Finders#find will work.
|
202
|
-
#
|
203
|
-
# === Examples
|
204
|
-
#
|
205
|
-
# Most of the time, your selectors will be Strings:
|
206
|
-
#
|
207
|
-
# class MyWidget < Dill::Widget
|
208
|
-
# root '.selector'
|
209
|
-
# end
|
210
|
-
#
|
211
|
-
# This will match any element with a class of "selector". For example:
|
212
|
-
#
|
213
|
-
# <span class="selector">Pick me!</span>
|
214
|
-
#
|
215
|
-
# ==== Composite selectors
|
216
|
-
#
|
217
|
-
# If you're using CSS as the query language, it's useful to be able to use
|
218
|
-
# +text: 'Some text'+ to zero in on a specific node:
|
219
|
-
#
|
220
|
-
# class MySpecificWidget < Dill::Widget
|
221
|
-
# root '.selector', text: 'Pick me!'
|
222
|
-
# end
|
223
|
-
#
|
224
|
-
# This is especially useful, e.g., when you want to create a widget
|
225
|
-
# to match a specific error or notification:
|
226
|
-
#
|
227
|
-
# class NoFreeSpace < Dill::Widget
|
228
|
-
# root '.error', text: 'No free space left!'
|
229
|
-
# end
|
230
|
-
#
|
231
|
-
# So, given the following HTML:
|
232
|
-
#
|
233
|
-
# <body>
|
234
|
-
# <div class="error">No free space left!</div>
|
235
|
-
#
|
236
|
-
# <!-- ... -->
|
237
|
-
# </body>
|
238
|
-
#
|
239
|
-
# You can test for the error's present using the following code:
|
240
|
-
#
|
241
|
-
# document.has_widget?(:no_free_space) #=> true
|
242
|
-
#
|
243
|
-
# Note: When you want to match text, consider using +I18n.t+ instead of
|
244
|
-
# hard-coding the text, so that your tests don't break when the text changes.
|
245
|
-
#
|
246
|
-
# Finally, you may want to override the query language:
|
247
|
-
#
|
248
|
-
# class MyWidgetUsesXPath < Dill::Widget
|
249
|
-
# root :xpath, '//some/node'
|
250
|
-
# end
|
251
|
-
def self.root(*selector)
|
252
|
-
@selector = selector.flatten
|
253
|
-
end
|
254
|
-
|
255
|
-
# Returns the selector specified with +root+.
|
256
|
-
def self.selector
|
257
|
-
@selector
|
258
|
-
end
|
259
|
-
|
260
|
-
# Returns the root node (a Capybara::Node::Element) of the current widget.
|
261
|
-
attr_reader :root
|
262
|
-
|
263
|
-
def initialize(root)
|
264
|
-
self.root = root
|
265
|
-
end
|
266
|
-
|
267
|
-
# Returns +true+ if this widget's representation is less than +value+.
|
268
|
-
#
|
269
|
-
# Waits for the result to be +true+ for the time defined in
|
270
|
-
# `Capybara.default_wait_time`.
|
271
|
-
def <(value)
|
272
|
-
test { cast_to_type_of(value) < value }
|
273
|
-
end
|
274
|
-
|
275
|
-
# Returns +true+ if this widget's representation is less than or equal to
|
276
|
-
# +value+.
|
277
|
-
#
|
278
|
-
# Waits for the result to be +true+ for the time defined in
|
279
|
-
# `Capybara.default_wait_time`.
|
280
|
-
def <=(value)
|
281
|
-
test { cast_to_type_of(value) <= value }
|
282
|
-
end
|
283
|
-
|
284
|
-
# Returns +true+ if this widget's representation is greater than +value+.
|
285
|
-
#
|
286
|
-
# Waits for the result to be +true+ for the time defined in
|
287
|
-
# `Capybara.default_wait_time`.
|
288
|
-
def >(value)
|
289
|
-
test { cast_to_type_of(value) > value }
|
290
|
-
end
|
291
|
-
|
292
|
-
# Returns +true+ if this widget's representation is greater than or equal to
|
293
|
-
# +value+.
|
294
|
-
#
|
295
|
-
# Waits for the result to be +true+ for the time defined in
|
296
|
-
# `Capybara.default_wait_time`.
|
297
|
-
def >=(value)
|
298
|
-
test { cast_to_type_of(value) >= value }
|
299
|
-
end
|
300
|
-
|
301
|
-
# Compares the current widget with +value+, waiting for the comparison
|
302
|
-
# to return +true+.
|
303
|
-
def ==(value)
|
304
|
-
test { cast_to_type_of(value) == value }
|
305
|
-
end
|
306
|
-
|
307
|
-
# Calls +=~+ on this widget's text content.
|
308
|
-
def =~(regexp)
|
309
|
-
test { to_s =~ regexp }
|
310
|
-
end
|
311
|
-
|
312
|
-
# Calls +!~+ on this widget's text content.
|
313
|
-
def !~(regexp)
|
314
|
-
test { to_s !~ regexp }
|
315
|
-
end
|
316
|
-
|
317
|
-
# Compares the current widget with +value+, waiting for the comparison
|
318
|
-
# to return +false+.
|
319
|
-
def !=(value)
|
320
|
-
test { cast_to_type_of(value) != value }
|
321
|
-
end
|
322
|
-
|
323
|
-
# Clicks the current widget, or the child widget given by +name+.
|
324
|
-
#
|
325
|
-
# === Usage
|
326
|
-
#
|
327
|
-
# Given the following widget definition:
|
328
|
-
#
|
329
|
-
# class Container < Dill::Widget
|
330
|
-
# root '#container'
|
331
|
-
#
|
332
|
-
# widget :link, 'a'
|
333
|
-
# end
|
334
|
-
#
|
335
|
-
# Send +click+ with no arguments to trigger a +click+ event on +#container+.
|
336
|
-
#
|
337
|
-
# widget(:container).click
|
338
|
-
#
|
339
|
-
# This is the equivalent of doing the following using Capybara:
|
340
|
-
#
|
341
|
-
# find('#container').click
|
342
|
-
#
|
343
|
-
# Send +click :link+ to trigger a +click+ event on +a+:
|
344
|
-
#
|
345
|
-
# widget(:container).click :link
|
346
|
-
#
|
347
|
-
# This is the equivalent of doing the following using Capybara:
|
348
|
-
#
|
349
|
-
# find('#container a').click
|
350
|
-
def click(name = nil)
|
351
|
-
if name
|
352
|
-
widget(name).click
|
353
|
-
else
|
354
|
-
root.click
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
# Compares this widget with the given +diffable+, as long as it responds to
|
359
|
-
# the same protocol as Cucumber::Ast::Table#diff!.
|
360
|
-
#
|
361
|
-
# Waits +wait_time+ seconds for the comparison to be successful, otherwise
|
362
|
-
# raises Cucumber::Ast::Table::Different on failure.
|
363
|
-
#
|
364
|
-
# This is especially useful when you're not sure if the widget is in the
|
365
|
-
# proper state to be compared with the table.
|
366
|
-
#
|
367
|
-
# === Example
|
368
|
-
#
|
369
|
-
# Then(/^some step that takes in a cucumber table$/) do |table|
|
370
|
-
# widget(:my_widget).diff table
|
371
|
-
# end
|
372
|
-
def diff(diffable, wait_time = Capybara.default_wait_time)
|
373
|
-
# #diff! raises an exception if the comparison fails, or returns nil if it
|
374
|
-
# doesn't. We don't need to worry about failure, because that will be
|
375
|
-
# propagated, but we need to return +true+ when it succeeds, to end the
|
376
|
-
# comparison.
|
377
|
-
#
|
378
|
-
# We use WidgetCheckpoint instead of #test because we want the
|
379
|
-
# succeed-or-raise behavior.
|
380
|
-
WidgetCheckpoint.wait_for(wait_time) { diffable.diff!(to_table) || true }
|
381
|
-
end
|
382
|
-
|
383
|
-
# Determines if the widget underlying an action exists.
|
384
|
-
#
|
385
|
-
# @param name the name of the action
|
386
|
-
#
|
387
|
-
# @raise Missing if an action with +name+ can't be found.
|
388
|
-
#
|
389
|
-
# @return [Boolean] +true+ if the action widget is found, +false+
|
390
|
-
# otherwise.
|
391
|
-
def has_action?(name)
|
392
|
-
raise Missing, "couldn't find `#{name}' action" unless respond_to?(name)
|
393
|
-
|
394
|
-
has_widget?(:"#{name}_widget")
|
395
|
-
end
|
396
|
-
|
397
|
-
def inspect
|
398
|
-
inspection = "<!-- #{self.class.name}: -->\n"
|
399
|
-
root = self.root
|
400
|
-
|
401
|
-
begin
|
402
|
-
xml = Nokogiri::HTML(page.body).at(root.path).to_xml
|
403
|
-
|
404
|
-
inspection << Nokogiri::XML(xml, &:noblanks).to_xhtml
|
405
|
-
rescue Capybara::NotSupportedByDriverError
|
406
|
-
inspection << "<#{root.tag_name}>\n#{to_s}"
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
# Reloads the widget, waiting for its contents to change (by default),
|
411
|
-
# or until +wait_time+ expires.
|
412
|
-
#
|
413
|
-
# Call this method to make sure a widget has enough time to update
|
414
|
-
# itself.
|
415
|
-
#
|
416
|
-
# You can pass a block to this method to control what it means for the
|
417
|
-
# widget to be reloaded.
|
418
|
-
#
|
419
|
-
# *Note: does not account for multiple changes to the widget yet.*
|
420
|
-
#
|
421
|
-
# @param wait_time [Numeric] how long we should wait for changes, in
|
422
|
-
# seconds.
|
423
|
-
#
|
424
|
-
# @yield A block that determines what it means for a widget to be
|
425
|
-
# reloaded.
|
426
|
-
# @yieldreturn [Boolean] +true+ if the widget is considered to be
|
427
|
-
# reloaded, +false+ otherwise.
|
428
|
-
#
|
429
|
-
# @return the current widget
|
430
|
-
#
|
431
|
-
# @see Checkpoint
|
432
|
-
def reload(wait_time = Capybara.default_wait_time, &condition)
|
433
|
-
unless test
|
434
|
-
old_root = root
|
435
|
-
test = ->{ old_root != root }
|
436
|
-
end
|
437
|
-
|
438
|
-
test wait_time, &condition
|
439
|
-
|
440
|
-
begin
|
441
|
-
root.inspect
|
442
|
-
rescue
|
443
|
-
raise Removed, "widget was removed"
|
444
|
-
end
|
445
|
-
|
446
|
-
self
|
447
|
-
end
|
448
|
-
|
449
|
-
# Calls +match+ on this widget's text content.
|
450
|
-
#
|
451
|
-
# If a block is given, passes the resulting match data to the block.
|
452
|
-
#
|
453
|
-
# @param pattern the pattern to match
|
454
|
-
# @param position where to begin the search
|
455
|
-
#
|
456
|
-
# @yieldparam [MatchData] the match data from running +match+ on the text.
|
457
|
-
#
|
458
|
-
# @return [MatchData] the match data from running +match+ on the text.
|
459
|
-
def match(pattern, position = 0, &block)
|
460
|
-
test { to_s.match(pattern, position, &block) }
|
461
|
-
end
|
462
|
-
|
463
|
-
def text
|
464
|
-
NodeText.new(root)
|
465
|
-
end
|
466
|
-
|
467
|
-
# Converts this widget into a string representation suitable to be displayed
|
468
|
-
# in a Cucumber table cell. By default calls #text.
|
469
|
-
#
|
470
|
-
# This method will be called by methods that build tables or rows (usually
|
471
|
-
# #to_table or #to_row) so, in general, you won't call it directly, but feel
|
472
|
-
# free to override it when needed.
|
473
|
-
#
|
474
|
-
# Returns a String.
|
475
|
-
def to_cell
|
476
|
-
to_s
|
477
|
-
end
|
478
|
-
|
479
|
-
def to_i
|
480
|
-
to_s.to_i
|
481
|
-
end
|
482
|
-
|
483
|
-
def to_f
|
484
|
-
to_s.to_f
|
485
|
-
end
|
486
|
-
|
487
|
-
alias_method :to_s, :text
|
488
|
-
|
489
|
-
protected
|
490
|
-
|
491
|
-
def cast_to_type_of(value)
|
492
|
-
case value
|
493
|
-
when Float
|
494
|
-
to_f
|
495
|
-
when Integer
|
496
|
-
to_i
|
497
|
-
when String
|
498
|
-
to_s
|
499
|
-
else
|
500
|
-
raise TypeError, "can't convert this widget to `#{klass}'"
|
501
|
-
end
|
502
|
-
end
|
503
|
-
|
504
|
-
private
|
505
|
-
|
506
|
-
attr_writer :root
|
507
|
-
|
508
|
-
def test(wait_time = Capybara.default_wait_time, &block)
|
509
|
-
WidgetCheckpoint.wait_for(wait_time, &block) rescue nil
|
510
|
-
end
|
511
|
-
|
512
|
-
def page
|
513
|
-
Capybara.current_session
|
514
|
-
end
|
515
|
-
end
|
516
|
-
end
|