testcentricity_web 4.3.1 → 4.4.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/CHANGELOG.md +42 -12
- data/LICENSE.md +1 -1
- data/README.md +1794 -697
- data/lib/devices/devices.yml +144 -216
- data/lib/testcentricity_web/browser_helper.rb +33 -4
- data/lib/testcentricity_web/data_objects/environment.rb +96 -13
- data/lib/testcentricity_web/exception_queue_helper.rb +5 -6
- data/lib/testcentricity_web/version.rb +1 -1
- data/lib/testcentricity_web/web_core/page_object.rb +53 -49
- data/lib/testcentricity_web/web_core/page_objects_helper.rb +20 -11
- data/lib/testcentricity_web/web_core/page_section.rb +31 -34
- data/lib/testcentricity_web/web_core/webdriver_helper.rb +379 -252
- data/lib/testcentricity_web/web_elements/audio.rb +6 -4
- data/lib/testcentricity_web/web_elements/button.rb +7 -4
- data/lib/testcentricity_web/web_elements/checkbox.rb +149 -147
- data/lib/testcentricity_web/web_elements/file_field.rb +38 -36
- data/lib/testcentricity_web/web_elements/image.rb +75 -70
- data/lib/testcentricity_web/web_elements/label.rb +6 -4
- data/lib/testcentricity_web/web_elements/link.rb +15 -13
- data/lib/testcentricity_web/web_elements/list.rb +171 -169
- data/lib/testcentricity_web/web_elements/media.rb +384 -379
- data/lib/testcentricity_web/web_elements/radio.rb +135 -133
- data/lib/testcentricity_web/web_elements/range.rb +16 -29
- data/lib/testcentricity_web/web_elements/select_list.rb +247 -245
- data/lib/testcentricity_web/web_elements/table.rb +575 -573
- data/lib/testcentricity_web/web_elements/textfield.rb +143 -139
- data/lib/testcentricity_web/web_elements/ui_element.rb +1171 -0
- data/lib/testcentricity_web/web_elements/video.rb +39 -37
- data/lib/testcentricity_web/world_extensions.rb +37 -4
- data/lib/testcentricity_web.rb +4 -23
- metadata +27 -79
- data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +0 -1148
@@ -1,8 +1,10 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Elements
|
3
|
+
class Audio < Media
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :audio
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
8
10
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Elements
|
3
|
+
class Button < UIElement
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :button
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
8
10
|
end
|
11
|
+
|
@@ -1,181 +1,183 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Elements
|
3
|
+
class CheckBox < UIElement
|
4
|
+
attr_accessor :proxy
|
5
|
+
attr_accessor :label
|
6
|
+
attr_accessor :input
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
def initialize(name, parent, locator, context)
|
9
|
+
super
|
10
|
+
@type = :checkbox
|
11
|
+
check_spec = {
|
12
|
+
input: nil,
|
13
|
+
proxy: nil,
|
14
|
+
label: nil
|
15
|
+
}
|
16
|
+
define_custom_elements(check_spec)
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
def define_custom_elements(element_spec)
|
20
|
+
element_spec.each do |element, value|
|
21
|
+
case element
|
22
|
+
when :input
|
23
|
+
@input = value
|
24
|
+
when :proxy
|
25
|
+
@proxy = value
|
26
|
+
when :label
|
27
|
+
@label = value
|
28
|
+
else
|
29
|
+
raise "#{element} is not a recognized checkbox element"
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Does checkbox object exists?
|
34
|
-
#
|
35
|
-
# @return [Boolean]
|
36
|
-
# @example
|
37
|
-
# remember_me_checkbox.exists?
|
38
|
-
#
|
39
|
-
def exists?
|
40
|
-
obj, = find_object(:all)
|
41
|
-
obj != nil
|
42
|
-
end
|
43
|
-
|
44
|
-
# Is checkbox checked?
|
45
|
-
#
|
46
|
-
# @return [Boolean]
|
47
|
-
# @example
|
48
|
-
# remember_me_checkbox.checked?
|
49
|
-
#
|
50
|
-
def checked?
|
51
|
-
@base_object, = find_element(:all)
|
52
|
-
object_not_found_exception(@base_object, 'Checkbox')
|
53
|
-
chk = if @input.nil?
|
54
|
-
@base_object
|
55
|
-
else
|
56
|
-
find_component(@input, 'checkbox')
|
57
|
-
end
|
58
|
-
chk.checked?
|
59
|
-
end
|
60
33
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
34
|
+
# Does checkbox object exists?
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
# @example
|
38
|
+
# remember_me_checkbox.exists?
|
39
|
+
#
|
40
|
+
def exists?
|
41
|
+
obj, = find_object(:all)
|
42
|
+
obj != nil
|
43
|
+
end
|
71
44
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
if @proxy.nil?
|
80
|
-
super
|
81
|
-
else
|
45
|
+
# Is checkbox checked?
|
46
|
+
#
|
47
|
+
# @return [Boolean]
|
48
|
+
# @example
|
49
|
+
# remember_me_checkbox.checked?
|
50
|
+
#
|
51
|
+
def checked?
|
82
52
|
@base_object, = find_element(:all)
|
83
53
|
object_not_found_exception(@base_object, 'Checkbox')
|
84
|
-
|
85
|
-
|
54
|
+
chk = if @input.nil?
|
55
|
+
@base_object
|
56
|
+
else
|
57
|
+
find_component(@input, 'checkbox')
|
58
|
+
end
|
59
|
+
chk.checked?
|
86
60
|
end
|
87
|
-
end
|
88
61
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
else
|
99
|
-
@base_object, = find_element(:all)
|
100
|
-
object_not_found_exception(@base_object, 'Checkbox')
|
101
|
-
chk = find_component(@input, 'checkbox')
|
102
|
-
chk.disabled?
|
62
|
+
# Is checkbox state indeterminate?
|
63
|
+
#
|
64
|
+
# @return [Boolean]
|
65
|
+
# @example
|
66
|
+
# remember_me_checkbox.indeterminate?
|
67
|
+
#
|
68
|
+
def indeterminate?
|
69
|
+
state = get_attribute('indeterminate')
|
70
|
+
state.boolean? ? state : state == 'true'
|
103
71
|
end
|
104
|
-
end
|
105
72
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
if @label.nil?
|
73
|
+
# Is checkbox visible?
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
# @example
|
77
|
+
# remember_me_checkbox.visible?
|
78
|
+
#
|
79
|
+
def visible?
|
114
80
|
if @proxy.nil?
|
115
81
|
super
|
116
82
|
else
|
83
|
+
@base_object, = find_element(:all)
|
84
|
+
object_not_found_exception(@base_object, 'Checkbox')
|
117
85
|
proxy = find_component(@proxy, 'checkbox proxy')
|
118
|
-
proxy.
|
86
|
+
proxy.visible?
|
119
87
|
end
|
120
|
-
else
|
121
|
-
label = find_component(@label, 'checkbox label')
|
122
|
-
label.text
|
123
88
|
end
|
124
|
-
end
|
125
89
|
|
126
|
-
|
127
|
-
|
128
|
-
|
90
|
+
# Is checkbox disabled (not enabled)?
|
91
|
+
#
|
92
|
+
# @return [Boolean]
|
93
|
+
# @example
|
94
|
+
# remember_me_checkbox.disabled?
|
95
|
+
#
|
96
|
+
def disabled?
|
97
|
+
if @input.nil?
|
98
|
+
super
|
99
|
+
else
|
100
|
+
@base_object, = find_element(:all)
|
101
|
+
object_not_found_exception(@base_object, 'Checkbox')
|
102
|
+
chk = find_component(@input, 'checkbox')
|
103
|
+
chk.disabled?
|
104
|
+
end
|
105
|
+
end
|
129
106
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
107
|
+
# Return checkbox caption
|
108
|
+
#
|
109
|
+
# @return [Boolean]
|
110
|
+
# @example
|
111
|
+
# remember_me_checkbox.get_value
|
112
|
+
#
|
113
|
+
def get_value
|
114
|
+
if @label.nil?
|
115
|
+
if @proxy.nil?
|
116
|
+
super
|
117
|
+
else
|
118
|
+
proxy = find_component(@proxy, 'checkbox proxy')
|
119
|
+
proxy.text
|
120
|
+
end
|
144
121
|
else
|
145
|
-
|
122
|
+
label = find_component(@label, 'checkbox label')
|
123
|
+
label.text
|
146
124
|
end
|
147
|
-
|
148
|
-
|
149
|
-
|
125
|
+
end
|
126
|
+
|
127
|
+
alias get_caption get_value
|
128
|
+
alias caption get_value
|
129
|
+
alias value get_value
|
130
|
+
|
131
|
+
# Set the check state of a checkbox object.
|
132
|
+
#
|
133
|
+
# @param state [Boolean] true = checked / false = unchecked
|
134
|
+
# @example
|
135
|
+
# remember_me_checkbox.set_checkbox_state(true)
|
136
|
+
#
|
137
|
+
def set_checkbox_state(state)
|
138
|
+
@base_object, = find_element(:all)
|
139
|
+
object_not_found_exception(@base_object, 'Checkbox')
|
140
|
+
proxy = find_component(@proxy, 'checkbox proxy') unless @proxy.nil?
|
141
|
+
chk = find_component(@input, 'checkbox') unless @input.nil?
|
142
|
+
if @input.nil?
|
143
|
+
if @proxy.nil?
|
144
|
+
@base_object.click unless state == @base_object.checked?
|
145
|
+
else
|
146
|
+
proxy.click unless state == @base_object.checked?
|
147
|
+
end
|
150
148
|
else
|
151
|
-
proxy.
|
149
|
+
if @proxy.nil?
|
150
|
+
@base_object.click unless state == chk.checked?
|
151
|
+
else
|
152
|
+
proxy.click unless state == chk.checked?
|
153
|
+
end
|
152
154
|
end
|
153
155
|
end
|
154
|
-
end
|
155
156
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
157
|
+
# Set the check state of a checkbox object.
|
158
|
+
#
|
159
|
+
# @example
|
160
|
+
# remember_me_checkbox.check
|
161
|
+
#
|
162
|
+
def check
|
163
|
+
set_checkbox_state(true)
|
164
|
+
end
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
166
|
+
# Uncheck a checkbox object.
|
167
|
+
#
|
168
|
+
# @example
|
169
|
+
# remember_me_checkbox.uncheck
|
170
|
+
#
|
171
|
+
def uncheck
|
172
|
+
set_checkbox_state(state = false)
|
173
|
+
end
|
173
174
|
|
174
|
-
|
175
|
-
|
176
|
-
|
175
|
+
def verify_check_state(state, enqueue = false)
|
176
|
+
actual = checked?
|
177
|
+
enqueue ?
|
177
178
|
ExceptionQueue.enqueue_assert_equal(state, actual, "Expected checkbox #{object_ref_message}") :
|
178
179
|
assert_equal(state, actual, "Expected checkbox #{object_ref_message} to be #{state} but found #{actual} instead")
|
180
|
+
end
|
179
181
|
end
|
180
182
|
end
|
181
183
|
end
|
@@ -1,49 +1,51 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Elements
|
3
|
+
class FileField < UIElement
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :filefield
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def file_upload(file_path)
|
10
|
+
obj, = find_element(visible = false)
|
11
|
+
obj.send_keys(file_path)
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
+
# :nocov:
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def file_attach(file_path)
|
17
|
+
Capybara.ignore_hidden_elements = false
|
18
|
+
page.attach_file(@locator, file_path)
|
19
|
+
Capybara.ignore_hidden_elements = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def drop_files(files)
|
23
|
+
js_script = 'fileList = Array();'
|
24
|
+
files.count.times do |i|
|
25
|
+
# generate a fake input selector
|
26
|
+
page.execute_script("if ($('#seleniumUpload#{i}').length == 0) { seleniumUpload#{i} = window.$('<input/>').attr({id: 'seleniumUpload#{i}', type:'file'}).appendTo('body'); }")
|
27
|
+
# attach file to the fake input selector through Capybara
|
28
|
+
attach_file("seleniumUpload#{i}", files[i])
|
29
|
+
# create the fake js event
|
30
|
+
js_script = "#{js_script} fileList.push(seleniumUpload#{i}.get(0).files[0]);"
|
31
|
+
end
|
32
|
+
# trigger the fake drop event
|
33
|
+
page.execute_script("#{js_script} e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : fileList } }; $('#{@locator}').trigger(e);")
|
34
|
+
end
|
20
35
|
|
21
|
-
|
22
|
-
js_script = 'fileList = Array();'
|
23
|
-
files.count.times do |i|
|
36
|
+
def ng_drop_file(file_path)
|
24
37
|
# generate a fake input selector
|
25
|
-
page.execute_script("
|
38
|
+
page.execute_script("fakeFileInput = window.$('<input/>').attr({ id: 'fileFileInput', type: 'file' }).appendTo('body');")
|
26
39
|
# attach file to the fake input selector through Capybara
|
27
|
-
attach_file(
|
40
|
+
page.attach_file('fakeFileInput', file_path)
|
28
41
|
# create the fake js event
|
29
|
-
js_script = "
|
42
|
+
js_script = "var scope = angular.element('#{@locator}').scope();"
|
43
|
+
js_script = "#{js_script} scope.files = [fakeFileInput.get(0).files[0]];"
|
44
|
+
# trigger the fake drop event
|
45
|
+
page.execute_script(js_script)
|
30
46
|
end
|
31
|
-
# trigger the fake drop event
|
32
|
-
page.execute_script("#{js_script} e = $.Event('drop'); e.originalEvent = {dataTransfer : { files : fileList } }; $('#{@locator}').trigger(e);")
|
33
|
-
end
|
34
47
|
|
35
|
-
|
36
|
-
# generate a fake input selector
|
37
|
-
page.execute_script("fakeFileInput = window.$('<input/>').attr({ id: 'fileFileInput', type: 'file' }).appendTo('body');")
|
38
|
-
# attach file to the fake input selector through Capybara
|
39
|
-
page.attach_file('fakeFileInput', file_path)
|
40
|
-
# create the fake js event
|
41
|
-
js_script = "var scope = angular.element('#{@locator}').scope();"
|
42
|
-
js_script = "#{js_script} scope.files = [fakeFileInput.get(0).files[0]];"
|
43
|
-
# trigger the fake drop event
|
44
|
-
page.execute_script(js_script)
|
48
|
+
# :nocov:
|
45
49
|
end
|
46
|
-
|
47
|
-
# :nocov:
|
48
50
|
end
|
49
51
|
end
|
@@ -1,81 +1,86 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Elements
|
3
|
+
class Image < UIElement
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :image
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
9
|
+
# Is image loaded?
|
10
|
+
#
|
11
|
+
# @return [Boolean]
|
12
|
+
# @example
|
13
|
+
# company_logo_image.is_loaded?
|
14
|
+
#
|
15
|
+
def loaded?
|
16
|
+
obj, = find_element
|
17
|
+
object_not_found_exception(obj, nil)
|
18
|
+
state = obj.native.attribute('complete')
|
19
|
+
state.boolean? ? state : state == 'true'
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
+
alias is_loaded? loaded?
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
24
|
+
# Is image broken?
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
# @example
|
28
|
+
# company_logo_image.broken?
|
29
|
+
#
|
30
|
+
def broken?
|
31
|
+
obj, = find_element
|
32
|
+
object_not_found_exception(obj, nil)
|
33
|
+
result = page.execute_script(
|
34
|
+
'return arguments[0].complete && typeof arguments[0].naturalWidth != "undefined" && arguments[0].naturalWidth > 0',
|
35
|
+
obj
|
36
|
+
)
|
37
|
+
!result
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
40
|
+
# Wait until the image is fully loaded, or until the specified wait time has expired.
|
41
|
+
#
|
42
|
+
# @param seconds [Integer or Float] wait time in seconds
|
43
|
+
# @example
|
44
|
+
# company_logo_image.wait_until_loaded(5)
|
45
|
+
#
|
46
|
+
def wait_until_loaded(seconds = nil, post_exception = true)
|
47
|
+
timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
|
48
|
+
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
49
|
+
wait.until do
|
50
|
+
reset_mru_cache
|
51
|
+
is_loaded?
|
52
|
+
end
|
53
|
+
rescue
|
54
|
+
if post_exception
|
55
|
+
raise "Image #{object_ref_message} failed to load within #{timeout} seconds" unless loaded?
|
56
|
+
else
|
57
|
+
loaded?
|
58
|
+
end
|
54
59
|
end
|
55
|
-
end
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
# Return image alt property
|
62
|
+
#
|
63
|
+
# @return [String] value of alt property
|
64
|
+
# @example
|
65
|
+
# alt_value = company_logo_image.alt
|
66
|
+
#
|
67
|
+
def alt
|
68
|
+
obj, = find_element
|
69
|
+
object_not_found_exception(obj, nil)
|
70
|
+
obj.native.attribute('alt')
|
71
|
+
end
|
68
72
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
73
|
+
# Return image src property
|
74
|
+
#
|
75
|
+
# @return [String] value of src property
|
76
|
+
# @example
|
77
|
+
# src_value = company_logo_image.src
|
78
|
+
#
|
79
|
+
def src
|
80
|
+
obj, = find_element
|
81
|
+
object_not_found_exception(obj, nil)
|
82
|
+
obj.native.attribute('src')
|
83
|
+
end
|
79
84
|
end
|
80
85
|
end
|
81
86
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Elements
|
3
|
+
class Label < UIElement
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :label
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
8
10
|
end
|
@@ -1,18 +1,20 @@
|
|
1
1
|
module TestCentricity
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Elements
|
3
|
+
class Link < UIElement
|
4
|
+
def initialize(name, parent, locator, context)
|
5
|
+
super
|
6
|
+
@type = :link
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
# Return link object's href property
|
10
|
+
#
|
11
|
+
# @return [String]
|
12
|
+
# @example
|
13
|
+
# contact_us_link.href
|
14
|
+
#
|
15
|
+
def href
|
16
|
+
get_attribute('href')
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|