class Snapshot::SimulatorLauncherBase

Attributes

collected_errors[RW]
current_number_of_retries_due_to_failing_simulator[RW]

The number of times we failed on launching the simulator… sigh

launcher_config[RW]

Public Class Methods

new(launcher_configuration: nil) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 19
def initialize(launcher_configuration: nil)
  @launcher_config = launcher_configuration
  @device_boot_datetime = DateTime.now
end

Public Instance Methods

add_media(device_types, media_type, paths) click to toggle source

pass an array of device types

# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 89
def add_media(device_types, media_type, paths)
  media_type = media_type.to_s

  device_types.each do |device_type|
    UI.verbose("Adding #{media_type}s to #{device_type}...")
    device_udid = TestCommandGenerator.device_udid(device_type)

    UI.message("Launch Simulator #{device_type}")
    Helper.backticks("xcrun instruments -w #{device_udid} &> /dev/null")

    paths.each do |path|
      UI.message("Adding '#{path}'")

      # Attempting addmedia since addphoto and addvideo are deprecated
      output = Helper.backticks("xcrun simctl addmedia #{device_udid} #{path.shellescape} &> /dev/null")

      # Run legacy addphoto and addvideo if addmedia isn't found
      # Output will be empty strin gif it was a success
      # Output will contain "usage: simctl" if command not found
      if output.include?('usage: simctl')
        Helper.backticks("xcrun simctl add#{media_type} #{device_udid} #{path.shellescape} &> /dev/null")
      end
    end
  end
end
clear_status_bar(device_type) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 140
def clear_status_bar(device_type)
  device_udid = TestCommandGenerator.device_udid(device_type)

  UI.message("Clearing Status Bar Override")
  Helper.backticks("xcrun simctl status_bar #{device_udid} clear &> /dev/null")
end
copy_simulator_logs(device_names, language, locale, launch_arguments) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 197
def copy_simulator_logs(device_names, language, locale, launch_arguments)
  return unless launcher_config.output_simulator_logs

  detected_language = locale || language
  language_folder = File.join(launcher_config.output_directory, detected_language)

  device_names.each do |device_name|
    device = TestCommandGeneratorBase.find_device(device_name)
    components = [launch_arguments].delete_if { |a| a.to_s.length == 0 }

    UI.header("Collecting system logs #{device_name} - #{language}")
    log_identity = Digest::MD5.hexdigest(components.join("-"))
    FastlaneCore::Simulator.copy_logs(device, log_identity, language_folder, @device_boot_datetime)
  end
end
disable_slide_to_type(device_type) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 189
def disable_slide_to_type(device_type)
  device_udid = TestCommandGenerator.device_udid(device_type)
  if device_udid
    UI.message("Disabling slide to type on #{device_type}")
    FastlaneCore::Simulator.disable_slide_to_type(udid: device_udid)
  end
end
erase_simulator(device_type) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 154
def erase_simulator(device_type)
  UI.verbose("Erasing #{device_type}...")
  device_udid = TestCommandGenerator.device_udid(device_type)

  UI.important("Erasing #{device_type}...")

  `xcrun simctl erase #{device_udid} &> /dev/null`
end
interface_style(device_type, dark_mode) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 177
def interface_style(device_type, dark_mode)
  device_udid = TestCommandGenerator.device_udid(device_type)
  if device_udid
    plist = {
      UserInterfaceStyleMode: (dark_mode ? 2 : 1)
    }
    UI.message("Setting interface style #{device_type} (UserInterfaceStyleMode=#{dark_mode})")
    plist_path = "#{ENV['HOME']}/Library/Developer/CoreSimulator/Devices/#{device_udid}/data/Library/Preferences/com.apple.uikitservices.userInterfaceStyleMode.plist"
    File.write(plist_path, Plist::Emit.dump(plist))
  end
end
localize_simulator(device_type, language, locale) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 163
def localize_simulator(device_type, language, locale)
  device_udid = TestCommandGenerator.device_udid(device_type)
  if device_udid
    locale ||= language.sub("-", "_")
    plist = {
      AppleLocale: locale,
      AppleLanguages: [language]
    }
    UI.message("Localizing #{device_type} (AppleLocale=#{locale} AppleLanguages=[#{language}])")
    plist_path = "#{ENV['HOME']}/Library/Developer/CoreSimulator/Devices/#{device_udid}/data/Library/Preferences/.GlobalPreferences.plist"
    File.write(plist_path, Plist::Emit.dump(plist))
  end
end
override_status_bar(device_type, arguments = nil) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 115
def override_status_bar(device_type, arguments = nil)
  device_udid = TestCommandGenerator.device_udid(device_type)

  UI.message("Launch Simulator #{device_type}")
  # Boot the simulator and wait for it to finish booting
  Helper.backticks("xcrun simctl bootstatus #{device_udid} -b &> /dev/null")

  # "Booted" status is not enough for to adjust the status bar
  # Simulator could stil be booting with Apple logo
  # Need to wait "some amount of time" until home screen shows
  boot_sleep = ENV["SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT"].to_i || 10
  UI.message("Waiting #{boot_sleep} seconds for device to fully boot before overriding status bar... Set 'SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT' environemnt variable to adjust timeout")
  sleep(boot_sleep) if boot_sleep > 0

  UI.message("Overriding Status Bar")

  if arguments.nil? || arguments.empty?
    # The time needs to be passed as ISO8601 so the simulator formats it correctly
    time = Time.new(2007, 1, 9, 9, 41, 0)
    arguments = "--time #{time.iso8601} --dataNetwork wifi --wifiMode active --wifiBars 3 --cellularMode active --cellularBars 4 --batteryState charged --batteryLevel 100"
  end

  Helper.backticks("xcrun simctl status_bar #{device_udid} override #{arguments} &> /dev/null")
end
prepare_directories_for_launch(language: nil, locale: nil, launch_arguments: nil) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 37
def prepare_directories_for_launch(language: nil, locale: nil, launch_arguments: nil)
  screenshots_path = TestCommandGenerator.derived_data_path
  FileUtils.rm_rf(File.join(screenshots_path, "Logs"))
  FileUtils.rm_rf(screenshots_path) if launcher_config.clean
  FileUtils.mkdir_p(screenshots_path)

  FileUtils.mkdir_p(CACHE_DIR)
  FileUtils.mkdir_p(SCREENSHOTS_DIR)

  File.write(File.join(CACHE_DIR, "language.txt"), language)
  File.write(File.join(CACHE_DIR, "locale.txt"), locale || "")
  File.write(File.join(CACHE_DIR, "snapshot-launch_arguments.txt"), launch_arguments.last)
end
prepare_for_launch(device_types, language, locale, launch_arguments) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 32
def prepare_for_launch(device_types, language, locale, launch_arguments)
  prepare_directories_for_launch(language: language, locale: locale, launch_arguments: launch_arguments)
  prepare_simulators_for_launch(device_types, language: language, locale: locale)
end
prepare_simulators_for_launch(device_types, language: nil, locale: nil) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 51
def prepare_simulators_for_launch(device_types, language: nil, locale: nil)
  # Kill and shutdown all currently running simulators so that the following settings
  # changes will be picked up when they are started again.
  Snapshot.kill_simulator # because of https://github.com/fastlane/fastlane/issues/2533
  `xcrun simctl shutdown booted &> /dev/null`

  Fixes::SimulatorZoomFix.patch
  Fixes::HardwareKeyboardFix.patch
  Fixes::SharedPasteboardFix.patch

  device_types.each do |type|
    if launcher_config.erase_simulator || launcher_config.localize_simulator || !launcher_config.dark_mode.nil?
      if launcher_config.erase_simulator
        erase_simulator(type)
      end
      if launcher_config.localize_simulator
        localize_simulator(type, language, locale)
      end
      unless launcher_config.dark_mode.nil?
        interface_style(type, launcher_config.dark_mode)
      end
    end
    if launcher_config.reinstall_app && !launcher_config.erase_simulator
      # no need to reinstall if device has been erased
      uninstall_app(type)
    end
    if launcher_config.disable_slide_to_type
      disable_slide_to_type(type)
    end
  end

  unless launcher_config.headless
    simulator_path = File.join(Helper.xcode_path, 'Applications', 'Simulator.app')
    Helper.backticks("open -a #{simulator_path} -g", print: FastlaneCore::Globals.verbose?)
  end
end
uninstall_app(device_type) click to toggle source
# File snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb, line 147
def uninstall_app(device_type)
  launcher_config.app_identifier ||= UI.input("App Identifier: ")
  device_udid = TestCommandGenerator.device_udid(device_type)

  FastlaneCore::Simulator.uninstall_app(launcher_config.app_identifier, device_type, device_udid)
end