Class: Calabash::Cucumber::SimulatorLauncher

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/calabash-cucumber/launch/simulator_launcher.rb

Overview

acts as a bridge to the sim_launcher SimLauncher and SdkDetector classes

Defined Under Namespace

Classes: TimeoutErr

Constant Summary collapse

DERIVED_DATA =

the file path to the default Xcode DerivedData directory

File.expand_path('~/Library/Developer/Xcode/DerivedData')
DEFAULT_DERIVED_DATA_INFO =

REGEX for finding application Info.plist

File.expand_path("#{DERIVED_DATA}/*/info.plist")
DEFAULT_SIM_WAIT =

if CONNECT_TIMEOUT is not set, wait this long for the app to launch in the simulator before retrying

30
DEFAULT_SIM_RETRY =

if MAX_CONNECT_RETRY is not set, try to launch the app this many times in the simulator before giving up

2

Constants included from Logging

Logging::CALABASH_NO_DEPRECATION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#_deprecated, #calabash_info, #calabash_warn, #debug_logging?, #full_console_logging?, #no_deprecation_warnings?

Constructor Details

#initializeSimulatorLauncher

creates a new instance an sets the :simulator and :sdk_detector attributes



48
49
50
51
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 48

def initialize
  @simulator = SimLauncher::Simulator.new
  @sdk_detector = SimLauncher::SdkDetector.new()
end

Instance Attribute Details

#deviceObject

an instance of Calabash::Cucumber::Device



35
36
37
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 35

def device
  @device
end

#launch_argsObject

the launch args passed from Calabash::Cucumber::Launcher to the launch and relaunch methods.



45
46
47
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 45

def launch_args
  @launch_args
end

#sdk_detectorObject

an instance of SimLauncher::SdkDetector



41
42
43
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 41

def sdk_detector
  @sdk_detector
end

#simulatorObject

an instance of SimLauncher::Simulator



38
39
40
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 38

def simulator
  @simulator
end

Instance Method Details

#app_bundle_or_raise(path = nil, device_build_dir = 'iPhoneSimulator') ⇒ String

attempts to deduce the path the to the app bundle (.app) todo methods should not use 2 optional arguments

Parameters:

  • path (String) (defaults to: nil)

    NEEDS DOCUMENTATION

  • device_build_dir (String) (defaults to: 'iPhoneSimulator')

    NEEDS DOCUMENTATION

Returns:

  • (String)

    absolute path to app bundle (.app)

Raises:

  • (RuntimeError)

    if app bundle (.app) cannot be found



166
167
168
169
170
171
172
173
174
175
176
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 166

def app_bundle_or_raise(path=nil, device_build_dir='iPhoneSimulator')
  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")
    end
    if full_console_logging?
      puts('-'*37)
      puts "Auto detected APP_BUNDLE_PATH:\n\n"

      puts "APP_BUNDLE_PATH= '#{bundle_path}'\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_logging?
      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

#bundle_path_from_xamarin_project(device_build_dir = 'iPhoneSimulator') ⇒ String?

attempts to deduce the path to the app bundle path (*.app) using heuristics and checking for executables linked with the Calabash server

Parameters:

  • device_build_dir (String) (defaults to: 'iPhoneSimulator')

    NEEDS DOCUMENTATION

Returns:

  • (String)

    absolute path the app bundle .app

  • (nil)

    iff the app bundle cannot be found



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 285

def 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

#derived_data_dir_for_projectString

uses heuristics to deduce the derived data directory for the project so the path to the app bundle (.app) can be detected.

Returns:

  • (String)

    absolute path to derived data directory

Raises:

  • (RuntimeError)

    if the derived data directory cannot be found



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 57

