lib/calabash-cucumber/launch/simulator_helper.rb in calabash-cucumber-0.9.169.pre2 vs lib/calabash-cucumber/launch/simulator_helper.rb in calabash-cucumber-0.9.169.pre5
- old
+ new
@@ -1,407 +1,61 @@
require 'sim_launcher'
-require 'json'
-require 'run_loop'
-require 'net/http'
-require 'cfpropertylist'
module Calabash
module Cucumber
+ # this module has been replaced by Simulator Launcher
+ #
+ # @deprecated Use the SimulatorLauncher class instead
+ # @since 0.9.169
module SimulatorHelper
- class TimeoutErr < RuntimeError
- end
-
- DERIVED_DATA = File.expand_path("~/Library/Developer/Xcode/DerivedData")
- DEFAULT_DERIVED_DATA_INFO = File.expand_path("#{DERIVED_DATA}/*/info.plist")
-
- DEFAULT_SIM_WAIT = 30
-
- DEFAULT_SIM_RETRY = 2
-
- # Load environment variable for showing full console output.
- # If not env var set then we use false, i.e. output to console is limited.
- FULL_CONSOLE_OUTPUT = ENV['CALABASH_FULL_CONSOLE_OUTPUT'] == '1' ? true : false
-
- def self.relaunch(path, sdk = nil, version = 'iphone', args = nil)
-
- app_bundle_path = app_bundle_or_raise(path)
- ensure_connectivity(app_bundle_path, sdk, version, args)
-
- end
-
+ # quits the simulator
+ #
+ # this has been deprecated, but it appears in legacy launch hooks
+ #
+ # use this pattern instead:
+ #
+ # at_exit do
+ # launcher = Calabash::Cucumber::Launcher.new
+ # if launcher.simulator_target?
+ # launcher.simulator_launcher.stop unless launcher.calabash_no_stop?
+ # end
+ # end
+ #
+ # @deprecated use the SimulatorLauncher.new().stop instead
def self.stop
- simulator = SimLauncher::Simulator.new
- simulator.quit_simulator
- end
-
- def self.derived_data_dir_for_project
- dir = project_dir
- xcode_workspace_name = ''
- info_plist = Dir.glob(DEFAULT_DERIVED_DATA_INFO).find { |plist_file|
- begin
- plist = CFPropertyList::List.new(:file => plist_file)
- hash = CFPropertyList.native_types(plist.value)
- ws_dir = File.dirname(hash['WorkspacePath']).downcase
- p_dir = dir.downcase
- if (p_dir.include? ws_dir)
- xcode_workspace_name = ws_dir.split('/').last
- end
- ws_dir == p_dir
- rescue
- false
- end
- }
-
- if not info_plist.nil?
- return File.dirname(info_plist)
- else
- res = Dir.glob("#{dir}/*.xcodeproj")
- if res.empty?
- raise "Unable to find *.xcodeproj in #{dir}"
- elsif res.count > 1
- raise "Unable to found several *.xcodeproj in #{dir}: #{res}"
- end
-
- xcode_proj_name = res.first.split(".xcodeproj")[0]
-
- xcode_proj_name = File.basename(xcode_proj_name)
-
- build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
- File.basename(xc_proj).start_with?(xcode_proj_name)
- end
-
- if (build_dirs.count == 0 && !xcode_workspace_name.empty?)
- # check for directory named "workspace-{deriveddirectoryrandomcharacters}"
- build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
- File.basename(xc_proj).downcase.start_with?(xcode_workspace_name)
- end
- end
-
- # todo analyze `self.derived_data_dir_for_project` to see if it contains dead code
- # todo assuming this is not dead code, the documentation around derived data for project needs to be updated
-
- if (build_dirs.count == 0)
- msg = ["Unable to find your built app."]
- msg << "This means that Calabash can't automatically launch iOS simulator."
- msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
- msg << ""
- msg << "To fix there are a couple of options:\n"
- msg << "Option 1) Make sure you are running this command from your project directory, "
- msg << "i.e., the directory containing your .xcodeproj file."
- msg << "In Xcode, build your calabash target for simulator."
- msg << "Check that your app can be found in\n #{File.expand_path("~/Library/Developer/Xcode/DerivedData")}"
- msg << "\n\nOption 2). In features/support/01_launch.rb set APP_BUNDLE_PATH to"
- msg << "the path where Xcode has built your Calabash target."
- msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
- raise msg.join("\n")
-
- elsif (build_dirs.count > 1)
- msg = ["Unable to auto detect APP_BUNDLE_PATH."]
- msg << "You have several projects with the same name: #{xcode_proj_name} in #{DERIVED_DATA}:\n"
- msg << build_dirs.join("\n")
-
- msg << "\nThis means that Calabash can't automatically launch iOS simulator."
- msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
- msg << "\nIn features/support/01_launch.rb set APP_BUNDLE_PATH to"
- msg << "the path where Xcode has built your Calabash target."
- msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
- raise msg.join("\n")
+ unless ENV['CALABASH_NO_DEPRECATION'] == '1'
+ if RUBY_VERSION < '2.0'
+ stack = Kernel.caller()[1..6].join("\n")
else
- if FULL_CONSOLE_OUTPUT
- puts "Found potential build dir: #{build_dirs.first}"
- puts "Checking..."
- end
- return build_dirs.first
+ stack = Kernel.caller(0, 6)[1..-1].join("\n")
end
- end
- end
- def self.project_dir
- File.expand_path(ENV['PROJECT_DIR'] || Dir.pwd)
- end
+ msgs = ['The Calabash::Cucumber::SimulatorHelper module has been replaced.',
+ 'Please replace:',
+ '',
+ ' Calabash::Cucumber::SimulatorHelper.stop',
+ '',
+ 'with this:',
+ '',
+ ' launcher = Calabash::Cucumber::Launcher.new',
+ ' launcher.simulator_launcher.stop',
+ '',
+ 'The stack trace below will show you the line number you need to change.']
- def self.detect_app_bundle(path=nil,device_build_dir='iPhoneSimulator')
- begin
- app_bundle_or_raise(path,device_build_dir)
- rescue =>e
- nil
- end
- end
+ msg = "deprecated '0.9.169' - #{msgs.join("\n")}\n#{stack}"
- def self.app_bundle_or_raise(path=nil, device_build_dir='iPhoneSimulator')
- bundle_path = nil
- path = File.expand_path(path) if path
-
- if path and not File.directory?(path)
- raise "Unable to find .app bundle at #{path}. It should be an .app directory."
- elsif path
- bundle_path = path
- elsif xamarin_project?
- bundle_path = bundle_path_from_xamarin_project(device_build_dir)
- unless bundle_path
- msg = ["Detected Xamarin project, but did not detect built app linked with Calabash"]
- msg << "You should build your project from Xamarin Studio"
- msg << "Make sure you build for Simulator and that you're using the Calabash components"
- raise msg.join("\n")
+ begin
+ STDERR.puts "\033[34m\nWARN: #{msg}\033[0m"
+ rescue
+ STDERR.puts "\nWARN: #{msg}"
end
- if FULL_CONSOLE_OUTPUT
- puts("-"*37)
- puts "Auto detected APP_BUNDLE_PATH:\n\n"
-
- puts "APP_BUNDLE_PATH=#{preferred_dir || sim_dirs[0]}\n\n"
- puts "Please verify!"
- puts "If this is wrong please set it as APP_BUNDLE_PATH in features/support/01_launch.rb\n"
- puts("-"*37)
- end
- else
- dd_dir = derived_data_dir_for_project
- sim_dirs = Dir.glob(File.join(dd_dir, "Build", "Products", "*-iphonesimulator", "*.app"))
- if sim_dirs.empty?
- msg = ["Unable to auto detect APP_BUNDLE_PATH."]
- msg << "Have you built your app for simulator?"
- msg << "Searched dir: #{dd_dir}/Build/Products"
- msg << "Please build your app from Xcode"
- msg << "You should build the -cal target."
- msg << ""
- msg << "Alternatively, specify APP_BUNDLE_PATH in features/support/01_launch.rb"
- msg << "This should point to the location of your built app linked with calabash.\n"
- raise msg.join("\n")
- end
- preferred_dir = find_preferred_dir(sim_dirs)
- if preferred_dir.nil?
- msg = ["Error... Unable to find APP_BUNDLE_PATH."]
- msg << "Cannot find a built app that is linked with calabash.framework"
- msg << "Please build your app from Xcode"
- msg << "You should build your calabash target."
- msg << ""
- msg << "Alternatively, specify APP_BUNDLE_PATH in features/support/01_launch.rb"
- msg << "This should point to the location of your built app linked with calabash.\n"
- raise msg.join("\n")
- end
- if FULL_CONSOLE_OUTPUT
- puts("-"*37)
- puts "Auto detected APP_BUNDLE_PATH:\n\n"
-
- puts "APP_BUNDLE_PATH=#{preferred_dir || sim_dirs[0]}\n\n"
- puts "Please verify!"
- puts "If this is wrong please set it as APP_BUNDLE_PATH in features/support/01_launch.rb\n"
- puts("-"*37)
- end
- bundle_path = sim_dirs[0]
end
- bundle_path
- end
-
- def self.xamarin_project?
- xamarin_ios_csproj_path != nil
- end
-
- def self.xamarin_ios_csproj_path
- solution_path = Dir['*.sln'].first
- if solution_path
- project_dir = Dir.pwd
- else
- solution_path = Dir[File.join('..','*.sln')].first
- project_dir = File.expand_path('..') if solution_path
- end
- return nil unless project_dir
-
- ios_project_dir = Dir[File.join(project_dir,'*.iOS')].first
- return ios_project_dir if ios_project_dir && File.directory?(ios_project_dir)
- # ios_project_dir does not exist
- # Detect case where there is no such sub directory
- # (i.e. iOS only Xamarin project)
- bin_dir = File.join(project_dir, 'bin')
- if xamarin_ios_bin_dir?(bin_dir)
- return project_dir ## Looks like iOS bin dir is here
- end
-
- sub_dirs = Dir[File.join(project_dir,'*')].select {|dir| File.directory?(dir)}
-
- sub_dirs.find do |sub_dir|
- contains_csproj = Dir[File.join(sub_dir,'*.csproj')].first
- contains_csproj && xamarin_ios_bin_dir?(File.join(sub_dir,'bin'))
- end
-
- end
-
- def self.xamarin_ios_bin_dir?(bin_dir)
- File.directory?(bin_dir) &&
- (File.directory?(File.join(bin_dir,'iPhoneSimulator')) ||
- File.directory?(File.join(bin_dir,'iPhone')))
- end
-
- def self.bundle_path_from_xamarin_project(device_build_dir='iPhoneSimulator')
- ios_project_path = xamarin_ios_csproj_path
- conf_glob = File.join(ios_project_path,'bin',device_build_dir,'*')
- built_confs = Dir[conf_glob]
-
- calabash_build = built_confs.find {|path| File.basename(path) == 'Calabash'}
- debug_build = built_confs.find {|path| File.basename(path) == 'Debug'}
-
- bundle_path = [calabash_build, debug_build, *built_confs].find do |path|
- next unless path && File.directory?(path)
- app_dir = Dir[File.join(path,'*.app')].first
- app_dir && linked_with_calabash?(app_dir)
- end
-
- Dir[File.join(bundle_path,'*.app')].first if bundle_path
- end
-
- def self.linked_with_calabash?(d)
- skipped_formats = [".png", ".jpg", ".jpeg", ".plist", ".nib", ".lproj"]
- dir = File.expand_path(d)
-
- # For every file on that .app directory
- Dir.entries(d).each do |file|
- # If this is an asset or any of those skipped formats, skip it.
- next if skipped_formats.include? File.extname(file)
-
- # If its not, try to run otool against that file, check whether we are linked against calabash framework.
- out = `otool #{dir}/#{file} -o 2> /dev/null | grep CalabashServer`
- return true if /CalabashServer/.match(out)
- end
-
- # Defaulted to false
- false
- end
-
- def self.find_preferred_dir(sim_dirs)
- sim_dirs.find do |d|
- linked_with_calabash?(d)
- end
- end
-
- def self.ensure_connectivity(app_bundle_path, sdk, version, args = nil)
- begin
- max_retry_count = (ENV['MAX_CONNECT_RETRY'] || DEFAULT_SIM_RETRY).to_i
- timeout = (ENV['CONNECT_TIMEOUT'] || DEFAULT_SIM_WAIT).to_i
- retry_count = 0
- connected = false
-
- if FULL_CONSOLE_OUTPUT
- puts "Waiting at most #{timeout} seconds for simulator (CONNECT_TIMEOUT)"
- puts "Retrying at most #{max_retry_count} times (MAX_CONNECT_RETRY)"
- end
-
- until connected do
- raise "MAX_RETRIES" if retry_count == max_retry_count
- retry_count += 1
- if FULL_CONSOLE_OUTPUT
- puts "(#{retry_count}.) Start Simulator #{sdk}, #{version}, for #{app_bundle_path}"
- end
- begin
- Timeout::timeout(timeout, TimeoutErr) do
- simulator = launch(app_bundle_path, sdk, version, args)
- until connected
- begin
- connected = (ping_app == '405')
- if connected
- server_version = get_version
- if server_version
- if FULL_CONSOLE_OUTPUT
- p server_version
- end
- unless version_check(server_version)
- msgs = ["You're running an older version of Calabash server with a newer client",
- "Client:#{Calabash::Cucumber::VERSION}",
- "Server:#{server_version}",
- "Minimum server version #{Calabash::Cucumber::FRAMEWORK_VERSION}",
- "Update recommended:",
- "https://github.com/calabash/calabash-ios/wiki/B1-Updating-your-Calabash-iOS-version"
- ]
- raise msgs.join("\n")
- end
- else
- connected = false
- end
- end
- rescue Exception => e
-
- ensure
- sleep 1 unless connected
- end
- end
- end
- rescue TimeoutErr => e
- puts 'Timed out... Retrying'
- stop
- end
- end
- rescue RuntimeError => e
- p e
- msg = "Unable to make connection to Calabash Server at #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}\n"
- msg << "Make sure you've' linked correctly with calabash.framework and set Other Linker Flags.\n"
- msg << "Make sure you don't have a firewall blocking traffic to #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}.\n"
- raise msg
- end
- end
-
-
- def self.launch(app_bundle_path, sdk, version, args = nil)
- simulator = SimLauncher::Simulator.new
- simulator.launch_ios_app(app_bundle_path, sdk, version)
+ simulator = SimLauncher::Simulator.new()
+ simulator.quit_simulator
simulator
end
- def self.ping_app
- url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
- if FULL_CONSOLE_OUTPUT
- puts "Ping #{url}..."
- end
- http = Net::HTTP.new(url.host, url.port)
- res = http.start do |sess|
- sess.request Net::HTTP::Get.new url.path
- end
- status = res.code
- begin
- http.finish if http and http.started?
- rescue
-
- end
- status
- end
-
- def self.get_version
- endpoint = ENV['DEVICE_ENDPOINT']|| "http://localhost:37265"
- endpoint += "/" unless endpoint.end_with? "/"
- url = URI.parse("#{endpoint}version")
-
- if FULL_CONSOLE_OUTPUT
- puts "Fetch version #{url}..."
- end
- begin
- body = Net::HTTP.get_response(url).body
- res = JSON.parse(body)
- if res['iOS_version']
- @ios_version = res['iOS_version']
- end
- res
- rescue
- nil
- end
- end
-
- def self.ios_version
- unless @ios_version
- get_version
- end
- @ios_version
- end
-
- def self.ios_major_version
- v = ios_version
- if v
- v.split(".")[0]
- end
- end
-
- def self.version_check(version)
- server_version = version["version"]
- Calabash::Cucumber::FRAMEWORK_VERSION == server_version
- end
end
-
end
end