Skip to content

Instantly share code, notes, and snippets.

@yonekawa
Last active April 6, 2016 20:30
Show Gist options
  • Save yonekawa/a66020d08d3fb1ec6457 to your computer and use it in GitHub Desktop.
Save yonekawa/a66020d08d3fb1ec6457 to your computer and use it in GitHub Desktop.
Appium support action for fastlane
module Fastlane
module Actions
class AppiumAction < Action
INVOKE_TIMEOUT = 30
APPIUM_PATH_HOMEBREW = '/usr/local/bin/appium'
APPIUM_APP_PATH = '/Applications/Appium.app'
APPIUM_APP_BUNDLE_PATH = 'Contents/Resources/node_modules/.bin/appium'
def self.run(params)
Actions.verify_gem!('rspec')
Actions.verify_gem!('appium_lib')
require 'rspec'
require 'appium_lib'
FastlaneCore::PrintTable.print_values(
config: params,
title: "Summary for Appium Action"
)
if params[:invoke_appium_server]
appium_pid = invoke_appium_server(params)
wait_for_appium_server(params)
end
configure_rspec(params)
rspec_args = []
rspec_args << params[:spec_path]
status = RSpec::Core::Runner.run(rspec_args).to_i
if status != 0
raise "Failed to run Appium spec. status code: #{status}".red
end
ensure
Actions.sh "kill #{appium_pid}" if appium_pid
end
def self.invoke_appium_server(params)
appium = detect_appium(params)
fork do
Process.exec("#{appium} -a #{params[:host]} -p #{params[:port]}")
end
end
def self.detect_appium(params)
appium_path = params[:appium_path] || `which appium`.to_s.strip
if appium_path.empty?
if File.exist?(APPIUM_PATH_HOMEBREW)
appium_path = APPIUM_PATH_HOMEBREW
elsif File.exist?(APPIUM_APP_PATH)
appium_path = APPIUM_APP_PATH
end
end
unless File.exist?(appium_path)
raise 'You have to install Appium using `npm install -g appium`'.red
end
if appium_path.end_with?('.app')
appium_path = "#{appium_path}/#{APPIUM_APP_BUNDLE_PATH}"
end
Helper.log.info("Appium executable detected: #{appium_path}")
appium_path
end
def self.wait_for_appium_server(params)
loop.with_index do |_, count|
break if `lsof -i:#{params[:port]}`.to_s.length != 0
if count * 5 > INVOKE_TIMEOUT
raise 'Invoke Appium server timed out'.red
end
sleep 5
end
end
def self.configure_rspec(params)
RSpec.configure do |c|
c.before(:each) do
caps = params[:caps] || {}
caps[:platformName] ||= params[:platform]
caps[:autoAcceptAlerts] ||= true
caps[:app] = params[:app_path]
@driver = Appium::Driver.new(
caps: caps,
server_url: params[:host],
port: params[:port]
).start_driver
Appium.promote_appium_methods(RSpec::Core::ExampleGroup)
end
c.after(:each) do
@driver.quit unless @driver.nil?
end
end
end
def self.description
'Run UI test by Appium with RSpec'
end
def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :platform,
env_name: 'FL_APPIUM_PLATFORM',
description: 'Appium platform name',
is_string: true
),
FastlaneCore::ConfigItem.new(
key: :spec_path,
env_name: 'FL_APPIUM_SPEC_PATH',
description: 'Path to Appium spec directory',
is_string: true
),
FastlaneCore::ConfigItem.new(
key: :app_path,
env_name: 'FL_APPIUM_APP_FILE_PATH',
description: 'Path to Appium target app file',
is_string: true
),
FastlaneCore::ConfigItem.new(
key: :invoke_appium_server,
env_name: 'FL_APPIUM_INVOKE_APPIUM_SERVER',
description: 'Use local Appium server with invoke automatically',
is_string: false,
default_value: true,
optional: true
),
FastlaneCore::ConfigItem.new(
key: :host,
env_name: 'FL_APPIUM_HOST',
description: 'Hostname of Appium server',
is_string: true,
default_value: '0.0.0.0',
optional: true
),
FastlaneCore::ConfigItem.new(
key: :port,
env_name: 'FL_APPIUM_PORT',
description: 'HTTP port of Appium server',
is_string: false,
default_value: 4723,
optional: true
),
FastlaneCore::ConfigItem.new(
key: :appium_path,
env_name: 'FL_APPIUM_EXECUTABLE_PATH',
description: 'Path to Appium executable',
is_string: true,
optional: true
),
FastlaneCore::ConfigItem.new(
key: :caps,
env_name: 'FL_APPIUM_CAPS',
description: 'Hash of caps for Appium::Driver',
is_string: false,
optional: true
)
]
end
def self.author
'yonekawa'
end
def self.is_supported?(platform)
platform == :ios
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment