testcentricity_apps 4.0.10

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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +193 -0
  4. data/LICENSE.md +27 -0
  5. data/README.md +2297 -0
  6. data/lib/testcentricity_apps/app_core/appium_connect_helper.rb +667 -0
  7. data/lib/testcentricity_apps/app_core/screen_object.rb +494 -0
  8. data/lib/testcentricity_apps/app_core/screen_objects_helper.rb +211 -0
  9. data/lib/testcentricity_apps/app_core/screen_section.rb +669 -0
  10. data/lib/testcentricity_apps/app_elements/alert.rb +152 -0
  11. data/lib/testcentricity_apps/app_elements/app_element.rb +728 -0
  12. data/lib/testcentricity_apps/app_elements/button.rb +10 -0
  13. data/lib/testcentricity_apps/app_elements/checkbox.rb +61 -0
  14. data/lib/testcentricity_apps/app_elements/image.rb +10 -0
  15. data/lib/testcentricity_apps/app_elements/label.rb +10 -0
  16. data/lib/testcentricity_apps/app_elements/list.rb +188 -0
  17. data/lib/testcentricity_apps/app_elements/menu.rb +159 -0
  18. data/lib/testcentricity_apps/app_elements/menubar.rb +78 -0
  19. data/lib/testcentricity_apps/app_elements/radio.rb +61 -0
  20. data/lib/testcentricity_apps/app_elements/selectlist.rb +126 -0
  21. data/lib/testcentricity_apps/app_elements/switch.rb +66 -0
  22. data/lib/testcentricity_apps/app_elements/textfield.rb +51 -0
  23. data/lib/testcentricity_apps/appium_server.rb +76 -0
  24. data/lib/testcentricity_apps/data_objects/data_objects_helper.rb +100 -0
  25. data/lib/testcentricity_apps/data_objects/environment.rb +423 -0
  26. data/lib/testcentricity_apps/exception_queue_helper.rb +160 -0
  27. data/lib/testcentricity_apps/utility_helpers.rb +48 -0
  28. data/lib/testcentricity_apps/version.rb +3 -0
  29. data/lib/testcentricity_apps/world_extensions.rb +61 -0
  30. data/lib/testcentricity_apps.rb +103 -0
  31. metadata +322 -0
