class ParallelCalabash::IosRunner

Public Class Methods

new(device_helper, silence, skip_ios_ping_check) click to toggle source
# File lib/parallel_calabash/runner.rb, line 80
def initialize(device_helper, silence, skip_ios_ping_check)
  @device_helper = device_helper
  @silence = silence
  @skip_ios_ping_check = skip_ios_ping_check
end

Public Instance Methods

base_command() click to toggle source
# File lib/parallel_calabash/runner.rb, line 86
def base_command
  'bundle exec cucumber'
end
command_for_test(process_number, test_files, app_path, cucumber_options, simulator) click to toggle source
# File lib/parallel_calabash/runner.rb, line 106
def command_for_test(process_number, test_files, app_path, cucumber_options, simulator)
  device = @device_helper.device_for_process process_number
  separator = (WINDOWS ? ' & ' : ';')
  remote = device[:USER] ? "ssh #{device[:USER]}@localhost" : 'bash -c'

  if device[:CALABASH_SERVER_PORT]
    user_app = copy_app_set_port(app_path, device)
  else
    user_app = app_path
  end

  device_name = device[:DEVICE_NAME] || "PCal-#{device[:USER]}"
  device_simulator = device[:SIMULATOR] || simulator

  # Device target changed in XCode 7, losing ' Simulator' for some reason.
  maybe_simulator = @device_helper.xcode7? ? '' : ' Simulator'
  device_target = device[:DEVICE_TARGET] || "#{device_name} (#{version(device_simulator)}#{maybe_simulator})"
  device_info = device[:DEVICE_TARGET] || (device[:USER] ? create_simulator(device_name, remote, simulator) : '')
  device_endpoint = device[:DEVICE_ENDPOINT] || "http://localhost:#{device[:CALABASH_SERVER_PORT]}"
  $stdout.print "#{process_number}>> Device: #{device_info} = #{device_name} = #{device_target}\n"
  $stdout.flush

  unless @skip_ios_ping_check
    hostname = device_endpoint.match("http://(.*):").captures.first
    pingable = system "ping -c 1 -o #{hostname}"
    fail "Cannot ping device_endpoint host: #{hostname}" unless pingable
  end

  cmd = [base_command, "APP_BUNDLE_PATH=#{user_app}", cucumber_options, *test_files].compact*' '

  env = {
      AUTOTEST: '1',
      DEVICE_ENDPOINT: device_endpoint,
      DEVICE_TARGET: device_target,
      DEVICE_INFO: device_info,
      TEST_USER: device[:USER] || %x( whoami ).strip,
      # 'DEBUG_UNIX_CALLS' => '1',
      TEST_PROCESS_NUMBER: (process_number+1).to_s,
      SCREENSHOT_PATH: "PCal_#{process_number+1}_"
  }
  env['BUNDLE_ID'] = ENV['BUNDLE_ID'] if ENV['BUNDLE_ID']
  exports = env.map { |k, v| WINDOWS ? "(SET \"#{k}=#{v}\")" : "#{k}='#{v}';export #{k}" }.join(separator)

  cmd = [ exports,  "#{device[:INIT] || ' : '}", "cd #{File.absolute_path('.')}", "umask 002", cmd].join(separator)

  if device[:USER]
    "#{remote} bash -lc \"#{cmd}\" 2>&1"
  else
    "bash -c \"#{cmd}\" 2>&1"
  end
end
copy_app_set_port(app_path, device) click to toggle source
# File lib/parallel_calabash/runner.rb, line 205
def copy_app_set_port(app_path, device)
  user_path = File.dirname(app_path) + '/' + device[:USER]
  FileUtils.rmtree(user_path)
  FileUtils.mkdir_p(user_path)
  user_app = user_path + '/' + File.basename(app_path)
  FileUtils.copy_entry(app_path, user_app)

  # Set plist.

  system("/usr/libexec/PlistBuddy -c 'Delete CalabashServerPort integer #{device[:CALABASH_SERVER_PORT]}' #{user_app}/Info.plist")
  unless system("/usr/libexec/PlistBuddy -c 'Add CalabashServerPort integer #{device[:CALABASH_SERVER_PORT]}' #{user_app}/Info.plist")
    raise "Unable to set CalabashServerPort in #{user_app}/Info.plist"
  end

  puts "User app: #{user_app}"

  user_app
end
create_simulator(device_name, ssh, simulator) click to toggle source
# File lib/parallel_calabash/runner.rb, line 184
def create_simulator(device_name, ssh, simulator)
  stop_and_remove(device_name, ssh)
  puts "Double check..."
  stop_and_remove(device_name, ssh)
  puts "OK if none"

  device_info = %x( #{ssh} "xcrun simctl create #{device_name} #{simulator}" ).strip
  fail "Failed to create #{device_name} for #{ssh}" unless device_info
  device_info
end
prepare_for_parallel_execution() click to toggle source
# File lib/parallel_calabash/runner.rb, line 169
def prepare_for_parallel_execution
  # copy-chown all the files, and set everything group-writable.
  Find.find('.') do |path|
    if File.file?(path) && !File.stat(path).owned?
      temp = "#{path}......"
      FileUtils.copy(path, temp)
      FileUtils.move(temp, path)
      puts "Chowned/copied.... #{path}"
    end
  end
  FileUtils.chmod_R('g+w', 'build/reports') if File.exists? 'build/reports'
  FileUtils.chmod('g+w', Dir['*'])
  FileUtils.chmod('g+w', '.')
end
run_tests(test_files, process_number, options) click to toggle source
# File lib/parallel_calabash/runner.rb, line 90
def run_tests(test_files, process_number, options)
  test = command_for_test(
      process_number, test_files,
      options[:app_path], "#{options[:cucumber_options]} #{options[:cucumber_reports]}",
      options[:simulator] || '0-0')
  $stdout.print "#{process_number}>> Command: #{test}\n"
  $stdout.flush

  o = execute_command_for_process(process_number, test)
  device = @device_helper.device_for_process process_number
  log = "/tmp/PCal-#{device[:USER]}.process_number"
  puts "Writing log #{log}"
  open(log, 'w') { |file| file.print o[:stdout] }
  o
end
stop_and_remove(device_name, ssh) click to toggle source
# File lib/parallel_calabash/runner.rb, line 195
def stop_and_remove(device_name, ssh)
  devices = %x( #{ssh} "xcrun simctl list devices" | grep #{device_name} )
  puts "Devices: #{devices}"
  devices.each_line do |device|
    _name, id, state = device.match(/^\s*([^(]*?)\s*\((\S+)\)\s+\((\S+)\)/).captures
    puts 'Shutdown: ' + %x( #{ssh} "xcrun simctl shutdown #{id}" ) if state =~ /booted/
    puts 'Delete: ' + %x( #{ssh} "xcrun simctl delete #{id}" )
  end
end
version(simulator) click to toggle source

def udid(name)

name = name.gsub(/(\W)/, '\\\\\\1')
line = %x( instruments -s devices ).split("\n").grep(/#{name}/)
fail "Found #{line.size} matches for #{name}, expected 1" unless line.size == 1
line.first.match(/\[(\S+)\]/).captures.first.to_s

end

# File lib/parallel_calabash/runner.rb, line 165
def version(simulator)
  simulator.match('\d+-\d+$').to_s.gsub('-', '.')
end