rubium-ios 1.0.0.pre
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 +7 -0
- data/lib/rubium.rb +21 -0
- data/lib/rubium/capabilities.rb +92 -0
- data/lib/rubium/driver.rb +233 -0
- data/lib/rubium/session.rb +26 -0
- data/lib/rubium/version.rb +16 -0
- data/lib/ui_automation.rb +325 -0
- data/lib/ui_automation/action_sheet.rb +9 -0
- data/lib/ui_automation/activity_view.rb +9 -0
- data/lib/ui_automation/alert.rb +16 -0
- data/lib/ui_automation/application.rb +57 -0
- data/lib/ui_automation/element.rb +255 -0
- data/lib/ui_automation/element_array.rb +226 -0
- data/lib/ui_automation/element_definitions.rb +51 -0
- data/lib/ui_automation/element_proxy_methods.rb +43 -0
- data/lib/ui_automation/keyboard.rb +40 -0
- data/lib/ui_automation/logger.rb +43 -0
- data/lib/ui_automation/navigation_bar.rb +17 -0
- data/lib/ui_automation/picker.rb +14 -0
- data/lib/ui_automation/popover.rb +23 -0
- data/lib/ui_automation/tab_bar.rb +31 -0
- data/lib/ui_automation/table_view.rb +35 -0
- data/lib/ui_automation/target.rb +42 -0
- data/lib/ui_automation/text_field.rb +9 -0
- data/lib/ui_automation/text_view.rb +9 -0
- data/lib/ui_automation/traits/cancellable.rb +12 -0
- data/lib/ui_automation/traits/text_input.rb +58 -0
- data/lib/ui_automation/window.rb +30 -0
- metadata +128 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
3
|
+
module UIAutomation
|
4
|
+
module ElementDefinitions
|
5
|
+
# Defines a method on an returns an element proxy.
|
6
|
+
#
|
7
|
+
# By default, the Javascript method name is underscored (e.g. textField => text_field)
|
8
|
+
# and the element returned is generic (UIAutomation::Element).
|
9
|
+
#
|
10
|
+
# @example Define a method 'text_field' that returns a proxy to <self>.textField()
|
11
|
+
# has_element :textField
|
12
|
+
#
|
13
|
+
# @param [Hash] opts options for defining the method
|
14
|
+
# @option opts [Symbol] :as Use a custom Ruby method name
|
15
|
+
# @option opts [Class] :type Return a specific UIAutomation::Element sub-class
|
16
|
+
# @api private
|
17
|
+
def has_element(js_method_name, opts={})
|
18
|
+
define_element_using(:element_proxy_for, js_method_name, opts)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Defines a method that returns an element array proxy.
|
22
|
+
#
|
23
|
+
# By default, the Javascript method name is underscored (e.g. textFields => text_fields)
|
24
|
+
# and the element array contains generic elements (UIAutomation::Element).
|
25
|
+
#
|
26
|
+
# @example Define a method 'text_fields' that returns a proxy to <self>.textFields()
|
27
|
+
# has_element :textFields
|
28
|
+
#
|
29
|
+
# @param [Hash] opts options for defining the method
|
30
|
+
# @option opts [Symbol] :as Use a custom Ruby method name
|
31
|
+
# @option opts [Class] :type Return elements with this specific UIAutomation::Element sub-class
|
32
|
+
# @api private
|
33
|
+
def has_element_array(js_method_name, opts={})
|
34
|
+
define_element_using(:element_array_proxy_for, js_method_name, opts)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def define_element_using(proxy_method, js_method_name, opts)
|
40
|
+
method_name = opts[:as] || js_method_name.to_s.underscore
|
41
|
+
|
42
|
+
define_method(method_name) do
|
43
|
+
if opts[:type]
|
44
|
+
send(proxy_method, js_method_name, opts[:type])
|
45
|
+
else
|
46
|
+
send(proxy_method, js_method_name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
module ElementProxyMethods
|
3
|
+
# Returns a new proxy object to a UIAElementArray. function_name must correspond to
|
4
|
+
# a function on the currently proxied object that returns an UIAElementArray as
|
5
|
+
# defined by the Javascript API documentation.
|
6
|
+
#
|
7
|
+
# By default, the returned object will use UIAutomation::Element when creating
|
8
|
+
# proxies to any elements within its collection - pass a different UIAutomation::Element
|
9
|
+
# sub-class in as a second parameter if you want to use a specific type.
|
10
|
+
#
|
11
|
+
# @param [Symbol] function_name The javascript function that returns the proxied UIAElementArray.
|
12
|
+
# @param [Class] element_klass The class used as the proxy for each element in the array.
|
13
|
+
# @api private
|
14
|
+
def element_array_proxy_for(function_name, element_klass = UIAutomation::Element)
|
15
|
+
proxy_for(function_name,
|
16
|
+
proxy_klass: UIAutomation::ElementArray,
|
17
|
+
proxy_args: [element_klass, self, window]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Similar to proxy_for() but returns an instance UIAutomation::Element by default.
|
22
|
+
#
|
23
|
+
# A specific UIAutomation::Element sub-class can be passed in as an optional second
|
24
|
+
# parameter.
|
25
|
+
#
|
26
|
+
# @raise [TypeError] if klass is not a UIAutomation::Element or sub-class.
|
27
|
+
# @param [Symbol] function_name The javascript function that returns the proxied UIAElement.
|
28
|
+
# @param [Class] klass The class to use for the returned proxy.
|
29
|
+
# @api private
|
30
|
+
def element_proxy_for(function_name, klass = UIAutomation::Element)
|
31
|
+
raise TypeError.new("Element type #{klass} is not a sub-class of UIAutomation::Element") unless (klass <= UIAutomation::Element)
|
32
|
+
|
33
|
+
proxy_for(function_name,
|
34
|
+
proxy_klass: klass,
|
35
|
+
proxy_args: [self, window]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class RemoteProxy
|
41
|
+
include ElementProxyMethods
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIAKeyboard objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAKeyboardClassReference/
|
5
|
+
#
|
6
|
+
class Keyboard < Element
|
7
|
+
### @!group Element Collections
|
8
|
+
|
9
|
+
# The keyboard's keys
|
10
|
+
has_element_array :keys
|
11
|
+
|
12
|
+
### @!endgroup
|
13
|
+
|
14
|
+
### @!group Elements
|
15
|
+
|
16
|
+
# @return [UIAutomation::Element] the keyboard's done button
|
17
|
+
def done_button
|
18
|
+
buttons['Done']
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [UIAutomation::Element] the keyboard's return button
|
22
|
+
def return_button
|
23
|
+
buttons['Return']
|
24
|
+
end
|
25
|
+
|
26
|
+
### @!endgroup
|
27
|
+
|
28
|
+
### @!group Actions
|
29
|
+
|
30
|
+
# Types the given string by simulating key presses.
|
31
|
+
#
|
32
|
+
# @param [String] string the string to type
|
33
|
+
#
|
34
|
+
def type(string)
|
35
|
+
perform :typeString, string
|
36
|
+
end
|
37
|
+
|
38
|
+
### @!endgroup
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIALogger objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIALoggerClassReference/
|
5
|
+
#
|
6
|
+
class Logger < RemoteProxy
|
7
|
+
def self.logger(driver)
|
8
|
+
from_javascript(driver, 'UIALogger')
|
9
|
+
end
|
10
|
+
|
11
|
+
def start(message)
|
12
|
+
perform :logStart, message
|
13
|
+
end
|
14
|
+
|
15
|
+
def pass(message)
|
16
|
+
perform :logPass, message
|
17
|
+
end
|
18
|
+
|
19
|
+
def fail(message)
|
20
|
+
perform :logFail, message
|
21
|
+
end
|
22
|
+
|
23
|
+
def issue(message)
|
24
|
+
perform :logIssue, message
|
25
|
+
end
|
26
|
+
|
27
|
+
def debug(message)
|
28
|
+
perform :logDebug, message
|
29
|
+
end
|
30
|
+
|
31
|
+
def error(message)
|
32
|
+
perform :logError, message
|
33
|
+
end
|
34
|
+
|
35
|
+
def message(message)
|
36
|
+
perform :logMessage, message
|
37
|
+
end
|
38
|
+
|
39
|
+
def warning(message)
|
40
|
+
perform :logWarning, message
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIANavigationBar objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIANavigationBarClassReference/
|
5
|
+
#
|
6
|
+
class NavigationBar < Element
|
7
|
+
### @!group Elements
|
8
|
+
|
9
|
+
# The navigation bar's left button
|
10
|
+
has_element :leftButton
|
11
|
+
|
12
|
+
# The navigation bar's right button
|
13
|
+
has_element :rightButton
|
14
|
+
|
15
|
+
### @!endgroup
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIAPicker objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAPickerClassReference/
|
5
|
+
#
|
6
|
+
class Picker < Element
|
7
|
+
### @!group Element Collections
|
8
|
+
|
9
|
+
# An array representing each wheel in the picker
|
10
|
+
has_element_array :wheels
|
11
|
+
|
12
|
+
### @!endgroup
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIAPopover objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAPopoverClassReference/
|
5
|
+
#
|
6
|
+
class Popover < Element
|
7
|
+
### @!group Elements
|
8
|
+
|
9
|
+
# The action sheet contained by the popover
|
10
|
+
has_element :actionSheet, type: UIAutomation::ActionSheet
|
11
|
+
|
12
|
+
# The navigation bar contained by the popover
|
13
|
+
has_element :navigationBar, type: UIAutomation::NavigationBar
|
14
|
+
|
15
|
+
# The tab bar contained by the popover
|
16
|
+
has_element :tabBar, type: UIAutomation::TabBar
|
17
|
+
|
18
|
+
# The toolbar contained by the popover
|
19
|
+
has_element :toolbar
|
20
|
+
|
21
|
+
### @!endgroup
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIATabBar objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIATabBarClassReference/
|
5
|
+
#
|
6
|
+
class TabBar < Element
|
7
|
+
### @!group Elements
|
8
|
+
|
9
|
+
# The currently selected tab
|
10
|
+
has_element :selectedButton
|
11
|
+
|
12
|
+
### @!endgroup
|
13
|
+
|
14
|
+
def tabs
|
15
|
+
buttons
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :selected_tab, :selected_button
|
19
|
+
|
20
|
+
### @!group Actions
|
21
|
+
|
22
|
+
# Selects the named tab
|
23
|
+
# @param [String] tab_name the tab's label
|
24
|
+
#
|
25
|
+
def tap_tab(tab_name)
|
26
|
+
tabs[tab_name].tap
|
27
|
+
end
|
28
|
+
|
29
|
+
### @!endgroup
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIATableView objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIATableViewClassReference/
|
5
|
+
#
|
6
|
+
class TableView < Element
|
7
|
+
### @!group Element Collections
|
8
|
+
|
9
|
+
# All of the cells in the table view
|
10
|
+
has_element_array :cells
|
11
|
+
|
12
|
+
# ALl of the visible cells in the table view
|
13
|
+
has_element_array :visibleCells
|
14
|
+
|
15
|
+
### @!endgroup
|
16
|
+
|
17
|
+
### @!group Actions
|
18
|
+
|
19
|
+
# Scrolls down to the named cell until it is visible on screen.
|
20
|
+
#
|
21
|
+
# @param [String] name the name of the cell to scroll to
|
22
|
+
def scroll_down_to_cell_named(name)
|
23
|
+
cells[name].until_element(:visible?) { scroll_down }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Scrolls up to the named cell until it is visible on screen.
|
27
|
+
#
|
28
|
+
# @param [String] name the name of the cell to scroll to
|
29
|
+
def scroll_up_to_cell_named(name)
|
30
|
+
cells[name].until_element(:visible?) { scroll_up }
|
31
|
+
end
|
32
|
+
|
33
|
+
### @!endgroup
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIATarget objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIATargetClassReference/
|
5
|
+
#
|
6
|
+
class Target < RemoteProxy
|
7
|
+
# Returns an instance of UIAutomation::Target that represents the singleton local target (UIATarget.localTarget()).
|
8
|
+
# @return [UIAutomation::Target]
|
9
|
+
#
|
10
|
+
def self.local_target(executor)
|
11
|
+
from_javascript(executor, 'UIATarget.localTarget()')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns a proxy to the currently active app.
|
15
|
+
# @return [UIAutomation::Application]
|
16
|
+
#
|
17
|
+
def front_most_app
|
18
|
+
proxy_for(:frontMostApp, proxy_klass: UIAutomation::Application)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets the current location (iOS Simulator only).
|
22
|
+
# @param [Hash] coordinates A hash containing :lat and :lng keys.
|
23
|
+
#
|
24
|
+
def location=(coordinates)
|
25
|
+
set_location(coordinates)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Performs a tap on the element by tapping at the position
|
29
|
+
# of the element's rect.
|
30
|
+
#
|
31
|
+
# The preferred method of tapping an element is to just
|
32
|
+
# call UIAutomation::Element#tap which calls the UIAElement tap() method
|
33
|
+
# directly on the element but this can sometimes fail on
|
34
|
+
# certain elements - this method is provided as a fallback.
|
35
|
+
#
|
36
|
+
# @param [UIAutomation::Element] element The element to tap.
|
37
|
+
#
|
38
|
+
def tap_element(element)
|
39
|
+
perform(:tap, element.rect)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIATextField objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIATextFieldClassReference/
|
5
|
+
#
|
6
|
+
class TextField < Element
|
7
|
+
include Traits::TextInput
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
# A RemoteProxy to UIATextView objects in the Javascript API.
|
3
|
+
#
|
4
|
+
# @see https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIATextViewClassReference/
|
5
|
+
#
|
6
|
+
class TextView < Element
|
7
|
+
include Traits::TextInput
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
module Traits
|
3
|
+
# Defines methods for elements that can be cancelled using a cancel button.
|
4
|
+
#
|
5
|
+
module Cancellable
|
6
|
+
# @return [UIAutomation::Element] The element's cancel button
|
7
|
+
def cancel_button
|
8
|
+
element_proxy_for(:cancelButton)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module UIAutomation
|
2
|
+
module Traits
|
3
|
+
# Defines methods for elements that support text entry using the system keyboard.
|
4
|
+
#
|
5
|
+
module TextInput
|
6
|
+
### @!group Actions
|
7
|
+
|
8
|
+
# Sets the text of the text field directly, bypassing the keyboard.
|
9
|
+
#
|
10
|
+
# If the text field does not currently have keyboard focus, it will be tapped first.
|
11
|
+
#
|
12
|
+
# @param [String] value the text to use as the text field's new value
|
13
|
+
#
|
14
|
+
def text=(value)
|
15
|
+
with_keyboard_focus do
|
16
|
+
perform :setValue, value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Begins typing in the text field using the on-screen keyboard
|
21
|
+
#
|
22
|
+
# If the text field has keyboard focus and the keyboard is visible, then the given
|
23
|
+
# block will be called immediately.
|
24
|
+
#
|
25
|
+
# Otherwise, this method will tap the text field if necessary, wait until it reports that
|
26
|
+
# it has keyboard focus, wait for the keyboard to become visible if it isn't
|
27
|
+
# already and then call the block.
|
28
|
+
#
|
29
|
+
# As a convenience, a proxy to the keyboard is yielded to the block.
|
30
|
+
#
|
31
|
+
# This method does not dismiss the keyboard automatically.
|
32
|
+
#
|
33
|
+
# @example Simulate typing in a text field using the on-screen keyboard
|
34
|
+
# text_field.begin_typing do |keyboard|
|
35
|
+
# keyboard.type "some text"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @yieldparam [UIAutomation::Keyboard] keyboard the keyboard proxy
|
39
|
+
#
|
40
|
+
def begin_typing(&block)
|
41
|
+
with_keyboard_focus do
|
42
|
+
application.keyboard.when_element(:visible?) do
|
43
|
+
yield application.keyboard if block_given?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
### @!endgroup
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def with_keyboard_focus(&block)
|
53
|
+
tap unless has_keyboard_focus?
|
54
|
+
when_element(:has_keyboard_focus?, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|