Class: Maze::Driver::Appium

Inherits:
Appium::Driver
  • Object
show all
Defined in:
lib/maze/driver/appium.rb

Overview

Provide a thin layer of abstraction above @see Appium::Driver

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server_url, capabilities, locator = :id) ⇒ Appium

Creates the Appium driver

Parameters:

  • server_url (String)

    URL of the Appium server

  • capabilities (Hash)

    a hash of capabilities to be used in this test run

  • locator (Symbol) (defaults to: :id)

    the primary locator strategy Appium should use to find elements



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/maze/driver/appium.rb', line 31

def initialize(server_url, capabilities, locator = :id)
  # Sets up identifiers for ease of connecting jobs
  capabilities ||= {}

  @element_locator = locator
  @capabilities = capabilities

  # Timers
  @find_element_timer = Maze.timers.add 'Appium - find element'
  @click_element_timer = Maze.timers.add 'Appium - click element'
  @clear_element_timer = Maze.timers.add 'Appium - clear element'
  @send_keys_timer = Maze.timers.add 'Appium - send keys to element'

  super({
    'caps' => @capabilities,
    'appium_lib' => {
      server_url: server_url
    }
  }, true)
end

Instance Attribute Details

#app_idString

Returns The app_id derived from session_capabilities (appPackage on Android, bundleID on iOS).

Returns:

  • (String)

    The app_id derived from session_capabilities (appPackage on Android, bundleID on iOS)



16
17
18
# File 'lib/maze/driver/appium.rb', line 16

def app_id
  @app_id
end

#capabilitiesObject (readonly)

Returns the value of attribute capabilities.



24
25
26
# File 'lib/maze/driver/appium.rb', line 24

def capabilities
  @capabilities
end

#device_typeObject (readonly)

Returns the value of attribute device_type.



20
21
22
# File 'lib/maze/driver/appium.rb', line 20

def device_type
  @device_type
end

Instance Method Details

#clear_and_send_keys_to_element(element_id, text) ⇒ Object

Sends keys to a given element, clearing it first

Parameters:

  • element_id (String)

    the element to clear and send text to

  • text (String)

    the text to send



214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/maze/driver/appium.rb', line 214

def clear_and_send_keys_to_element(element_id, text)
  element = find_element_timed(element_id)
  @clear_element_timer.time do
    element.clear
  end

  @send_keys_timer.time do
    element.send_keys(text)
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#clear_element(element_id) ⇒ Object

Clears a given element

Parameters:

  • element_id (String)

    the element to clear



156
157
158
159
160
161
162
163
164
165
# File 'lib/maze/driver/appium.rb', line 156

def clear_element(element_id)
  element = find_element_timed(element_id)
  @clear_element_timer.time do
    element.clear
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#click_element(element_id) ⇒ Object

Clicks a given element

Parameters:

  • element_id (String)

    the element to click



124
125
126
127
128
129
130
131
132
133
# File 'lib/maze/driver/appium.rb', line 124

def click_element(element_id)
  element = find_element_timed(element_id)
  @click_element_timer.time do
    element.click
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#click_element_if_present(element_id) ⇒ Boolean

Clicks a given element, ignoring any NoSuchElementError

Parameters:

  • element_id (String)

    the element to click

Returns:

  • (Boolean)

    True is the element was clicked



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/maze/driver/appium.rb', line 139

def click_element_if_present(element_id)
  element = find_element_timed(element_id)
  @click_element_timer.time do
    element.click
  end
  true
rescue Selenium::WebDriver::Error::NoSuchElementError
  false
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#close_appObject

A wrapper around close_app adding extra error handling



102
103
104
105
106
107
108
# File 'lib/maze/driver/appium.rb', line 102

def close_app
  super
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#device_infoObject



237
238
239
# File 'lib/maze/driver/appium.rb', line 237

def device_info
  driver.execute_script('mobile:deviceInfo')
end

#find_element_timed(element_id) ⇒ Object

A wrapper around find_element adding timer functionality



