domkey 0.1.0 → 0.2.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/.gitmodules +3 -0
- data/README.md +2 -4
- data/Rakefile +4 -1
- data/lib/domkey/version.rb +1 -1
- data/lib/domkey/view.rb +42 -4
- data/lib/domkey/view/cargo.rb +92 -0
- data/lib/domkey/view/checkbox_group.rb +75 -0
- data/lib/domkey/view/label_mapper.rb +18 -0
- data/lib/domkey/view/labeled_group.rb +50 -0
- data/lib/domkey/view/page_object.rb +85 -85
- data/lib/domkey/view/page_object_collection.rb +31 -49
- data/lib/domkey/view/radio_group.rb +70 -0
- data/lib/domkey/view/watir_widget.rb +106 -0
- data/lib/domkey/view/widgetry_package.rb +48 -0
- data/spec/checkbox_group_spec.rb +81 -0
- data/spec/html/test.html +61 -5
- data/spec/labeled_group_spec.rb +118 -0
- data/spec/page_object_collection_spec.rb +14 -14
- data/spec/page_object_decorators_spec.rb +41 -52
- data/spec/page_object_spec.rb +23 -18
- data/spec/page_spec.rb +12 -12
- data/spec/radio_group_spec.rb +85 -0
- data/spec/selenium_webdriver_api_example.rb +42 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/view_cargo_spec.rb +106 -0
- data/spec/view_dom_spec.rb +50 -16
- data/spec/view_doms_spec.rb +7 -7
- data/spec/watir_widget_select_spec.rb +176 -0
- data/spec/watirspec_pageobjects/watirspec_spec.rb +12 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45e6ac05a48d93eede629f82f2a5b04b14037f62
|
4
|
+
data.tar.gz: 9c3b5d281b8b000852489e1933de6b855b2975e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa5af099b7354c11538d238e9c4a59eb91cf41a7f7845fe10bd92659af309e7e65ebf1630d722952e17a39ca1a0e9a790e955a00d91df35a074ea9de9b83d3d1
|
7
|
+
data.tar.gz: 2fe75c7ca69ba9f0656491cea2a358a048f815b5da77bc7d614425c4a4a5a353b653364b4f13b522e2a366de699744389e3244dcde80822a7ed9fd6ab727fe56
|
data/.gitmodules
ADDED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# Domain
|
1
|
+
# Domain Specific PageObject for Selenium Watir-Webdriver
|
2
2
|
|
3
|
-
PageObject that models
|
4
|
-
|
5
|
-
Watir-Webdriver is the Bee's Knees! Now with Domain Specific PageObject Factory!
|
3
|
+
PageObject that models specific domain first and browser code second.
|
6
4
|
|
7
5
|
Watir-Webdriver is the Bee's Knees! Now with Domain Specific PageObject Factory!
|
8
6
|
|
data/Rakefile
CHANGED
data/lib/domkey/version.rb
CHANGED
data/lib/domkey/view.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'domkey/view/page_object'
|
2
2
|
require 'domkey/view/page_object_collection'
|
3
|
+
require 'domkey/view/radio_group'
|
4
|
+
require 'domkey/view/checkbox_group'
|
5
|
+
require 'domkey/view/cargo'
|
6
|
+
|
3
7
|
module Domkey
|
4
8
|
|
5
9
|
module View
|
@@ -7,18 +11,25 @@ module Domkey
|
|
7
11
|
module ClassMethods
|
8
12
|
|
9
13
|
# PageObjectCollection factory
|
10
|
-
def doms(key, &
|
14
|
+
def doms(key, &package)
|
11
15
|
send :define_method, key do
|
12
|
-
PageObjectCollection.new
|
16
|
+
PageObjectCollection.new package, Proc.new { browser }
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
16
20
|
# PageObject factory
|
17
|
-
def dom(key, &
|
21
|
+
def dom(key, &package)
|
18
22
|
send :define_method, key do
|
19
|
-
PageObject.new
|
23
|
+
PageObject.new package, Proc.new { browser }
|
20
24
|
end
|
21
25
|
end
|
26
|
+
|
27
|
+
# build Cargo with model and view
|
28
|
+
# @return [Domkey::View::Cargo]
|
29
|
+
def cargo model, browser: nil
|
30
|
+
Cargo.new model: model, view: self.new(browser)
|
31
|
+
end
|
32
|
+
|
22
33
|
end
|
23
34
|
|
24
35
|
def self.included(klass)
|
@@ -27,13 +38,40 @@ module Domkey
|
|
27
38
|
|
28
39
|
attr_accessor :browser
|
29
40
|
|
41
|
+
# @param [Watir::Browser] (false)
|
30
42
|
def initialize browser=nil
|
31
43
|
@browser = browser
|
32
44
|
end
|
33
45
|
|
46
|
+
# browser for this view.
|
47
|
+
# if View was initialized without a browser then default Domkey.browser is provided
|
48
|
+
# @return [Watir::Browser]
|
34
49
|
def browser
|
35
50
|
@browser ||= Domkey.browser
|
36
51
|
end
|
37
52
|
|
53
|
+
def set value
|
54
|
+
Cargo.new(model: value, view: self).set
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param [Hash{Symbol => Object}] view data where Symbol is semantic descriptor for a pageobject in the view
|
58
|
+
# @param [Symbol] for one pageobject
|
59
|
+
# @param [Array<Symbol>] for array of pageobjects
|
60
|
+
#
|
61
|
+
# @return [Hash{Symbol => Object}] data from the view
|
62
|
+
def value value
|
63
|
+
# transform value into hash
|
64
|
+
value = case value
|
65
|
+
when Symbol
|
66
|
+
{value => nil}
|
67
|
+
when Array
|
68
|
+
#array of symbols
|
69
|
+
Hash[value.map { |v| [v, nil] }]
|
70
|
+
when Hash
|
71
|
+
value
|
72
|
+
end
|
73
|
+
Cargo.new(model: value, view: self).value
|
74
|
+
end
|
75
|
+
|
38
76
|
end
|
39
77
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Domkey
|
2
|
+
|
3
|
+
module View
|
4
|
+
|
5
|
+
# Data shipping between Model and View
|
6
|
+
# Sends data to view. Grabs data from view
|
7
|
+
#
|
8
|
+
# For specialized transfer object a client would sublcass this Cargo,
|
9
|
+
# by default View.cargo factory method is provided for regular data transfer object
|
10
|
+
#
|
11
|
+
# @usage
|
12
|
+
#
|
13
|
+
# class MyView
|
14
|
+
# include Domkey::View
|
15
|
+
#
|
16
|
+
# dom(:city) { text_field(id: 'city2') }
|
17
|
+
#
|
18
|
+
# def fruit
|
19
|
+
# RadioGroup.new -> { checkboxes(name: 'fruit') }
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# model = {city: 'Austin', fruit: 'tomato'}
|
24
|
+
# cargo = MyView.cargo model
|
25
|
+
# cargo.set #=> sets view.city with model[:city] and view.fruit with model[:fruit]
|
26
|
+
# cargo.value #=> returns {city: 'Austing', fruit: 'tomato'}
|
27
|
+
#
|
28
|
+
# class MyCargo < Domkey::View::Cargo
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# model = {city: 'Mordor'}
|
33
|
+
# view = MyView.new
|
34
|
+
# cargo = MyCargo.new view: view, model: model
|
35
|
+
# cargo.set
|
36
|
+
#
|
37
|
+
class Cargo
|
38
|
+
|
39
|
+
attr_accessor :view, :model
|
40
|
+
|
41
|
+
def initialize model: nil, view: nil
|
42
|
+
@model = model
|
43
|
+
@view = view
|
44
|
+
end
|
45
|
+
|
46
|
+
# set each pageobject in the view with the value from the model
|
47
|
+
def set
|
48
|
+
@model.each_pair do |key, value|
|
49
|
+
set_pageobject key, value
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# extracts value for each pageobject identified by the model
|
55
|
+
# @returns [Model]
|
56
|
+
def value
|
57
|
+
extracted = {}
|
58
|
+
@model.each_pair do |key, value|
|
59
|
+
extracted[key] = value_for_pageobject(key, value)
|
60
|
+
end
|
61
|
+
extracted
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def set_pageobject key, value
|
67
|
+
@view.send(key).set value
|
68
|
+
end
|
69
|
+
|
70
|
+
def value_for_pageobject key, value
|
71
|
+
object = @view.send(key)
|
72
|
+
# object is pageobject
|
73
|
+
if object.method(:value).parameters.empty?
|
74
|
+
object.value
|
75
|
+
else
|
76
|
+
# object is another view that has collection of pageobject
|
77
|
+
object.value value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
## submits view
|
82
|
+
#def submit
|
83
|
+
#
|
84
|
+
#end
|
85
|
+
#
|
86
|
+
## is view ready?
|
87
|
+
#def ready?
|
88
|
+
#
|
89
|
+
#end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'domkey/view/labeled_group'
|
2
|
+
module Domkey
|
3
|
+
|
4
|
+
module View
|
5
|
+
|
6
|
+
# Acts like OptionSelectable object
|
7
|
+
# CheckboxGroup allows you to interact with PageObjectCollection of checkboxes as a single PageObject.
|
8
|
+
# Checkboxes collection is constrained by the same name attribute and acts like on object.
|
9
|
+
# It behaves like a Multi Select list.
|
10
|
+
# It can none, one or more options selected
|
11
|
+
class CheckboxGroup < PageObjectCollection
|
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
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# precondition on acting on this collection
|
63
|
+
# @return [true] when all checkboxes in collection share the same name attribute
|
64
|
+
# @raise [Exception::Error] when where is more than one unique name attribute
|
65
|
+
# --
|
66
|
+
# returns true on subsequent unless magically more radios show up after initial validation
|
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
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Domkey
|
2
|
+
|
3
|
+
module View
|
4
|
+
|
5
|
+
# return collection of PageObjects for label locators corresponding to id of each element in a collection
|
6
|
+
class LabelMapper
|
7
|
+
# @param [Array<PageObject>]
|
8
|
+
# @param [PageObjectCollection]
|
9
|
+
# @return [Array<PageObject>] where each PageObject is a locator for label for an id of a PageObject passed in parameters
|
10
|
+
def self.for collection
|
11
|
+
collection.map do |e|
|
12
|
+
PageObject.new -> { label(for: e.element.id) }, e.container
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'domkey/view/label_mapper'
|
3
|
+
module Domkey
|
4
|
+
|
5
|
+
module View
|
6
|
+
|
7
|
+
# Interfact to CheckboxGroup and RadioGroup elements through corresponding label elements;
|
8
|
+
# radio and checkbox controls form a group by name attribute
|
9
|
+
# however they don't have visible text indicators to the user who is looking at the page.
|
10
|
+
# The common strategy is to provide a lable element such that
|
11
|
+
# its for: attribute value maps to id: attribute value of an individual control in a group.
|
12
|
+
# The labels become visual indicators for the user. Clicking corresponding lable activates the control.
|
13
|
+
class LabeledGroup < SimpleDelegator
|
14
|
+
|
15
|
+
def initialize group
|
16
|
+
__setobj__(group)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param value [String] a label text to set a corresponding element referenced
|
20
|
+
# @param value [Array<String>] one or more labels
|
21
|
+
def set value
|
22
|
+
__getobj__.set false
|
23
|
+
labels = self.options
|
24
|
+
indices = [*value].map do |what|
|
25
|
+
i = case what
|
26
|
+
when String
|
27
|
+
labels.index(what)
|
28
|
+
when Regexp
|
29
|
+
labels.index(labels.find { |e| e.match(what) })
|
30
|
+
end
|
31
|
+
i ? i : fail(Exception::Error, "Label text to set not found for value: #{what.inspect}")
|
32
|
+
end
|
33
|
+
indices.each do |i|
|
34
|
+
__getobj__[i].element.set
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
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
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,120 +1,120 @@
|
|
1
|
+
require 'domkey/view/widgetry_package'
|
2
|
+
require 'domkey/view/watir_widget'
|
3
|
+
|
1
4
|
module Domkey
|
2
5
|
|
3
6
|
module View
|
4
7
|
|
8
|
+
# PageObject represents an semantically essential area in a View
|
9
|
+
# It is an object that responds to set and value as the main way of sending data to it.
|
10
|
+
# it is composed of one or more watir elements.
|
11
|
+
# PageObject encapuslates the widgetry of DOM elements to provide semantic interfact to the user of the widgetry
|
12
|
+
#
|
13
|
+
# Compose PageObject with package and container
|
14
|
+
#
|
15
|
+
# What is a container? it's a proc, a callable object that plays a role of a container for package widgetry
|
16
|
+
# container can be one of:
|
17
|
+
# - browser (default)
|
18
|
+
# - a pageobject
|
19
|
+
#
|
20
|
+
# What is package? it's a proc of DOM elements widgetry that can be found inside the container
|
21
|
+
# package can be one of the following:
|
22
|
+
# - definition of single watir element i.e. `-> { text_field(:id, 'foo')}`
|
23
|
+
# - a pageobject i.e. previously instantiated definition
|
24
|
+
# - hash where key defines subelement and value a definition or pageobject
|
25
|
+
#
|
26
|
+
# Usage:
|
27
|
+
# Clients would not usually instantate this class.
|
28
|
+
# A client class which acts as a View would use a :dom factory method to create PageObjects
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# class MyView
|
32
|
+
# include Domkey::View
|
33
|
+
#
|
34
|
+
# dom(:headline) { text_field(id:, 'some_desc_text') }
|
35
|
+
#
|
36
|
+
# def property
|
37
|
+
# PropertyPanel.new browser.div(id: 'container')
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# class PropertyPanel
|
42
|
+
# include Domkey::View
|
43
|
+
# dom(:headline) { text_field(class: 'headline_for_house') }
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# view = MyView.new
|
47
|
+
# view.headline.set 'HomeAway Rules!'
|
48
|
+
# view.value #=> returns 'HomeAway Rules!'
|
49
|
+
# view.property.headline.set 'Awesome Vactaion Home'
|
50
|
+
# view.property.headline.value #=> returns 'Awesome Vaction Home'
|
51
|
+
#
|
5
52
|
class PageObject
|
6
53
|
|
7
|
-
|
8
|
-
|
9
|
-
# PageObject represents an semantically essential area in a View
|
10
|
-
# It is an object that responds to set and value as the main way of sending data to it.
|
11
|
-
# it is composed of one or more watir elements.
|
12
|
-
# PageObject encapuslates the widgetry of DOM elements to provide semantic interfact to the user of the widgetry
|
13
|
-
#
|
14
|
-
# Compose PageObject with watirproc and container
|
15
|
-
#
|
16
|
-
# What is a container? it's a proc, a callable object that plays a role of a container for watirproc widgetry
|
17
|
-
# container can be one of:
|
18
|
-
# - browser (default)
|
19
|
-
# - a pageobject
|
20
|
-
#
|
21
|
-
# What is watirproc? it's a proc of DOM elements widgetry that can be found inside the container
|
22
|
-
# watirproc can be one of the following:
|
23
|
-
# - definition of single watir element i.e. `-> { text_field(:id, 'foo')}`
|
24
|
-
# - a pageobject i.e. previously instantiated definition
|
25
|
-
# - hash where key defines subelement and value a definition or pageobject
|
26
|
-
#
|
27
|
-
# Usage:
|
28
|
-
# Clients would not usually instantate this class.
|
29
|
-
# A client class which acts as a View would use a :dom factory method to create PageObjects
|
30
|
-
# Example:
|
31
|
-
#
|
32
|
-
# class MyView
|
33
|
-
# include Domkey::View
|
34
|
-
#
|
35
|
-
# dom(:headline) { text_field(id:, 'some_desc_text') }
|
36
|
-
#
|
37
|
-
# def property
|
38
|
-
# PropertyPanel.new browser.div(id: 'container')
|
39
|
-
# end
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# class PropertyPanel
|
43
|
-
# include Domkey::View
|
44
|
-
# dom(:headline) { text_field(class: 'headline_for_house') }
|
45
|
-
# end
|
46
|
-
#
|
47
|
-
# view = MyView.new
|
48
|
-
# view.headline.set 'HomeAway Rules!'
|
49
|
-
# view.value #=> returns 'HomeAway Rules!'
|
50
|
-
# view.property.headline.set 'Awesome Vactaion Home'
|
51
|
-
# view.property.headline.value #=> returns 'Awesome Vaction Home'
|
52
|
-
#
|
53
|
-
def initialize watirproc, container=lambda { Domkey.browser }
|
54
|
-
@container = container
|
55
|
-
@watirproc = initialize_this watirproc
|
56
|
-
end
|
54
|
+
# @api private
|
55
|
+
include WidgetryPackage
|
57
56
|
|
57
|
+
# Each Semantic PageObject defines what value means for itself
|
58
|
+
# @param [SemanticValue] Delegated to WebdriverElement and we expect it to respond to set
|
59
|
+
# @parma [Hash{Symbol => SemanticValue}]
|
58
60
|
def set value
|
59
|
-
return
|
60
|
-
value.each_pair { |k, v|
|
61
|
+
return watir_widget.set value unless value.respond_to?(:each_pair)
|
62
|
+
value.each_pair { |k, v| package.fetch(k).set(v) }
|
61
63
|
end
|
62
64
|
|
65
|
+
alias_method :value=, :set
|
66
|
+
|
67
|
+
# Each Semantic PageObject defines what value means for itself
|
68
|
+
# @return [SemanticValue] delegated to WebdriverElement and we expect it to respond to value message
|
69
|
+
# @return [Hash{Symbol => SemanticValue}]
|
63
70
|
def value
|
64
|
-
return
|
65
|
-
Hash[
|
71
|
+
return watir_widget.value unless package.respond_to?(:each_pair)
|
72
|
+
Hash[package.map { |key, pageobject| [key, pageobject.value] }]
|
66
73
|
end
|
67
74
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
return watirproc.fetch(key).element if key
|
72
|
-
Hash[watirproc.map { |key, watirproc| [key, watirproc.element] }]
|
75
|
+
def options
|
76
|
+
return watir_widget.options unless package.respond_to?(:each_pair)
|
77
|
+
Hash[package.map { |key, pageobject| [key, pageobject.options] }]
|
73
78
|
end
|
74
79
|
|
75
80
|
private
|
76
81
|
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
|
82
|
+
# wrap instantiator with strategy for setting and getting value for watir object
|
83
|
+
# expects that element to respond to set and value
|
84
|
+
# @returns [WatirWidget]
|
85
|
+
def watir_widget
|
86
|
+
WatirWidget.new(instantiator)
|
87
|
+
end
|
88
|
+
|
89
|
+
# @api private
|
90
|
+
# Recursive. Examines each packages and turns each Proc into PageObject
|
91
|
+
def initialize_this package
|
92
|
+
if package.respond_to?(:each_pair) #hash
|
93
|
+
Hash[package.map { |key, package| [key, PageObject.new(package, container)] }]
|
81
94
|
else
|
82
|
-
if
|
95
|
+
if package.respond_to?(:call) #proc
|
83
96
|
begin
|
84
97
|
# peek inside suitcase that is proc. XXX ouch, ugly
|
85
|
-
peeked_inside =
|
98
|
+
peeked_inside = package.call
|
86
99
|
rescue NoMethodError
|
87
|
-
return
|
100
|
+
return package #suitecase exploded, proc returned
|
88
101
|
end
|
89
102
|
if peeked_inside.respond_to?(:each_pair) # hash
|
90
103
|
return initialize_this peeked_inside
|
91
104
|
elsif peeked_inside.respond_to?(:wd) # watir element
|
92
105
|
return lambda { peeked_inside }
|
93
|
-
elsif peeked_inside.respond_to?(:
|
94
|
-
return peeked_inside.
|
106
|
+
elsif peeked_inside.respond_to?(:package) #pageobject
|
107
|
+
return peeked_inside.package
|
95
108
|
else
|
96
|
-
fail Exception::Error, "
|
109
|
+
fail Exception::Error, "package must be kind of hash, watirelement or pageobject but I got this: #{package}"
|
97
110
|
end
|
98
|
-
elsif
|
99
|
-
return
|
111
|
+
elsif package.respond_to?(:package) #pageobject
|
112
|
+
return package.package
|
100
113
|
else
|
101
|
-
fail Exception::Error, "
|
114
|
+
fail Exception::Error, "package must be kind of hash, watirelement or pageobject but I got this: #{package}"
|
102
115
|
end
|
103
116
|
end
|
104
117
|
end
|
105
|
-
|
106
|
-
# talk to the browser executor.
|
107
|
-
# returns runtime element in a specified container
|
108
|
-
# expects that element to respond to set and value
|
109
|
-
def instantiator
|
110
|
-
container_instantiator.instance_exec(&watirproc)
|
111
|
-
end
|
112
|
-
|
113
|
-
# talk to the browser
|
114
|
-
# returns runtime container element in a browser/driver
|
115
|
-
def container_instantiator
|
116
|
-
container.respond_to?(:call) ? container.call : container.send(:instantiator)
|
117
|
-
end
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|