def 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
  }

  return File.dirname(info_plist) unless info_plist.nil?

  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 `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 #{DERIVED_DATA}"
    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")
  else
    if full_console_logging?
      puts "Found potential build dir: #{build_dirs.first}"
      puts 'Checking...'
    end
    build_dirs.first
  end
end

#detect_app_bundle(path = nil, device_build_dir = 'iPhoneSimulator') ⇒ String?

attempts to deduce the app bundle path todo methods should not use 2 optional arguments

Parameters:

  • path (String) (defaults to: nil)

    NEEDS DOCUMENTATION

  • device_build_dir (String) (defaults to: 'iPhoneSimulator')

    NEEDS DOCUMENTATION

Returns:

  • (String)

    absolute path to app bundle (.app)

  • (nil)

    iff app bundle cannot be found



152
153
154
155
156
157
158
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 152

def detect_app_bundle(path=nil,device_build_dir='iPhoneSimulator')
  begin
    app_bundle_or_raise(path,device_build_dir)
  rescue
    nil
  end
end

#ensure_connectivity(app_bundle_path, sdk, device_family, args = nil) ⇒ Object

attempts to connect to launch the app and connect to the embedded calabash server.

to change the number of times launching is attempted set MAX_CONNECT_RETRY

to change the relaunch timeout set CONNECT_TIMEOUT

todo nearly a duplicate of Launcher ensure_connectivity todo args was originally intended to be the args passed to the application @ launch

Parameters:

  • app_bundle_path (String)

    path to the .app that should be launched

  • sdk (String)

    6.0.3, 6.1. if nil latest SDK will be used

  • device_family (String)

    | ipad

  • args (Hash) (defaults to: nil)

    eke! not used (see todo)

Raises:

  • (TimeoutErr)

    if app cannot be launched in the simulator



392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 392

def ensure_connectivity(app_bundle_path, sdk, device_family, args = nil)
  begin
    # todo should get the retry could from the args
    # todo should migrate MAX_CONNECT_RETRY to environment_helpers
    max_retry_count = (ENV['MAX_CONNECT_RETRY'] || DEFAULT_SIM_RETRY).to_i
    # todo should get the timeout from the args
    # todo should migrate CONNECT_TIMEOUT to environment helpers
    timeout = (ENV['CONNECT_TIMEOUT'] || DEFAULT_SIM_WAIT).to_i
    retry_count = 0
    connected = false

    if full_console_logging?
      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_logging?
        puts "(#{retry_count}.) Start Simulator #{sdk}, #{device_family}, for #{app_bundle_path}"
      end
      begin
        Timeout::timeout(timeout, TimeoutErr) do
          launch(app_bundle_path, sdk, device_family, args)
          until connected
            begin
              connected = (ping_app == '200')
              break if connected
            rescue Exception => e
              # nop
            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

#find_preferred_dir(sim_dirs) ⇒ String?

todo find_preferred_dir is a bad name - preferred for what? todo sim_dirs arg is a bad name - we can be iterating over any directory

Parameters:

  • sim_dirs (Array<String>)

    eke! why sim_dirs? why not a list of any directories?

Returns:

  • (String)

    the first path in sim_dirs that contains a binary linked with Calabash server

  • (nil)

    iff there is no path in sim_dirs that contains a binary linked with Calabash server



332
333
334
335
336
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 332

def find_preferred_dir(sim_dirs)
  sim_dirs.find do |d|
    linked_with_calabash?(d)
  end
end

#get_versionObject

Deprecated.

Calabash::Cucumber::Launcher.launcher.device instance methods

Raises:

  • (NotImplementedError)

    no longer implemented

Since:

  • 0.9.169



500
501
502
503
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 500

def get_version
  _deprecated('0.9.169', 'use an instance Device class instead', :warn)
  raise(NotImplementedError, 'this method has been deprecated')
end

#ios_major_versionObject

Deprecated.

use Calabash::Cucumber::Launcher.launcher.ios_major_version

Raises:

  • (NotImplementedError)

    no longer implemented

Since:

  • 0.9.169



516
517
518
519
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 516

def ios_major_version
  _deprecated('0.9.169', 'use an instance Device class instead', :warn)
  raise(NotImplementedError, 'this method has been deprecated')
end

#ios_versionObject

Deprecated.

Calabash::Cucumber::Launcher.launcher.device instance methods

Raises:

  • (NotImplementedError)

    no longer implemented

Since:

  • 0.9.169



508
509
510
511
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 508

def ios_version
  _deprecated('0.9.169', 'use an instance Device class instead', :warn)
  raise(NotImplementedError, 'this method has been deprecated')
end

#launch(app_bundle_path, sdk, device_family, args = nil) ⇒ Object

launches the app todo args was originally intended to be the args passed to the application @ launch

Parameters:

  • app_bundle_path (String)

    path to the .app that should be launched

  • sdk (String)

    6.0.3, 6.1. if nil latest SDK will be used

  • device_family (String)

    | ipad

  • args (Hash) (defaults to: nil)

    eke! not used (see todo)



448
449
450
451
452
453
454
455
456
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 448

def launch(app_bundle_path, sdk, device_family, args = nil)
  # cached but not used
  self.launch_args = args
  # launch arguments (eg. -NSShowNonLocalizedStrings) are not being passed
  # to sim_launcher
  # https://github.com/calabash/calabash-ios/issues/363
  self.simulator.launch_ios_app(app_bundle_path, sdk, device_family)
  simulator
end

#linked_with_calabash?(d) ⇒ Boolean

searches d for a file linked with Calabash server todo why are we not grep’ing for executable files? see server_version_from_bundle

Parameters:

  • d (String)

    path to a directory

Returns:

  • (Boolean)

    true iff there is a file that is linked with the Calabash server



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 307

def 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

#ping_appString

ping the version route of the calabash server embedded in the app

has the side effect of setting self.device attribute if successful

todo migrate DEVICE_ENDPOINT to environment_helpers todo migrate CALABASH_VERSION_PATH to environment_helpers todo this is an exact duplicate of Launcher ping method

Returns:

  • (String)

    returns the server status - ‘200’ is a success



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 347

def ping_app
  url = URI.parse(ENV['DEVICE_ENDPOINT']|| 'http://localhost:37265/')
  if full_console_logging?
    puts "Ping #{url}..."
  end

  http = Net::HTTP.new(url.host, url.port)
  res = http.start do |sess|
    # noinspection RubyResolve
    sess.request Net::HTTP::Get.new(ENV['CALABASH_VERSION_PATH'] || 'version')
  end

  status = res.code
  begin
    http.finish if http and http.started?
  rescue
    # nop
  end

  if status == '200'
    version_body = JSON.parse(res.body)
    self.device = Calabash::Cucumber::Device.new(url, version_body)
  end

  if full_console_logging?
    puts "ping status = '#{status}'"
  end
  status
end

#project_dirString

returns the absolute path to the project directory unless PROJECT_DIR is defined, returns the absolute path to the current directory todo migrate PROJECT_DIR to environment_helpers.rb

Returns:

  • (String)

    absolute path to the project directory



142
143
144
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 142

def project_dir
  File.expand_path(ENV['PROJECT_DIR'] || Dir.pwd)
end

#relaunch(app_path, sdk, args) ⇒ Object

relaunches the app at app_path in the simulator using sdk and args

todo args was originally intended to be the args passed to the application @ launch todo it is very likely that args == app_path so we might be able to eliminate an argument

Parameters:

  • app_path (String)

    the path to the .app

  • sdk (String)

    eg. 6.0.3, 6.1

  • args (Hash)

    the only option we are interested in is :device



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 467

def relaunch(app_path, sdk, args)
  app_bundle_path = app_bundle_or_raise(app_path)

  if sdk.nil?
    # iOS 7 requires launching with instruments, so we _must_ launch with
    # the first SDK that is _not_ iOS 7
    _sdk = self.sdk_detector.available_sdk_versions.reverse.find { |x| !x.start_with?('7') }
  else
    # use SDK_VERSION to specify a different version
    # as of Xcode 5.0.2, the min supported simulator version is iOS 6
    _sdk = sdk
  end

  if args[:device]
    device_family = args[:device].to_s
  else
    device_family = 'iphone'
  end

  self.launch_args = args

  ensure_connectivity(app_bundle_path, _sdk, device_family, args)
end

#stopObject

stops (quits) the simulator



492
493
494
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 492

def stop
  self.simulator.quit_simulator
end

#version_check(version) ⇒ Object

Deprecated.

version checking is done in Launcher

Raises:

  • (NotImplementedError)

    no longer implemented

Since:

  • 0.9.169



527
528
529
530
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 527

def version_check(version)
  _deprecated('0.9.169', 'check is now done in Launcher', :warn)
  raise(NotImplementedError, 'this method has been deprecated and will be removed')
end

#xamarin_ios_bin_dir?(bin_dir) ⇒ Boolean

is this the Xamarin iOS bin directory?

Returns:

  • (Boolean)

    true iff this is the Xamarin iOS bin directory



273
274
275
276
277
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 273

def 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

#xamarin_ios_csproj_pathString

path to the Xamarin IDE project

Returns:

  • (String)

    absolute path to the Xamarin IDE project



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 237

def xamarin_ios_csproj_path
  solution_path = Dir['*.sln'].first

  project_dir = nil
  if solution_path
    project_dir = Dir.pwd
  else
    solution_path = Dir[File.join('..','*.sln')].first
    if solution_path
      project_dir = File.expand_path('..')
    end
  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

#xamarin_project?Boolean

is this a Xamarin IDE project?

Returns:

  • (Boolean)

    true iff the project is a Xamarin IDE project



231
232
233
# File 'lib/calabash-cucumber/launch/simulator_launcher.rb', line 231

def xamarin_project?
  xamarin_ios_csproj_path != nil
end