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
51
# File 'lib/maze/driver/appium.rb', line 31

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

  @failed = false
  @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



226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/maze/driver/appium.rb', line 226

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
  fail_driver
  raise e
end

#clear_element(element_id) ⇒ Object

Clears a given element

Parameters:

  • element_id (String)

    the element to clear



168
169
170
171
172
173
174
175
176
177
# File 'lib/maze/driver/appium.rb', line 168

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
  fail_driver
  raise e
end

#click_element(element_id) ⇒ Object

Clicks a given element

Parameters:

  • element_id (String)

    the element to click



136
137
138
139
140
141
142
143
144
145
# File 'lib/maze/driver/appium.rb', line 136

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
  fail_driver
  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



151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/maze/driver/appium.rb', line 151

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
  fail_driver
  raise e
end

#close_appObject

A wrapper around close_app adding extra error handling



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

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

#device_infoObject



249
250
251
# File 'lib/maze/driver/appium.rb', line 249

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

#fail_driverObject

Marks the driver as failed



74
75
76
77
# File 'lib/maze/driver/appium.rb', line 74

def fail_driver
  $logger.error 'Appium driver failed, remaining scenarios will be skipped'
  @failed = true
end

#failed?Boolean

Whether the driver has known to have failed (it may still have failed and us not know yet)

Returns:

  • (Boolean)


69
70
71
# File 'lib/maze/driver/appium.rb', line 69

def failed?
  @failed
end

#find_element_timed(element_id) ⇒ Object

A wrapper around find_element adding timer functionality



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

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
  fail_driver
  raise e
end

#launch_appObject

A wrapper around launch_app adding extra error handling



105
106
107
108
109
110
111
# File 'lib/maze/driver/appium.rb', line 105

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

#page_sourceObject

Gets the application hierarchy XML



180
181
182
# File 'lib/maze/driver/appium.rb', line 180

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



244
245
246
247
# File 'lib/maze/driver/appium.rb', line 244

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



218
219
220
# File 'lib/maze/driver/appium.rb', line 218

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



193
194
195
196
197
198
199
200
201
202
# File 'lib/maze/driver/appium.rb', line 193

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
  fail_driver
  raise e
end

#session_capabilitiesObject



253
254
255
# File 'lib/maze/driver/appium.rb', line 253

def session_capabilities
  driver.session_capabilities
end

#set_rotation(orientation) ⇒ Object

Sets the rotation of the device

Parameters:

  • orientation (Symbol)

    :portrait or :landscape



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

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

#start_driverObject

Starts the Appium driver



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

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



185
186
187
# File 'lib/maze/driver/appium.rb', line 185

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



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/maze/driver/appium.rb', line 84

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
  fail_driver
  raise e
else
  true
end

#window_sizeObject



211
212
213
# File 'lib/maze/driver/appium.rb', line 211

def window_size
  @driver.window_size
end