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
data/lib/dill.rb
CHANGED
@@ -2,28 +2,16 @@ require 'chronic'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'capybara'
|
4
4
|
|
5
|
-
require 'dill/checkpoint'
|
6
|
-
require 'dill/widget_class'
|
7
|
-
require 'dill/widget_checkpoint'
|
8
|
-
require 'dill/widget_container'
|
9
5
|
require 'dill/conversions'
|
10
6
|
require 'dill/instance_conversions'
|
11
|
-
require 'dill/
|
12
|
-
require 'dill/
|
13
|
-
require 'dill/widget'
|
14
|
-
require 'dill/list_item'
|
15
|
-
require 'dill/list'
|
16
|
-
require 'dill/base_table'
|
17
|
-
require 'dill/auto_table'
|
18
|
-
require 'dill/table'
|
19
|
-
require 'dill/field_group'
|
20
|
-
require 'dill/form'
|
21
|
-
require 'dill/document'
|
7
|
+
require 'dill/checkpoint'
|
8
|
+
require 'dill/widgets'
|
22
9
|
require 'dill/text_table'
|
23
10
|
require 'dill/text_table/mapping'
|
24
11
|
require 'dill/text_table/void_mapping'
|
25
12
|
require 'dill/text_table/transformations'
|
26
13
|
require 'dill/text_table/cell_text'
|
14
|
+
require 'dill/capybara'
|
27
15
|
require 'dill/dsl'
|
28
16
|
|
29
17
|
module Dill
|
data/lib/dill/checkpoint.rb
CHANGED
@@ -6,14 +6,54 @@ module Dill
|
|
6
6
|
# which inspired this class.
|
7
7
|
class Checkpoint
|
8
8
|
class ConditionNotMet < StandardError; end
|
9
|
-
class TimeFrozen < StandardError; end
|
10
9
|
|
11
|
-
|
12
|
-
|
10
|
+
class Timer
|
11
|
+
class Frozen < StandardError; end
|
12
|
+
|
13
|
+
def initialize(duration)
|
14
|
+
@duration = duration
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :duration
|
18
|
+
|
19
|
+
def expired?
|
20
|
+
duration < elapsed
|
21
|
+
end
|
22
|
+
|
23
|
+
def elapsed
|
24
|
+
now - start_time
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
@start_time = now
|
29
|
+
end
|
30
|
+
|
31
|
+
def tick
|
32
|
+
sleep tick_duration
|
33
|
+
|
34
|
+
raise Frozen, 'time appears to be frozen' if frozen?
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def now
|
40
|
+
Time.now
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :start_time
|
44
|
+
|
45
|
+
def frozen?
|
46
|
+
now == start_time
|
47
|
+
end
|
48
|
+
|
49
|
+
def tick_duration
|
50
|
+
0.05
|
51
|
+
end
|
52
|
+
end
|
13
53
|
|
14
54
|
# Shortcut for instance level wait_for.
|
15
55
|
def self.wait_for(wait_time = Capybara.default_wait_time, &block)
|
16
|
-
new(wait_time).
|
56
|
+
new(wait_time).call(&block)
|
17
57
|
end
|
18
58
|
|
19
59
|
# Initializes a new Checkpoint.
|
@@ -21,7 +61,7 @@ module Dill
|
|
21
61
|
# @param wait_time how long this checkpoint will wait for its conditions to
|
22
62
|
# be met, in seconds.
|
23
63
|
def initialize(wait_time = Capybara.default_wait_time)
|
24
|
-
@
|
64
|
+
@timer = Timer.new(wait_time)
|
25
65
|
end
|
26
66
|
|
27
67
|
# Executes +block+ repeatedly until it returns a "truthy" value or
|
@@ -35,48 +75,26 @@ module Dill
|
|
35
75
|
# raises a Dill::Checkpoint::ConditionNotMet error.
|
36
76
|
#
|
37
77
|
# Returns whatever value is returned by the block.
|
38
|
-
def
|
39
|
-
start
|
78
|
+
def call(&condition)
|
79
|
+
timer.start
|
40
80
|
|
41
81
|
begin
|
42
82
|
yield or raise ConditionNotMet
|
43
83
|
rescue *rescuable_errors
|
44
|
-
raise if expired?
|
45
|
-
|
46
|
-
wait
|
84
|
+
raise if timer.expired?
|
47
85
|
|
48
|
-
|
86
|
+
timer.tick
|
49
87
|
|
50
88
|
retry
|
51
89
|
end
|
52
90
|
end
|
53
91
|
|
92
|
+
protected
|
93
|
+
|
54
94
|
def rescuable_errors
|
55
95
|
[StandardError]
|
56
96
|
end
|
57
97
|
|
58
|
-
|
59
|
-
|
60
|
-
attr_reader :start_time
|
61
|
-
|
62
|
-
def expired?
|
63
|
-
remaining_time > wait_time
|
64
|
-
end
|
65
|
-
|
66
|
-
def remaining_time
|
67
|
-
Time.now - start_time
|
68
|
-
end
|
69
|
-
|
70
|
-
def start
|
71
|
-
@start_time = Time.now
|
72
|
-
end
|
73
|
-
|
74
|
-
def wait
|
75
|
-
sleep 0.05
|
76
|
-
end
|
77
|
-
|
78
|
-
def time_frozen?
|
79
|
-
Time.now == start_time
|
80
|
-
end
|
98
|
+
attr_reader :timer
|
81
99
|
end
|
82
100
|
end
|
data/lib/dill/conversions.rb
CHANGED
data/lib/dill/dsl.rb
CHANGED
@@ -5,26 +5,36 @@ module Dill
|
|
5
5
|
# @return [Document] the current document with the class of the
|
6
6
|
# current object set as the widget lookup scope.
|
7
7
|
def document
|
8
|
-
Document.new(widget_lookup_scope
|
8
|
+
Document.new(widget_lookup_scope)
|
9
9
|
end
|
10
10
|
|
11
11
|
# @return [Boolean] Whether one or more widgets exist in the current
|
12
12
|
# document.
|
13
|
-
def has_widget?(name)
|
14
|
-
document.has_widget?(name)
|
13
|
+
def has_widget?(name, *args)
|
14
|
+
document.has_widget?(name, *args)
|
15
|
+
end
|
16
|
+
|
17
|
+
def value(name, *args)
|
18
|
+
widget(name, *args).value
|
15
19
|
end
|
16
20
|
|
17
21
|
# Returns a widget instance for the given name.
|
18
22
|
#
|
19
23
|
# @param name [String, Symbol]
|
20
|
-
def widget(name)
|
21
|
-
document.widget(name)
|
24
|
+
def widget(name, *args)
|
25
|
+
document.widget(name, *args)
|
22
26
|
end
|
23
27
|
|
24
28
|
def widget_lookup_scope
|
25
29
|
@widget_lookup_scope ||= default_widget_lookup_scope
|
26
30
|
end
|
27
31
|
|
32
|
+
# re-run one or more assertions until either they all pass,
|
33
|
+
# or Dill times out, which will result in a test failure.
|
34
|
+
def eventually(wait_time = Capybara.default_wait_time, &block)
|
35
|
+
Checkpoint.wait_for wait_time, &block
|
36
|
+
end
|
37
|
+
|
28
38
|
private
|
29
39
|
|
30
40
|
def default_widget_lookup_scope
|
data/lib/dill/version.rb
CHANGED
data/lib/dill/widgets.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# This file describes the organization of the major Widget API components.
|
2
|
+
#
|
3
|
+
# === Parts
|
4
|
+
#
|
5
|
+
# Widget parts encapsulate the set of behaviours that constitute a widget.
|
6
|
+
module Dill
|
7
|
+
module Constructors
|
8
|
+
def Widget(*selector, &block)
|
9
|
+
WidgetClass.new(selector.flatten, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method :String, :Widget
|
13
|
+
|
14
|
+
def Integer(*selector)
|
15
|
+
Widget(selector) do
|
16
|
+
def value
|
17
|
+
Integer(text)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'bigdecimal'
|
23
|
+
|
24
|
+
def Decimal(*selector)
|
25
|
+
Widget(selector) do
|
26
|
+
def value
|
27
|
+
# ensure we can convert to float first
|
28
|
+
Float(text) && BigDecimal.new(text)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
extend Constructors
|
35
|
+
end
|
36
|
+
|
37
|
+
module Dill::WidgetParts; end
|
38
|
+
|
39
|
+
require 'dill/widgets/parts/struct'
|
40
|
+
require 'dill/widgets/parts/container'
|
41
|
+
|
42
|
+
require 'dill/widgets/widget_class'
|
43
|
+
require 'dill/widgets/widget_name'
|
44
|
+
require 'dill/widgets/widget'
|
45
|
+
require 'dill/widgets/list_item'
|
46
|
+
require 'dill/widgets/list'
|
47
|
+
require 'dill/widgets/base_table'
|
48
|
+
require 'dill/widgets/auto_table'
|
49
|
+
require 'dill/widgets/table'
|
50
|
+
require 'dill/widgets/field'
|
51
|
+
require 'dill/widgets/check_box'
|
52
|
+
require 'dill/widgets/select'
|
53
|
+
require 'dill/widgets/text_field'
|
54
|
+
require 'dill/widgets/field_group'
|
55
|
+
require 'dill/widgets/form'
|
56
|
+
require 'dill/widgets/document'
|
@@ -4,7 +4,7 @@ module Dill
|
|
4
4
|
# don't include footer in to_table, because footer column configuration is very
|
5
5
|
# often different from the headers & values.
|
6
6
|
def footers
|
7
|
-
@footers ||= root.all(footer_selector).map { |n|
|
7
|
+
@footers ||= root.all(footer_selector).map { |n| Widget.new(n).text }
|
8
8
|
end
|
9
9
|
|
10
10
|
protected
|
@@ -37,7 +37,9 @@ module Dill
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def headers
|
40
|
-
@headers ||= root.
|
40
|
+
@headers ||= root.
|
41
|
+
all(header_selector).
|
42
|
+
map { |n| Widget.new(n).text.downcase }
|
41
43
|
end
|
42
44
|
|
43
45
|
def footer_selector
|
@@ -66,7 +68,7 @@ module Dill
|
|
66
68
|
attr_accessor :cell_selector
|
67
69
|
|
68
70
|
def node_text(node)
|
69
|
-
|
71
|
+
node.text.strip
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dill
|
2
|
+
# A check box.
|
3
|
+
class CheckBox < Field
|
4
|
+
# @!method set(value)
|
5
|
+
# Checks or unchecks the current checkbox.
|
6
|
+
#
|
7
|
+
# @param value [Boolean] +true+ to check the checkbox, +false+
|
8
|
+
# otherwise.
|
9
|
+
def_delegator :root, :set
|
10
|
+
|
11
|
+
# @return [Boolean] +true+ if the checkbox is checked, +false+
|
12
|
+
# otherwise.
|
13
|
+
def get
|
14
|
+
!! root.checked?
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_cell
|
18
|
+
to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return +"yes"+ if the checkbox is checked, +"no"+ otherwise.
|
22
|
+
def to_s
|
23
|
+
get ? 'yes' : 'no'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dill
|
2
|
+
# A form field.
|
3
|
+
class Field < Widget
|
4
|
+
def self.find_in(parent)
|
5
|
+
new { parent.root.find_field(*selector) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.present_in?(parent)
|
9
|
+
parent.root.has_field?(*selector)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return This field's value.
|
13
|
+
#
|
14
|
+
# Override this to get the actual value.
|
15
|
+
def get
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the field value.
|
20
|
+
#
|
21
|
+
# Override this to set the value.
|
22
|
+
def set(value)
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -241,91 +241,5 @@ module Dill
|
|
241
241
|
|
242
242
|
[headers, body]
|
243
243
|
end
|
244
|
-
|
245
|
-
# A form field.
|
246
|
-
class Field < Widget
|
247
|
-
def self.find_in(parent)
|
248
|
-
new(parent.find_field(*selector))
|
249
|
-
end
|
250
|
-
|
251
|
-
def self.present_in?(parent)
|
252
|
-
parent.has_field?(*selector)
|
253
|
-
end
|
254
|
-
|
255
|
-
# @return This field's value.
|
256
|
-
#
|
257
|
-
# Override this to get the actual value.
|
258
|
-
def get
|
259
|
-
raise NotImplementedError
|
260
|
-
end
|
261
|
-
|
262
|
-
# Sets the field value.
|
263
|
-
#
|
264
|
-
# Override this to set the value.
|
265
|
-
def set(value)
|
266
|
-
raise NotImplementedError
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
# A check box.
|
271
|
-
class CheckBox < Field
|
272
|
-
# @!method set(value)
|
273
|
-
# Checks or unchecks the current checkbox.
|
274
|
-
#
|
275
|
-
# @param value [Boolean] +true+ to check the checkbox, +false+
|
276
|
-
# otherwise.
|
277
|
-
def_delegator :root, :set
|
278
|
-
|
279
|
-
# @return [Boolean] +true+ if the checkbox is checked, +false+
|
280
|
-
# otherwise.
|
281
|
-
def get
|
282
|
-
!! root.checked?
|
283
|
-
end
|
284
|
-
|
285
|
-
# @return +"yes"+ if the checkbox is checked, +"no"+ otherwise.
|
286
|
-
def to_s
|
287
|
-
get ? 'yes' : 'no'
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
# A select.
|
292
|
-
class Select < Field
|
293
|
-
# @return [String] The text of the selected option.
|
294
|
-
def get
|
295
|
-
option = root.find('[selected]') rescue nil
|
296
|
-
|
297
|
-
option && option.text
|
298
|
-
end
|
299
|
-
|
300
|
-
# Selects the given option.
|
301
|
-
#
|
302
|
-
# @param option [String] The text of the option to select.
|
303
|
-
def set(option)
|
304
|
-
root.find('option', text: option).select_option
|
305
|
-
end
|
306
|
-
|
307
|
-
# @!method to_s
|
308
|
-
# @return the text of the selected option, or the empty string if
|
309
|
-
# no option is selected.
|
310
|
-
def_delegator :get, :to_s
|
311
|
-
end
|
312
|
-
|
313
|
-
# A text field.
|
314
|
-
class TextField < Field
|
315
|
-
# @!method get
|
316
|
-
# @return The text field value.
|
317
|
-
def_delegator :root, :value, :get
|
318
|
-
|
319
|
-
# @!method set(value)
|
320
|
-
# Sets the text field value.
|
321
|
-
#
|
322
|
-
# @param value [String] the value to set.
|
323
|
-
def_delegator :root, :set
|
324
|
-
|
325
|
-
# @!method to_s
|
326
|
-
# @return the text field value, or the empty string if the field is
|
327
|
-
# empty.
|
328
|
-
def_delegator :get, :to_s
|
329
|
-
end
|
330
244
|
end
|
331
245
|
end
|