111
112
113
114
115
116
117
118
119
# File 'lib/maze/driver/appium.rb', line 111

def find_element_timed(element_id)
  @find_element_timer.time do
    find_element(@element_locator, element_id)
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#launch_appObject

A wrapper around launch_app adding extra error handling



93
94
95
96
97
98
99
# File 'lib/maze/driver/appium.rb', line 93

def launch_app
  super
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#page_sourceObject

Gets the application hierarchy XML



168
169
170
# File 'lib/maze/driver/appium.rb', line 168

def page_source
  @driver.page_source
end

#reset_with_timeout(timeout = 0.1) ⇒ Object

Reset the currently running application after a given timeout

Parameters:

  • timeout (Number) (defaults to: 0.1)

    the amount of time in seconds to wait before resetting



232
233
234
235
# File 'lib/maze/driver/appium.rb', line 232

def reset_with_timeout(timeout = 0.1)
  sleep(timeout)
  reset
end

#send_keys(text) ⇒ Object

Send keys to the device without a specific element

Parameters:

  • text (String)

    the text to send



206
207
208
# File 'lib/maze/driver/appium.rb', line 206

def send_keys(text)
  @driver.send_keys(text)
end

#send_keys_to_element(element_id, text) ⇒ Object

Sends keys to a given element

Parameters:

  • element_id (String)

    the element to send text to

  • text (String)

    the text to send



181
182
183
184
185
186
187
188
189
190
# File 'lib/maze/driver/appium.rb', line 181

def send_keys_to_element(element_id, text)
  element = find_element_timed(element_id)
  @send_keys_timer.time do
    element.send_keys(text)
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
end

#session_capabilitiesObject



241
242
243
# File 'lib/maze/driver/appium.rb', line 241

def session_capabilities
  driver.session_capabilities
end

#set_rotation(orientation) ⇒ Object

Sets the rotation of the device

Parameters:

  • orientation (Symbol)

    :portrait or :landscape



195
196
197
# File 'lib/maze/driver/appium.rb', line 195

def set_rotation(orientation)
  @driver.rotation = orientation
end

#start_driverObject

Starts the Appium driver



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/maze/driver/appium.rb', line 53

def start_driver
  begin
    $logger.info 'Starting Appium driver...'
    time = Time.now
    super
    $logger.info "Appium driver started in #{(Time.now - time).to_i}s"
  rescue => error
    $logger.warn "Appium driver failed to start in #{(Time.now - time).to_i}s"
    $logger.warn "#{error.class} occurred with message: #{error.message}"
    # Do not Bugsnag.notify here as we re-raise the error
    raise error
  end
end

#unlockObject

Unlocks the device



173
174
175
# File 'lib/maze/driver/appium.rb', line 173

def unlock
  @driver.unlock
end

#wait_for_element(element_id, timeout = 15, retry_if_stale = true) ⇒ Object

Checks for an element, waiting until it is present or the method times out

Parameters:

  • element_id (String)

    the element to search for

  • timeout (Integer) (defaults to: 15)

    the maximum time to wait for an element to be present in seconds

  • retry_if_stale (Boolean) (defaults to: true)

    enables the method to retry acquiring the element if a StaleObjectException occurs



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/maze/driver/appium.rb', line 72

def wait_for_element(element_id, timeout = 15, retry_if_stale = true)
  wait = Selenium::WebDriver::Wait.new(timeout: timeout)
  wait.until { find_element(@element_locator, element_id).displayed? }
rescue Selenium::WebDriver::Error::TimeoutError
  false
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
  if retry_if_stale
    wait_for_element(element_id, timeout, false)
  else
    $logger.warn "StaleElementReferenceError occurred: #{e}"
    false
  end
rescue Selenium::WebDriver::Error::ServerError => e
  # Assume the remote appium session has stopped, so crash out of the session
  Maze.driver = nil
  raise e
else
  true
end

#window_sizeObject



199
200
201
# File 'lib/maze/driver/appium.rb', line 199

def window_size
  @driver.window_size
end