Class: Maze::Client::Appium::BaseClient

Inherits:
Object
  • Object
show all
Defined in:
lib/maze/client/appium/base_client.rb

Direct Known Subclasses

BitBarClient, BrowserStackClient, LocalClient

Constant Summary collapse

FIXTURE_CONFIG =
'fixture_config.json'

Instance Method Summary collapse

Constructor Details

#initializeBaseClient

Returns a new instance of BaseClient.



23
24
25
# File 'lib/maze/client/appium/base_client.rb', line 23

def initialize
  @start_attempts = 0
end

Instance Method Details

#attempt_start_driver(config) ⇒ Object



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

def attempt_start_driver(config)
  config.capabilities = device_capabilities
  driver = Maze::Driver::Appium.new config.appium_server_url,
                                    config.capabilities,
                                    config.locator

  sanitized_url = Maze::Helper.sanitize_url(config.appium_server_url)
  $logger.info "Creating Appium session with #{sanitized_url}..."
  result = driver.start_driver
  if result
    # Log details of this session
    $logger.info "Created Appium session: #{driver.session_id}"
    @session_metadata = Maze::Client::Appium::SessionMetadata.new
    @session_metadata.id = driver.session_id
    @session_metadata.farm = Maze.config.farm.to_s
  end
  driver
end

#device_capabilitiesObject



150
151
152
# File 'lib/maze/client/appium/base_client.rb', line 150

def device_capabilities
  raise 'Method not implemented by this class'
end

#handle_error(error) ⇒ Object



141
142
143
# File 'lib/maze/client/appium/base_client.rb', line 141

def handle_error(error)
  raise 'Method not implemented by this class'
end

#log_run_introObject



154
155
156
# File 'lib/maze/client/appium/base_client.rb', line 154

def log_run_intro
  raise 'Method not implemented by this class'
end

#log_run_outroObject



158
159
160
# File 'lib/maze/client/appium/base_client.rb', line 158

def log_run_outro
  raise 'Method not implemented by this class'
end

#maze_addressObject



65
66
67
# File 'lib/maze/client/appium/base_client.rb', line 65

def maze_address
  raise 'Method not implemented by this class'
end

#prepare_sessionObject



61
62
63
# File 'lib/maze/client/appium/base_client.rb', line 61

def prepare_session
  raise 'Method not implemented by this class'
end

#report_sessionObject



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/maze/client/appium/base_client.rb', line 177

def report_session
  if @session_metadata.success
    error = Success.new('Success')
  else
    error = ::Selenium::WebDriver::Error::ServerError.new(@session_metadata.failure_message)
  end

  Bugsnag.notify(error) do |event|
    event.api_key = ENV['MAZE_APPIUM_BUGSNAG_API_KEY']

     = {
      'session id': @session_metadata.id,
      'success': @session_metadata.success,
      'device farm': @session_metadata.farm.to_s,
    }
    ['device'] = @session_metadata.device if @session_metadata.device

    if @session_metadata.success
      event.severity = 'info'
    else
      event.severity = 'error'
      event.unhandled = true
      ['failure message'] = @session_metadata.failure_message
    end

    event.(:'Appium Session', )
  end
end

#retry_start_driver?Boolean

Returns:

  • (Boolean)


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

def retry_start_driver?
  raise 'Method not implemented by this class'
end

#start_driver(config, max_attempts = 5) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/maze/client/appium/base_client.rb', line 102

def start_driver(config, max_attempts = 5)

  attempts = 0

  while attempts < max_attempts && Maze.driver.nil?
    attempts += 1
    start_error = nil
    begin
      Maze.driver = attempt_start_driver(config)
    rescue => error
      $logger.error "Session creation failed: #{error}"
      start_error = error
    end

    if Maze.driver
      # Infer OS version if necessary when running locally
      if Maze.config.farm == :local && Maze.config.os_version.nil?
        version = case Maze.config.os
                  when 'android'
                    driver.session_capabilities['platformVersion'].to_f
                  when 'ios'
                    driver.session_capabilities['sdkVersion'].to_f
                  end
        $logger.info "Inferred OS version to be #{version}"
        Maze.config.os_version = version
      end
    else
      interval = handle_error(start_error)
      if interval && attempts < max_attempts
        $logger.warn "Failed to create Appium driver, retrying in #{interval} seconds"
        Kernel::sleep interval
      else
        $logger.error 'Failed to create Appium driver, exiting'
        Kernel::exit(::Maze::Api::ExitCode::SESSION_CREATION_FAILURE)
      end
    end
  end
end

#start_scenarioObject



145
146
147
148
# File 'lib/maze/client/appium/base_client.rb', line 145

def start_scenario
  # Launch the app on macOS
  Maze.driver.get(Maze.config.app) if Maze.config.os == 'macos'
end

#start_sessionObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/maze/client/appium/base_client.rb', line 27

def start_session
  prepare_session

  start_driver(Maze.config)

  # Set bundle/app id for later use
  unless Maze.config.app.nil?
    Maze.driver.app_id = case Maze::Helper.get_current_platform
                         when 'android'
                           Maze.driver.session_capabilities['appPackage']
                         when 'ios'
                           unless app_id = Maze.driver.session_capabilities['CFBundleIdentifier']
                              app_id = Maze.driver.session_capabilities['bundleId']
                           end
                           app_id
                         end
  end

  $logger.error "Failed to determine app id." if Maze.driver.app_id.nil?

  # Log the device information after it's started
  write_device_info

  # Ensure the device is unlocked
  begin
    Maze::Api::Appium::DeviceManager.new.unlock
  rescue => error
    Bugsnag.notify error
    $logger.warn "Failed to unlock device: #{error}"
  end

  log_run_intro
end

#stop_sessionObject



162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/maze/client/appium/base_client.rb', line 162

def stop_session
  if Maze.driver.failed?
    @session_metadata.success = false
    @session_metadata.failure_message = Maze.driver.failure_reason
  else
    Maze.driver.driver_quit
    @session_metadata.success = true
  end

  # Report session outcome to Bugsnag
  report_session if ENV['MAZE_APPIUM_BUGSNAG_API_KEY']

  Maze::AppiumServer.stop if Maze::AppiumServer.running
end

#write_device_infoObject



73
74
75
76
77
78
79
80
81
# File 'lib/maze/client/appium/base_client.rb', line 73

def write_device_info
  info = Maze::Api::Appium::DeviceManager.new.info
  filepath = File.join(Dir.pwd, 'maze_output', 'device_info.json')
  File.open(filepath, 'w+') do |file|
    file.puts(JSON.pretty_generate(info))
  end
rescue => error
  $logger.warn "Could not write device information file, #{error.message}"
end