domkey 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/domkey/exception.rb +4 -0
- data/lib/domkey/version.rb +1 -1
- data/lib/domkey/view.rb +1 -0
- data/lib/domkey/view/checkbox_group.rb +12 -63
- data/lib/domkey/view/label_mapper.rb +7 -1
- data/lib/domkey/view/labeled_group.rb +22 -11
- data/lib/domkey/view/option_selectable.rb +102 -0
- data/lib/domkey/view/option_selectable_group.rb +120 -0
- data/lib/domkey/view/page_object.rb +11 -11
- data/lib/domkey/view/page_object_collection.rb +1 -1
- data/lib/domkey/view/radio_group.rb +9 -58
- data/lib/domkey/view/select_list.rb +67 -0
- data/lib/domkey/view/widgetry/dispatcher.rb +51 -0
- data/lib/domkey/view/widgetry/package.rb +49 -0
- data/spec/checkbox_group_spec.rb +81 -5
- data/spec/option_selectable_spec.rb +57 -0
- data/spec/radio_group_spec.rb +62 -4
- data/spec/select_list_spec.rb +212 -0
- metadata +11 -6
- data/lib/domkey/view/watir_widget.rb +0 -106
- data/lib/domkey/view/widgetry_package.rb +0 -48
- data/spec/watir_widget_select_spec.rb +0 -176
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0468e0993e03c228863792b2979fc0518aea17db
|
4
|
+
data.tar.gz: d36475ac117f17891905d01328dadca7bc08fe90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef11d67c2261cc2e7f4228bbe1f2466a1d82f4ebb8eedd895850c9e48d109080506ae91f6a40055184308e04f24395aedc5c81d0f48d5d7ba866d23b78a4e45d
|
7
|
+
data.tar.gz: 5b613799843aedb4959c422fe4dfcf91c28740903c78e4e86dc4b40e971ff803a77567df785e066ae702069bcc5becdb56246c98a7feba1012bc0e96b8cf49e4
|
data/lib/domkey/exception.rb
CHANGED
data/lib/domkey/version.rb
CHANGED
data/lib/domkey/view.rb
CHANGED
@@ -1,74 +1,23 @@
|
|
1
|
-
require 'domkey/view/
|
1
|
+
require 'domkey/view/option_selectable_group'
|
2
|
+
|
2
3
|
module Domkey
|
3
4
|
|
4
5
|
module View
|
5
6
|
|
6
|
-
# Acts like OptionSelectable object
|
7
7
|
# CheckboxGroup allows you to interact with PageObjectCollection of checkboxes as a single PageObject.
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
# clears all options and sets only the desired value(s)
|
14
|
-
# @param [String, Regexp] find value attribute or match value and set that checkbox
|
15
|
-
# @param [Array<String, Regexp>] find each value attribute and set each checkbox
|
16
|
-
# @param [False] uncheck any checked checkboxes
|
17
|
-
def set value
|
18
|
-
validate_scope
|
19
|
-
element.each { |e| e.clear }
|
20
|
-
return unless value
|
21
|
-
[*value].each do |v|
|
22
|
-
e = case v
|
23
|
-
when String
|
24
|
-
element.find { |e| e.value == v }
|
25
|
-
when Regexp
|
26
|
-
element.find { |e| e.value.match(v) }
|
27
|
-
end
|
28
|
-
e ? e.set : fail(Exception::Error, "Checkbox to be set not found by value: #{v.inspect}")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Array<String>] value attributes of each checked checkbox
|
33
|
-
def value
|
34
|
-
validate_scope
|
35
|
-
element.find_all { |e| e.set? }.map { |e| e.value }
|
36
|
-
end
|
37
|
-
|
38
|
-
def options
|
39
|
-
validate_scope
|
40
|
-
element.map { |e| e.value }
|
41
|
-
end
|
42
|
-
|
43
|
-
# convert to LabeledGroup settable by corresponding label text
|
44
|
-
def to_labeled
|
45
|
-
LabeledGroup.new(self)
|
46
|
-
end
|
47
|
-
|
48
|
-
# @yield [PageObject]
|
49
|
-
def each(&blk)
|
50
|
-
validate_scope
|
51
|
-
super(&blk)
|
52
|
-
end
|
53
|
-
|
54
|
-
# @return [Array<PageObject>]
|
55
|
-
def to_a
|
56
|
-
validate_scope
|
57
|
-
super
|
58
|
-
end
|
8
|
+
# Acts like OptionSelectable
|
9
|
+
# Checkboxes collection is constrained by the same name attribute
|
10
|
+
# Behaves like a multi Select list.
|
11
|
+
# It can have none, one or more options selected
|
12
|
+
class CheckboxGroup < OptionSelectableGroup
|
59
13
|
|
60
14
|
private
|
61
15
|
|
62
|
-
#
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def validate_scope
|
68
|
-
return if @validated
|
69
|
-
groups = element.map { |e| e.name }.uniq
|
70
|
-
fail(Exception::Error, "CheckboxGroup definition scope too broad: Found #{groups.count} checkbox groups with names: #{groups}") unless (groups.size == 1)
|
71
|
-
@validated = true
|
16
|
+
# @api private
|
17
|
+
# unselects all checkboxes before setting it with desired value
|
18
|
+
def before_set
|
19
|
+
validate_scope
|
20
|
+
each { |o| o.set false }
|
72
21
|
end
|
73
22
|
end
|
74
23
|
end
|
@@ -2,8 +2,9 @@ module Domkey
|
|
2
2
|
|
3
3
|
module View
|
4
4
|
|
5
|
-
# return collection of PageObjects for label locators corresponding to id of each element in a collection
|
6
5
|
class LabelMapper
|
6
|
+
|
7
|
+
# return collection of PageObjects for label locators corresponding to id of each element in a collection
|
7
8
|
# @param [Array<PageObject>]
|
8
9
|
# @param [PageObjectCollection]
|
9
10
|
# @return [Array<PageObject>] where each PageObject is a locator for label for an id of a PageObject passed in parameters
|
@@ -12,6 +13,11 @@ module Domkey
|
|
12
13
|
PageObject.new -> { label(for: e.element.id) }, e.container
|
13
14
|
end
|
14
15
|
end
|
16
|
+
|
17
|
+
# provide PageObject wrapping label corresponding to id of element in pageobject.
|
18
|
+
def self.find pageobject
|
19
|
+
PageObject.new -> { label(for: pageobject.element.id) }, pageobject.container
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -16,10 +16,31 @@ module Domkey
|
|
16
16
|
__setobj__(group)
|
17
17
|
end
|
18
18
|
|
19
|
+
def before_set
|
20
|
+
__getobj__.set false
|
21
|
+
end
|
22
|
+
|
19
23
|
# @param value [String] a label text to set a corresponding element referenced
|
20
24
|
# @param value [Array<String>] one or more labels
|
21
25
|
def set value
|
22
|
-
|
26
|
+
before_set
|
27
|
+
set_strategy(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<String>] label texts for selected elements
|
31
|
+
def value
|
32
|
+
selected_ones = __getobj__.find_all { |e| e.element.set? }
|
33
|
+
LabelMapper.for(selected_ones).map { |e| e.element.text }
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Array<String>] label texts for all elements in a group
|
37
|
+
def options
|
38
|
+
LabelMapper.for(__getobj__).map { |e| e.element.text }
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def set_strategy value
|
23
44
|
labels = self.options
|
24
45
|
indices = [*value].map do |what|
|
25
46
|
i = case what
|
@@ -35,16 +56,6 @@ module Domkey
|
|
35
56
|
end
|
36
57
|
end
|
37
58
|
|
38
|
-
# @return [Array<String>] label texts for selected elements
|
39
|
-
def value
|
40
|
-
selected_ones = __getobj__.find_all { |e| e.element.set? }
|
41
|
-
LabelMapper.for(selected_ones).map { |e| e.element.text }
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [Array<String>] label texts for all elements in a group
|
45
|
-
def options
|
46
|
-
LabelMapper.for(__getobj__).map { |e| e.element.text }
|
47
|
-
end
|
48
59
|
end
|
49
60
|
end
|
50
61
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Domkey
|
2
|
+
module View
|
3
|
+
module OptionSelectable
|
4
|
+
|
5
|
+
# clears all options and sets only the desired value(s)
|
6
|
+
# @param [String, Regexp] sets default designated option by String or Regexp
|
7
|
+
# @param [Array<String, Regexp>] sets each String, Regexp
|
8
|
+
# @param [False] unselects all options
|
9
|
+
# @param [Hash{how => value}] selects by how strategy where how is a symbol :label, :index, :text, :value
|
10
|
+
# Clients need to implement individual strategy for each 'how' => 'value' pair based on what it means to be selected by what
|
11
|
+
def set value
|
12
|
+
before_set
|
13
|
+
set_strategy value
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param [] opts. Represents a qualifier of what types of options to return. defaults to empty
|
17
|
+
# @return [Array<String>] when opts param emtpy returns array of default strings implemented by client
|
18
|
+
# @param [Symbol,Array<Symbol>] symbols represents what option selector to return
|
19
|
+
# @return [Array<Hash{what => value}] where what is a symbol for option selector, :index, :value, :text, :label
|
20
|
+
def value *opts
|
21
|
+
opts = opts.flatten
|
22
|
+
return value_by_default if (opts.empty? || opts.find { |e| e.kind_of?(String) })
|
23
|
+
value_by_options opts
|
24
|
+
end
|
25
|
+
|
26
|
+
# similar strategy to value but returns all options and not only selected ones
|
27
|
+
def options *opts
|
28
|
+
opts = opts.flatten
|
29
|
+
return options_by_default if opts.empty?
|
30
|
+
options_by opts
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def options_by_default
|
36
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
37
|
+
end
|
38
|
+
|
39
|
+
def options_by opts
|
40
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
41
|
+
end
|
42
|
+
|
43
|
+
def value_by_default
|
44
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
45
|
+
end
|
46
|
+
|
47
|
+
def value_by_options options
|
48
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
49
|
+
end
|
50
|
+
|
51
|
+
def before_set
|
52
|
+
# hook. client can provide actions to be taken before setting this PageObject
|
53
|
+
end
|
54
|
+
|
55
|
+
# strategy for selecting OptionSelectable object
|
56
|
+
def set_strategy value
|
57
|
+
case value
|
58
|
+
when String
|
59
|
+
set_by_string(value)
|
60
|
+
when Regexp
|
61
|
+
set_by_regexp(value)
|
62
|
+
when Array
|
63
|
+
value.each { |v| set_strategy(v) }
|
64
|
+
when Hash
|
65
|
+
value.each_pair do |how, value|
|
66
|
+
case how
|
67
|
+
when :label
|
68
|
+
set_by_label(value)
|
69
|
+
when :text
|
70
|
+
set_strategy(value)
|
71
|
+
when :index
|
72
|
+
set_by_index(value)
|
73
|
+
when :value
|
74
|
+
set_by_value(value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_by_string value
|
81
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_by_regexp value
|
85
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_by_label value
|
89
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_by_index value
|
93
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
94
|
+
end
|
95
|
+
|
96
|
+
def set_by_value value
|
97
|
+
fail Exception::NotImplementedError, "Subclass responsible for implementing"
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'domkey/view/option_selectable'
|
2
|
+
require 'domkey/view/labeled_group'
|
3
|
+
|
4
|
+
module Domkey
|
5
|
+
module View
|
6
|
+
|
7
|
+
#OptionsSelectable CheckboxGroup, RadioGroup
|
8
|
+
class OptionSelectableGroup < PageObjectCollection
|
9
|
+
|
10
|
+
include OptionSelectable
|
11
|
+
|
12
|
+
def set_by_index value
|
13
|
+
[*value].each do |i|
|
14
|
+
self[i.to_i].set(true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_by_label value
|
19
|
+
to_labeled.__send__(:set_strategy, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_by_regexp value
|
23
|
+
o = find { |o| o.value.match(value) }
|
24
|
+
o ? o.element.set : fail(Exception::NotFoundError, "Element not found with value: #{v.inspect}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_by_string value
|
28
|
+
o = find { |o| o.value == value }
|
29
|
+
o ? o.element.set : fail(Exception::NotFoundError, "Element not found with value: #{v.inspect}")
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def value_by_default
|
34
|
+
validate_scope
|
35
|
+
find_all { |e| e.element.set? }.map { |e| e.value }
|
36
|
+
end
|
37
|
+
|
38
|
+
def value_by_options opts
|
39
|
+
validate_scope
|
40
|
+
result = []
|
41
|
+
each_with_index do |e, i|
|
42
|
+
if e.element.set?
|
43
|
+
|
44
|
+
v = opts.map do |o|
|
45
|
+
case o
|
46
|
+
when :index
|
47
|
+
[o, i]
|
48
|
+
when :label, :text
|
49
|
+
[o, LabelMapper.find(e).element.text]
|
50
|
+
else
|
51
|
+
[o, e.send(o)]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
result << Hash[v]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
def options_by_default
|
61
|
+
validate_scope
|
62
|
+
map { |e| e.value }
|
63
|
+
end
|
64
|
+
|
65
|
+
def options_by opts
|
66
|
+
validate_scope
|
67
|
+
result = []
|
68
|
+
each_with_index do |e, i|
|
69
|
+
|
70
|
+
v = opts.map do |o|
|
71
|
+
case o
|
72
|
+
when :index
|
73
|
+
[o, i]
|
74
|
+
when :label, :text
|
75
|
+
[o, LabelMapper.find(e).element.text]
|
76
|
+
else
|
77
|
+
[o, e.send(o)]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
result << Hash[v]
|
81
|
+
end
|
82
|
+
|
83
|
+
result
|
84
|
+
end
|
85
|
+
|
86
|
+
# convert to LabeledGroup settable by corresponding label text
|
87
|
+
def to_labeled
|
88
|
+
LabeledGroup.new(self)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# @yield [PageObject]
|
93
|
+
def each(&blk)
|
94
|
+
validate_scope
|
95
|
+
super(&blk)
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [Array<PageObject>]
|
99
|
+
def to_a
|
100
|
+
validate_scope
|
101
|
+
super
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# precondition on acting on this collection
|
107
|
+
# @return [true] when all radios in collection share the same name attribute
|
108
|
+
# @raise [Exception::Error] when where is more than one unique name attribute
|
109
|
+
# --
|
110
|
+
# returns true on subsequent unless magically more radios show up after initial validation
|
111
|
+
def validate_scope
|
112
|
+
return if @validated
|
113
|
+
groups = element.map { |e| e.name }.uniq
|
114
|
+
fail(Exception::Error, "RadioGroup definition scope too broad: Found #{groups.count} radio groups with names: #{groups}") unless (groups.size == 1)
|
115
|
+
@validated = true
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'domkey/view/
|
2
|
-
require 'domkey/view/
|
1
|
+
require 'domkey/view/widgetry/package'
|
2
|
+
require 'domkey/view/widgetry/dispatcher'
|
3
3
|
|
4
4
|
module Domkey
|
5
5
|
|
@@ -52,13 +52,13 @@ module Domkey
|
|
52
52
|
class PageObject
|
53
53
|
|
54
54
|
# @api private
|
55
|
-
include
|
55
|
+
include Widgetry::Package
|
56
56
|
|
57
57
|
# Each Semantic PageObject defines what value means for itself
|
58
58
|
# @param [SemanticValue] Delegated to WebdriverElement and we expect it to respond to set
|
59
59
|
# @parma [Hash{Symbol => SemanticValue}]
|
60
60
|
def set value
|
61
|
-
return
|
61
|
+
return widgetry_dispatcher.set value unless value.respond_to?(:each_pair)
|
62
62
|
value.each_pair { |k, v| package.fetch(k).set(v) }
|
63
63
|
end
|
64
64
|
|
@@ -68,22 +68,22 @@ module Domkey
|
|
68
68
|
# @return [SemanticValue] delegated to WebdriverElement and we expect it to respond to value message
|
69
69
|
# @return [Hash{Symbol => SemanticValue}]
|
70
70
|
def value
|
71
|
-
return
|
71
|
+
return widgetry_dispatcher.value unless package.respond_to?(:each_pair)
|
72
72
|
Hash[package.map { |key, pageobject| [key, pageobject.value] }]
|
73
73
|
end
|
74
74
|
|
75
75
|
def options
|
76
|
-
return
|
76
|
+
return widgetry_dispatcher.options unless package.respond_to?(:each_pair)
|
77
77
|
Hash[package.map { |key, pageobject| [key, pageobject.options] }]
|
78
78
|
end
|
79
79
|
|
80
80
|
private
|
81
81
|
|
82
|
-
# wrap instantiator with strategy for setting and getting value for
|
82
|
+
# wrap instantiator with strategy for setting and getting value for underlying object
|
83
83
|
# expects that element to respond to set and value
|
84
|
-
# @returns [
|
85
|
-
def
|
86
|
-
|
84
|
+
# @returns [Widgetry::Dispatcher] that responds to set, value, options
|
85
|
+
def widgetry_dispatcher
|
86
|
+
Widgetry.dispatcher(instantiator)
|
87
87
|
end
|
88
88
|
|
89
89
|
# @api private
|
@@ -96,7 +96,7 @@ module Domkey
|
|
96
96
|
begin
|
97
97
|
# peek inside suitcase that is proc. XXX ouch, ugly
|
98
98
|
peeked_inside = package.call
|
99
|
-
rescue
|
99
|
+
rescue StandardError
|
100
100
|
return package #suitecase exploded, proc returned
|
101
101
|
end
|
102
102
|
if peeked_inside.respond_to?(:each_pair) # hash
|