@@ -0,0 +1,669 @@
1
+ require 'test/unit'
2
+
3
+ module TestCentricity
4
+ class ScreenSection < BaseScreenSectionObject
5
+ include Test::Unit::Assertions
6
+
7
+ attr_reader :context, :name
8
+ attr_accessor :locator
9
+ attr_accessor :parent
10
+ attr_accessor :parent_list
11
+ attr_accessor :list_index
12
+
13
+ def initialize(name, parent, locator, context)
14
+ @name = name
15
+ @parent = parent
16
+ @locator = locator
17
+ @context = context
18
+ @parent_list = nil
19
+ @list_index = nil
20
+ end
21
+
22
+ def get_locator
23
+ my_locator = if @locator.zero? && defined?(section_locator)
24
+ section_locator
25
+ else
26
+ @locator
27
+ end
28
+ locators = []
29
+ if @context == :section && !@parent.nil?
30
+ locators = @parent.get_locator
31
+ end
32
+
33
+ if @parent_list.nil?
34
+ locators.push(my_locator)
35
+ else
36
+ locators.push(@parent_list.get_locator)
37
+ if @list_index.nil?
38
+ locators.push(my_locator)
39
+ else
40
+ item_objects = @parent_list.item_refs
41
+ if item_objects.nil?
42
+ list_key = my_locator.keys[0]
43
+ list_value = "#{my_locator.values[0]}[#{@list_index}]"
44
+ else
45
+ list_key = :object
46
+ list_value = item_objects[@list_index - 1]
47
+ end
48
+ locators.push( { list_key => list_value } )
49
+ end
50
+ end
51
+ locators
52
+ end
53
+
54
+ def set_list_index(list, index = 1)
55
+ @parent_list = list unless list.nil?
56
+ @list_index = index
57
+ end
58
+
59
+ def get_item_count
60
+ raise 'No parent list defined' if @parent_list.nil?
61
+ @parent_list.get_item_count
62
+ end
63
+
64
+ def get_list_items
65
+ items = []
66
+ (1..get_item_count).each do |item|
67
+ set_list_index(nil, item)
68
+ begin
69
+ items.push(get_value)
70
+ rescue
71
+ scroll_into_view(@parent_list.scroll_mode)
72
+ items.push(get_value)
73
+ end
74
+ end
75
+ items
76
+ end
77
+
78
+ def get_object_type
79
+ :section
80
+ end
81
+
82
+ def get_name
83
+ @name
84
+ end
85
+
86
+ def set_parent(parent)
87
+ @parent = parent
88
+ end
89
+
90
+ # Declare and instantiate a single generic UI Element for this screen section object.
91
+ #
92
+ # @param element_name [Symbol] name of UI object (as a symbol)
93
+ # @param locator [Hash] { locator_strategy: locator_identifier }
94
+ # The locator_strategy (a Symbol) specifies the selector strategy that Appium will use to find the UI element. Valid
95
+ # selectors are accessibility_id:, id:, name:, class:, xpath:, predicate: (iOS only), class_chain: (iOS only), and
96
+ # css: (WebViews in hybrid apps only).
97
+ # * The locator_identifier (a String) is the value or attribute that uniquely and unambiguously identifies the UI element.
98
+ #
99
+ # @example
100
+ # element :video_player, { accessibility_id: 'YouTube Video Player' }
101
+ #
102
+ def self.element(element_name, locator)
103
+ define_section_element(element_name, TestCentricity::AppElements::AppUIElement, locator)
104
+ end
105
+
106
+ # Declare and instantiate a collection of generic UI Elements for this screen section object.
107
+ #
108
+ # @param element_hash [Hash] names of UI objects (as a Symbol) and locator Hash
109
+ # @example
110
+ # elements drop_down_field: { accessibility_id: 'drop_trigger' },
111
+ # settings_item: { accessibility_id: 'settings' },
112
+ # log_out_item: { accessibility_id: 'logout' }
113
+ #
114
+ def self.elements(element_hash)
115
+ element_hash.each_pair { |element_name, locator| element(element_name, locator) }
116
+ end
117
+
118
+ # Declare and instantiate a single button UI Element for this screen section object.
119
+ #
120
+ # @param element_name [Symbol] name of button object (as a symbol)
121
+ # @param locator [Hash] { locator_strategy: locator_identifier }
122
+ # @example
123
+ # button :video_play, { accessibility_id: 'video icon play' }
124
+ #
125
+ def self.button(element_name, locator)
126
+ define_section_element(element_name, TestCentricity::AppElements::AppButton, locator)
127
+ end
128
+
129
+ # Declare and instantiate a collection of buttons for this screen section object.
130
+ #
131
+ # @param element_hash [Hash] names of buttons (as symbol) and locator Hash
132
+ # @example
133
+ # buttons video_back: { accessibility_id: 'video icon backward' },
134
+ # video_play: { accessibility_id: 'video icon play' },
135
+ # video_pause: { accessibility_id: 'video icon stop' },
136
+ # video_forward: { accessibility_id: 'video icon forward' }
137
+ #
138
+ def self.buttons(element_hash)
139
+ element_hash.each_pair { |element_name, locator| button(element_name, locator) }
140
+ end
141
+
142
+ # Declare and instantiate a single textfield UI Element for this screen section object.
143
+ #
144
+ # @param element_name [Symbol] name of textfield object (as a symbol)
145
+ # @param locator [Hash] { locator_strategy: locator_identifier }
146
+ # @example
147
+ # textfield :payee_name_field, { xpath: '//android.widget.EditText[@content-desc="Full Name* input field"]' }
148
+ # textfield :payee_name_field, { xpath: '//XCUIElementTypeTextField[@name="Full Name* input field"]' }
149
+ #
150
+ def self.textfield(element_name, locator)
151
+ define_section_element(element_name, TestCentricity::AppElements::AppTextField, locator)
152
+ end
153
+
154
+ # Declare and instantiate a collection of textfields for this screen section object.
155
+ #
156
+ # @param element_hash [Hash] names of textfields (as symbol) and locator Hash
157
+ # @example
158
+ # textfields username_field: { accessibility_id: 'Username input field' },
159
+ # password_field: { accessibility_id: 'Password input field' }
160
+ #
161
+ def self.textfields(element_hash)
162
+ element_hash.each_pair { |element_name, locator| textfield(element_name, locator) }
163
+ end
164
+
165
+ # Declare and instantiate a single switch UI Element for this screen section object.
166
+ #
167
+ # @param element_name [Symbol] name of switch object (as a symbol)
168
+ # @param locator [Hash] { locator_strategy: locator_identifier }
169
+ # @example
170
+ # switch :debug_mode_switch, { accessibility_id: 'debug mode' }
171
+ #
172
+ def self.switch(element_name, locator)
173
+ define_section_element(element_name, TestCentricity::AppElements::AppSwitch, locator)
174
+ end
175
+
176
+ # Declare and instantiate a collection of switches for this screen section object.
177
+ #
178
+ # @param element_hash [Hash] names of switches (as symbol) and locator Hash
179
+ # @example
180
+ # switches debug_mode_switch: { accessibility_id: 'debug mode' },
181
+ # metrics_switch: { accessibility_id: 'metrics' }
182
+ #
183
+ def self.switches(element_hash)
184
+ element_hash.each_pair { |element_name, locator| switch(element_name, locator) }
185
+ end
186
+
187
+ # Declare and instantiate a single checkbox UI Element for this screen section object.
188
+ #
189
+ # @param element_name [Symbol] name of checkbox object (as a symbol)
190
+ # @param locator [Hash] { locator_strategy: locator_identifier }
191
+ # @example
192
+ # checkbox :bill_address_check, { xpath: '//XCUIElementTypeOther[contains(@name, "billing checkbox")]'}
193
+ #
194
+ def self.checkbox(element_name, locator)
195
+ define_section_element(element_name, TestCentricity::AppElements::AppCheckBox, locator)
196
+ end
197
+
198
+ # Declare and instantiate a collection of checkboxes for this screen section object.
199
+ #
200
+ # @param element_hash [Hash] names of checkboxes (as symbol) and locator Hash
201
+ # @example
202
+ # checkboxes bill_address_check: { xpath: '//XCUIElementTypeOther[contains(@name, "billing checkbox")]'},
203
+ # is_gift_check: { accessibility_id: 'is a gift' }
204
+ #
205
+ def self.checkboxes(element_hash)
206
+ element_hash.each_pair { |element_name, locator| checkbox(element_name, locator) }
207
+ end
208
+
209
+ # Declare and instantiate a single radio button UI Element for this screen section object.
210
+ #
211
+ # @param element_name [Symbol] name of radio button object (as a symbol)
212
+ # @param locator [Hash] { locator_strategy: locator_identifier }
213
+ # @example
214
+ # radio :unicode_radio, { xpath: '//XCUIElementTypeRadioButton[@label="Unicode"]'}
215
+ #
216
+ def self.radio(element_name, locator)
217
+ define_section_element(element_name, TestCentricity::AppElements::AppRadio, locator)
218
+ end
219
+
220
+ # Declare and instantiate a collection of radio buttons for this screen section object.
221
+ #
222
+ # @param element_hash [Hash] names of radio buttons (as symbol) and locator Hash
223
+ # @example
224
+ # radios unicode_radio: { xpath: '//XCUIElementTypeRadioButton[@label="Unicode"]'},
225
+ # ascii_radio: { xpath: '//XCUIElementTypeRadioButton[@label="ASCII"] }
226
+ #
227
+ def self.radios(element_hash)
228
+ element_hash.each_pair { |element_name, locator| radio(element_name, locator) }
229
+ end
230
+
231
+ # Declare and instantiate a single label UI Element for this screen section object.
232
+ #
233
+ # @param element_name [Symbol] name of label object (as a symbol)
234
+ # @param locator [Hash] { locator_strategy: locator_identifier }
235
+ # @example
236
+ # label :header_label, { accessibility_id: 'container header' }
237
+ #
238
+ def self.label(element_name, locator)
239
+ define_section_element(element_name, TestCentricity::AppElements::AppLabel, locator)
240
+ end
241
+
242
+ # Declare and instantiate a collection of labels for this screen section object.
243
+ #
244
+ # @param element_hash [Hash] names of labels (as symbol) and locator Hash
245
+ # @example
246
+ # labels total_qty_value: { accessibility_id: 'total number' },
247
+ # total_price_value: { accessibility_id: 'total price' }
248
+ #
249
+ def self.labels(element_hash)
250
+ element_hash.each_pair { |element_name, locator| label(element_name, locator) }
251
+ end
252
+
253
+ # Declare and instantiate a single list UI Element for this screen section object.
254
+ #
255
+ # @param element_name [Symbol] name of list object (as a symbol)
256
+ # @param locator [Hash] { locator_strategy: locator_identifier }
257
+ # @example
258
+ # list :carousel_list, { accessibility_id: 'Carousel' }
259
+ #
260
+ def self.list(element_name, locator)
261
+ define_section_element(element_name, TestCentricity::AppElements::AppList, locator)
262
+ end
263
+
264
+ # Declare and instantiate a collection of lists for this screen section object.
265
+ #
266
+ # @param element_hash [Hash] names of lists (as symbol) and locator Hash
267
+ # @example
268
+ # lists product_grid: { xpath: '//android.widget.ScrollView/android.view.ViewGroup' },
269
+ # cart_list: { xpath: '//android.widget.ScrollView[@content-desc="cart screen"]' }
270
+ #
271
+ def self.lists(element_hash)
272
+ element_hash.each_pair { |element_name, locator| list(element_name, locator) }
273
+ end
274
+
275
+ # Declare and instantiate a single selectlist UI Element for this screen section object.
276
+ #
277
+ # @param element_name [Symbol] name of selectlist object (as a symbol)
278
+ # @param locator [Hash] { locator_strategy: locator_identifier }
279
+ # @example
280
+ # selectlist :convert_list, { xpath: '//XCUIElementTypePopUpButton[@label="convert"]' }
281
+ #
282
+ def self.selectlist(element_name, locator)
283
+ define_section_element(element_name, TestCentricity::AppElements::AppSelectList, locator)
284
+ end
285
+
286
+ # Declare and instantiate a collection of selectlists for this screen section object.
287
+ #
288
+ # @param element_hash [Hash] names of selectlists (as symbol) and locator Hash
289
+ # @example
290
+ # selectlists convert_list: { xpath: '//XCUIElementTypePopUpButton[@label="convert"]' },
291
+ # from_list: { xpath: '//XCUIElementTypePopUpButton[@label="convert_from"]' }
292
+ #
293
+ def self.selectlists(element_hash)
294
+ element_hash.each_pair { |element_name, locator| selectlist(element_name, locator) }
295
+ end
296
+
297
+ # Declare and instantiate a single image UI Element for this screen section object.
298
+ #
299
+ # @param element_name [Symbol] name of image object (as a symbol)
300
+ # @param locator [Hash] { locator_strategy: locator_identifier }
301
+ # @example
302
+ # image :product_image, { xpath: '//XCUIElementTypeImage' }
303
+ #
304
+ def self.image(element_name, locator)
305
+ define_section_element(element_name, TestCentricity::AppElements::AppImage, locator)
306
+ end
307
+
308
+ # Declare and instantiate a collection of images for this screen section object.
309
+ #
310
+ # @param element_hash [Hash] names of images (as symbol) and locator Hash
311
+ # @example
312
+ # images empty_cart_image: { accessibility_id: 'empty_cart' },
313
+ # logo_image: { accessibility_id: 'WebdriverIO logo' }
314
+ #
315
+ def self.images(element_hash)
316
+ element_hash.each_pair { |element_name, locator| image(element_name, locator) }
317
+ end
318
+
319
+ # Instantiate a single ScreenSection object within this ScreenSection object.
320
+ #
321
+ # @param section_name [Symbol] name of ScreenSection object (as a symbol)
322
+ # @param class_name [Class] Class name of ScreenSection object
323
+ # @example
324
+ # section :nav_menu, NavMenu
325
+ #
326
+ def self.section(section_name, obj, locator = 0)
327
+ define_section_element(section_name, obj, locator)
328
+ end
329
+
330
+ # Declare and instantiate a collection of ScreenSection objects for this ScreenSection object.
331
+ #
332
+ # @param element_hash [Hash] names of ScreenSections (as symbol) and class name
333
+ # @example
334
+ # sections product_grid_item: ProductGridItem,
335
+ # sort_by_menu: SortByMenu
336
+ #
337
+ def self.sections(section_hash)
338
+ section_hash.each_pair { |section_name, class_name| section(section_name, class_name) }
339
+ end
340
+
341
+ # Click on a screen Section object
342
+ #
343
+ # @example
344
+ # bar_chart_section.click
345
+ #
346
+ def click
347
+ section = find_section
348
+ section_not_found_exception(section)
349
+ section.click
350
+ end
351
+
352
+ # Tap on a screen Section object
353
+ #
354
+ # @example
355
+ # bar_chart_section.tap
356
+ #
357
+ def tap
358
+ section = find_section
359
+ section_not_found_exception(section)
360
+ driver.action
361
+ .click_and_hold(section)
362
+ .release
363
+ .perform
364
+ end
365
+
366
+ # Double-tap on a screen Section object
367
+ #
368
+ # @example
369
+ # bar_chart_section.double_tap
370
+ #
371
+ def double_tap
372
+ section = find_section
373
+ section_not_found_exception(section)
374
+ driver.action
375
+ .click_and_hold(section)
376
+ .release
377
+ .pause(duration: 0.2)
378
+ .click_and_hold(section)
379
+ .release
380
+ .perform
381
+ end
382
+
383
+ # Long press on a screen Section object
384
+ #
385
+ # @param duration [Float] duration of long press in seconds
386
+ # @example
387
+ # header_image.long_press(1.5)
388
+ #
389
+ def long_press(duration = 1)
390
+ section = find_section
391
+ section_not_found_exception(section)
392
+ driver.action
393
+ .click_and_hold(section)
394
+ .pause(duration: duration)
395
+ .release
396
+ .perform
397
+ end
398
+
399
+ # Scroll the screen Section object until it is visible. If scroll_mode is not specified, then vertical scrolling will
400
+ # be used.
401
+ #
402
+ # @param scroll_mode [Symbol] :vertical (default) or :horizontal
403
+ # @example
404
+ # carousel_item.scroll_into_view(scroll_mode = :horizontal)
405
+ #
406
+ def scroll_into_view(scroll_mode = :vertical)
407
+ return if visible?
408
+ obj = element
409
+ object_not_found_exception(obj)
410
+ driver.action.move_to(obj).perform
411
+ case scroll_mode
412
+ when :vertical
413
+ start_direction = :down
414
+ end_direction = :up
415
+ when :horizontal
416
+ start_direction = :right
417
+ end_direction = :left
418
+ else
419
+ raise "#{scroll_mode} is not a valid selector"
420
+ end
421
+ try_count = 8
422
+ direction = start_direction
423
+ while hidden?
424
+ swipe_gesture(direction, distance = 0.2)
425
+ try_count -= 1
426
+ if try_count.zero?
427
+ if direction == end_direction
428
+ break
429
+ else
430
+ direction = end_direction
431
+ try_count = 8
432
+ end
433
+ end
434
+ end
435
+ end
436
+
437
+ # Does screen Section object exists?
438
+ #
439
+ # @return [Boolean]
440
+ # @example
441
+ # navigation_toolbar.exists?
442
+ #
443
+ def exists?
444
+ section = find_section
445
+ section != nil
446
+ end
447
+
448
+ # Is screen Section object enabled?
449
+ #
450
+ # @return [Boolean]
451
+ # @example
452
+ # bar_chart_section.enabled?
453
+ #
454
+ def enabled?
455
+ section = find_section
456
+ section_not_found_exception(section)
457
+ section.enabled?
458
+ end
459
+
460
+ # Is screen Section object disabled (not enabled)?
461
+ #
462
+ # @return [Boolean]
463
+ # @example
464
+ # bar_chart_section.disabled?
465
+ #
466
+ def disabled?
467
+ !enabled?
468
+ end
469
+
470
+ # Is screen Section object visible?
471
+ #
472
+ # @return [Boolean]
473
+ # @example
474
+ # navigation_toolbar.visible?
475
+ #
476
+ def visible?
477
+ section = find_section
478
+ return false if section.nil?
479
+ section.displayed?
480
+ end
481
+
482
+ # Is screen Section object hidden (not visible)?
483
+ #
484
+ # @return [Boolean]
485
+ # @example
486
+ # navigation_toolbar.hidden?
487
+ #
488
+ def hidden?
489
+ !visible?
490
+ end
491
+
492
+ def identifier
493
+ if Environ.is_macos?
494
+ section = find_section
495
+ section_not_found_exception(section)
496
+ section.identifier
497
+ else
498
+ raise 'identifier is not a supported attribute'
499
+ end
500
+ end
501
+
502
+ # Send keystrokes to this section object.
503
+ #
504
+ # @param value [String] keys
505
+ # @example
506
+ # basic_view.send_keys('Lime green')
507
+ #
508
+ def send_keys(value)
509
+ section = find_section
510
+ section_not_found_exception(section)
511
+ section.send_keys(value)
512
+ end
513
+
514
+ # Wait until the screen Section object exists, or until the specified wait time has expired. If the wait time is nil,
515
+ # then the wait time will be Environ.default_max_wait_time.
516
+ #
517
+ # @param seconds [Integer or Float] wait time in seconds
518
+ # @example
519
+ # navigation_toolbar.wait_until_exists(1.5)
520
+ #
521
+ def wait_until_exists(seconds = nil, post_exception = true)
522
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
523
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
524
+ wait.until { exists? }
525
+ rescue
526
+ if post_exception
527
+ raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless exists?
528
+ else
529
+ exists?
530
+ end
531
+ end
532
+
533
+ # Wait until the screen Section object no longer exists, or until the specified wait time has expired. If the wait
534
+ # time is nil, then the wait time will be Environ.default_max_wait_time.
535
+ #
536
+ # @param seconds [Integer or Float] wait time in seconds
537
+ # @example
538
+ # navigation_toolbar.wait_until_gone(5)
539
+ #
540
+ def wait_until_gone(seconds = nil, post_exception = true)
541
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
542
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
543
+ wait.until { !exists? }
544
+ rescue
545
+ if post_exception
546
+ raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if exists?
547
+ else
548
+ exists?
549
+ end
550
+ end
551
+
552
+ # Wait until the screen Section object is visible, or until the specified wait time has expired. If the wait time is nil,
553
+ # then the wait time will be Environ.default_max_wait_time.
554
+ #
555
+ # @param seconds [Integer or Float] wait time in seconds
556
+ # @example
557
+ # navigation_toolbar.wait_until_visible(1.5)
558
+ #
559
+ def wait_until_visible(seconds = nil, post_exception = true)
560
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
561
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
562
+ wait.until { visible? }
563
+ rescue
564
+ if post_exception
565
+ raise "Could not find Section object '#{get_name}' (#{get_locator}) after #{timeout} seconds" unless visible?
566
+ else
567
+ visible?
568
+ end
569
+ end
570
+
571
+ # Wait until the screen Section object is hidden, or until the specified wait time has expired. If the wait time is nil,
572
+ # then the wait time will be Environ.default_max_wait_time.
573
+ #
574
+ # @param seconds [Integer or Float] wait time in seconds
575
+ # @example
576
+ # navigation_toolbar.wait_until_hidden(2)
577
+ #
578
+ def wait_until_hidden(seconds = nil, post_exception = true)
579
+ timeout = seconds.nil? ? Environ.default_max_wait_time : seconds
580
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
581
+ wait.until { hidden? }
582
+ rescue
583
+ if post_exception
584
+ raise "Section object '#{get_name}' (#{get_locator}) remained visible after #{timeout} seconds" if visible?
585
+ else
586
+ visible?
587
+ end
588
+ end
589
+
590
+ # Return width of screen Section object.
591
+ #
592
+ # @return [Integer]
593
+ # @example
594
+ # button_width = my_button.width
595
+ #
596
+ def width
597
+ section = find_section
598
+ section_not_found_exception(section)
599
+ section.size.width
600
+ end
601
+
602
+ # Return height of screen Section object.
603
+ #
604
+ # @return [Integer]
605
+ # @example
606
+ # button_height = my_button.height
607
+ #
608
+ def height
609
+ section = find_section
610
+ section_not_found_exception(section)
611
+ section.size.height
612
+ end
613
+
614
+ # Return x coordinate of screen Section object's location.
615
+ #
616
+ # @return [Integer]
617
+ # @example
618
+ # button_x = my_button.x_loc
619
+ #
620
+ def x_loc
621
+ section = find_section
622
+ section_not_found_exception(section)
623
+ section.location.x
624
+ end
625
+
626
+ # Return y coordinate of screen Section object's location.
627
+ #
628
+ # @return [Integer]
629
+ # @example
630
+ # button_x = my_button.x_loc
631
+ #
632
+ def y_loc
633
+ section = find_section
634
+ section_not_found_exception(section)
635
+ section.location.y
636
+ end
637
+
638
+ private
639
+
640
+ def find_section
641
+ obj = nil
642
+ locators = get_locator
643
+ locators.each do |loc|
644
+ if obj.nil?
645
+ obj = find_element(loc.keys[0], loc.values[0])
646
+ else
647
+ obj = obj.find_element(loc.keys[0], loc.values[0])
648
+ end
649
+ puts "Found section object #{loc}" if ENV['DEBUG']
650
+ end
651
+ obj
652
+ rescue
653
+ nil
654
+ end
655
+
656
+ def section_not_found_exception(obj)
657
+ raise ObjectNotFoundError.new("Section object '#{get_name}' - (#{get_locator}) not found") unless obj
658
+ end
659
+
660
+ def self.define_section_element(element_name, obj, locator)
661
+ define_method(element_name) do
662
+ ivar_name = "@#{element_name}"
663
+ ivar = instance_variable_get(ivar_name)
664
+ return ivar if ivar
665
+ instance_variable_set(ivar_name, obj.new(element_name, self, locator, :section))
666
+ end
667
+ end
668
+ end
669
+ end