testautoi 0.9.127 → 0.9.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/CalabashSetup CHANGED
Binary file
@@ -0,0 +1,5 @@
1
+ UIATarget.localTarget().delay(1);
2
+ var textField = UIATarget.localTarget().frontMostApp().mainWindow().textFields()[1].value();
3
+ UIATarget.localTarget().host().performTaskWithPathArgumentsTimeout("/usr/bin/sed", ["-i", "", "s/^IPAddress=.*$/IPAddress="+ textField +"/1", "./Device.cfg"], 2);
4
+
5
+
data/bin/LaunchApp.js ADDED
@@ -0,0 +1,5 @@
1
+ UIATarget.localTarget().delay(1);
2
+ var textField = UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0].setValue("[%app%]");
3
+ UIATarget.localTarget().frontMostApp().mainWindow().buttons()[0].tap();
4
+
5
+
@@ -44,28 +44,14 @@ def build(options={:build_dir=>"Calabash",
44
44
  res
45
45
  end
46
46
 
47
- def console(options={:script => "irb_ios5.sh"})
48
- path = File.join(@source_dir,".irbrc")
49
- if File.exists?(".irbrc")
50
- old_str = File.read(".irbrc")
51
- new_str = File.read(path)
52
- if old_str != new_str
53
- puts "Moving old .irbrc file to .irbrc.old"
54
- FileUtils.mv(".irbrc", ".irbrc.old")
55
- puts "Copying calabash-ios .irbrc file to current directory..."
56
- FileUtils.cp(path, ".")
57
- end
58
- else
59
- puts "Copying calabash-ios .irbrc file to current directory..."
60
- FileUtils.cp(path, ".")
61
- end
62
-
63
- if !File.exists?(options[:script])
64
- puts "Copying calabash-ios #{options[:script]} file to current directory..."
65
- FileUtils.cp(File.join(@source_dir,options[:script]), ".")
47
+ def console
48
+ path = ENV['CALABASH_IRBRC']
49
+ unless path
50
+ path = File.expand_path(File.join(@script_dir,".irbrc"))
51
+ ENV['IRBRC'] = path
66
52
  end
67
- puts "Running irb with ./.irbrc..."
68
- system("./#{options[:script]}")
53
+ puts "Running irb..."
54
+ exec("irb")
69
55
  end
70
56
 
71
57
 
@@ -13,9 +13,6 @@ def calabash_scaffold
13
13
  exit 2 unless STDIN.gets.chomp == ''
14
14
 
15
15
  FileUtils.cp_r(@source_dir, @features_dir)
16
- FileUtils.mv "#{@features_dir}/.irbrc", "."
17
- FileUtils.mv "#{@features_dir}/irb_ios4.sh", "."
18
- FileUtils.mv "#{@features_dir}/irb_ios5.sh", "."
19
16
 
20
17
  msg("Info") do
21
18
  puts "Features subdirectory created. \n"
@@ -174,28 +174,25 @@ def setup_project(project_name, project_path, path)
174
174
  exit 1
175
175
  end
176
176
 
177
- pwd = FileUtils.pwd
178
- FileUtils.cd project_path
179
- ##Backup
180
- if File.exists? "#{proj_file}.bak"
181
- msg("Error") do
182
- puts "Backup file already exists. #{proj_file}.bak"
183
- puts "For safety, I won't overwrite this file."
184
- puts "You must manually move this file, if you want to"
185
- puts "Run calabash-ios setup again."
177
+ FileUtils.cd project_path do
178
+ ##Backup
179
+ if File.exists? "#{proj_file}.bak"
180
+ msg("Error") do
181
+ puts "Backup file already exists. #{proj_file}.bak"
182
+ puts "For safety, I won't overwrite this file."
183
+ puts "You must manually move this file, if you want to"
184
+ puts "Run calabash-ios setup again."
185
+ end
186
+ exit 1
186
187
  end
187
- exit 1
188
188
  end
189
189
 
190
- file = download_calabash(project_path)
190
+ download_calabash(project_path)
191
191
 
192
192
  msg("Info") do
193
193
  puts "Setting up project file for calabash-ios."
194
194
  end
195
195
 
196
-
197
- FileUtils.cd pwd
198
-
199
196
  ##Backup
200
197
  msg("Info") do
201
198
  puts "Making backup of project file: #{proj_file}"
data/bin/devicedetect ADDED
Binary file
data/bin/fruitstrap ADDED
Binary file
data/bin/testautoi ADDED
@@ -0,0 +1,643 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+ require 'json'
5
+ require 'tmpdir'
6
+ require 'zip/zip'
7
+ require 'uri'
8
+
9
+ require File.join(File.dirname(__FILE__),"calabash-ios-sim")
10
+
11
+ @settings_file = File.join(FileUtils.pwd, ".testautoi_settings")
12
+
13
+ def print_usage
14
+ puts <<EOF
15
+ Usage: testautoi <command-name> [parameters] [options]
16
+ <command-name> can be one of
17
+ setup
18
+ Set up test automation configurations
19
+ run
20
+ Start test automation
21
+ build <Source Dir>
22
+ Build the instrumented app.
23
+ Use getsource command first to download source to <Source Dir>
24
+ install
25
+ Install the app
26
+ install tools
27
+ Download and install tools from Subversion.
28
+ launch
29
+ Launch the app
30
+ getip
31
+ Get the device's IP address
32
+ gen
33
+ Generate the skeleton of features directory
34
+ sim run
35
+ Start an iOS Simulator
36
+ sim quit
37
+ Quit the iOS Simulator
38
+ devices
39
+ List connected iOS Devices
40
+ getsource list
41
+ List of source branches
42
+ getsource <Branch>
43
+ Download a branch of app source
44
+ getsouce trunk
45
+ Download the trunk of app source
46
+ getbuild list
47
+ List available builds in the build drop
48
+ getbuild <Version>
49
+ Download the build with <Version>.
50
+ getbuild trunk
51
+ Download the trunk build
52
+ getscript list
53
+ List available scripts
54
+ getscript <Script>
55
+ Download the specified script
56
+ record start
57
+ Start recording
58
+ record stop
59
+ Stop recording
60
+ version
61
+ prints the gem version
62
+
63
+ <options> can be
64
+ -v, --verbose
65
+ Turns on verbose logging
66
+ EOF
67
+ end
68
+
69
+ def is_windows?
70
+ (RUBY_PLATFORM =~ /mswin|mingw|cygwin/)
71
+ end
72
+
73
+ def get_ip_from_device_cfg
74
+ IO.read("Device.cfg").scan(/^IPAddress=(\S*)$/)[0][0]
75
+ end
76
+
77
+ def gen
78
+ STDOUT.sync = true
79
+ cmd = "calabash-ios gen"
80
+ result = system(cmd)
81
+ sleep(1)
82
+ result
83
+ end
84
+
85
+ def run(option)
86
+ app_bundle = @settings["app_bundle"].to_s.strip
87
+ app_bundle_id = app_bundle_id(File.join(FileUtils.pwd, app_bundle))
88
+ app_url = app_bundle_url_schemes(File.join(FileUtils.pwd, app_bundle))
89
+ device_ipaddr = @settings["device_ipaddr"].to_s.strip
90
+ device_udid = @settings["device_udid"].to_s.strip
91
+ STDOUT.sync = true
92
+ arguments = ARGV
93
+ if option == 'console'
94
+ cmd = "calabash-ios console"
95
+ else
96
+ cmd = "cucumber #{arguments.join(" ")}"
97
+ end
98
+ env = {}
99
+ env["APP_BUNDLE_PATH"] = File.join(FileUtils.pwd, app_bundle)
100
+ if device_udid == ''
101
+ # Use Simulator
102
+ else
103
+ env["NO_LAUNCH"] = "1"
104
+ get_device_ip
105
+ if ENV["NO_INSTALL"] != "1"
106
+ uninstall_app(app_bundle_id)
107
+ install_app(File.join(FileUtils.pwd, app_bundle))
108
+ end
109
+ launch_app(app_url)
110
+ sleep(5)
111
+ device_ipaddr = get_ip_from_device_cfg
112
+ end
113
+ if device_ipaddr != ''
114
+ env["DEVICE_ENDPOINT"] = "http://#{device_ipaddr}:37265"
115
+ end
116
+ result = system(env, cmd)
117
+ sleep(1)
118
+ result
119
+ end
120
+
121
+ def setup
122
+ read_settings
123
+ puts "Settings for Test Automation"
124
+
125
+ ask_for_setting("svn_location", "Please enter svn location of test source", @settings["svn_location"])
126
+ ask_for_setting("svn_location_tools", "Please enter svn location of tools", @settings["svn_location_tools"])
127
+ ask_for_setting("svn_location_app", "Please enter svn location of app source", @settings["svn_location_app"])
128
+ ask_for_setting("svn_username", "Please enter svn username", @settings["svn_username"])
129
+ ask_for_setting("svn_password", "Please enter svn password", @settings["svn_password"])
130
+
131
+ ask_for_setting("build_drop_location", "Please enter build drop location", @settings["build_drop_location"])
132
+ ask_for_setting("build_drop_username", "Please enter the username", @settings["build_drop_username"])
133
+ ask_for_setting("build_drop_password", "Please enter the password", @settings["build_drop_password"])
134
+
135
+ ask_for_setting("app_bundle", "Please enter the name of app bundle", @settings["app_bundle"])
136
+ ask_for_setting("device_udid", "Please enter the unique device ID of the device", @settings["device_udid"])
137
+
138
+ @settings["build_drop_branch_dir"] = "Mobile/iPhone/branch"
139
+ @settings["build_drop_trunk_dir"] = "Mobile/iPhone/trunk"
140
+
141
+ open(@settings_file, 'w') do |f|
142
+ f.puts @settings.to_json
143
+ end
144
+ puts "Saved your settings to #{@settings_file}. You can edit the settings manually or run this setup script again"
145
+ end
146
+
147
+ def ask_for_setting(key, msg, def_value)
148
+ puts (def_value.to_s.empty? ? msg : "#{msg} (#{def_value})")
149
+ input = STDIN.gets.chomp
150
+ if input.empty?
151
+ @settings[key] = def_value
152
+ elsif input.strip.empty?
153
+ @settings[key] = ''
154
+ else
155
+ @settings[key] = input
156
+ end
157
+ end
158
+
159
+ def read_settings
160
+ if File.exist? @settings_file
161
+ @settings = JSON.parse(IO.read(@settings_file))
162
+ else
163
+ @settings = {}
164
+ end
165
+ end
166
+
167
+ def smb_connect_win(location,username,password)
168
+ mount_node = location.tr('/', '\\')
169
+ username = username.tr('/', '\\')
170
+
171
+ cmd = "net use"
172
+ output=`#{cmd}` ; result=$?.success?
173
+
174
+ if output.include?(mount_node)
175
+ cmd = "net use #{mount_node} /delete"
176
+ output=`#{cmd}` ; result=$?.success?
177
+ end
178
+
179
+ cmd = "net use #{mount_node} #{password} /user:#{username}"
180
+ output=`#{cmd}` ; result=$?.success?
181
+ raise "the command '#{cmd}' failed" if result == false
182
+
183
+ mount_node
184
+ end
185
+
186
+ def smb_disconnect_win(mount_node)
187
+ cmd = "net use #{mount_node} /delete"
188
+ output=`#{cmd}` ; result=$?.success?
189
+ end
190
+
191
+ def smb_connect_mac(location,username,password)
192
+ # create mount node
193
+ mount_node = "/Volumes/build_drop_temp"
194
+ if File.exists?(mount_node)
195
+ cmd = "umount #{mount_node}"
196
+ output=`#{cmd}` ; result=$?.success?
197
+ FileUtils.rm_rf(mount_node) if result == false
198
+ end
199
+ cmd = "mkdir #{mount_node}"
200
+ output=`#{cmd}` ; result=$?.success?
201
+ raise "the command '#{cmd}' failed" if result == false
202
+
203
+ # mount smbfs
204
+ location = location.tr('\\','/')
205
+ username = username.tr('\\',';').tr('/',';')
206
+ raise "The build drop location is incorrect" if not location.start_with?("//")
207
+ cmd = "mount -t smbfs //'#{username}':#{password}@#{location[2..-1]} #{mount_node}"
208
+ output=`#{cmd}` ; result=$?.success?
209
+ raise "the command '#{cmd}' failed" if result == false
210
+ mount_node
211
+ end
212
+
213
+ def smb_disconnect_mac(mount_node)
214
+ # unmount fs
215
+ cmd = "umount -f #{mount_node}"
216
+ output=`#{cmd}` ; result=$?.success?
217
+ raise "the command '#{cmd}' failed" if result == false
218
+ end
219
+
220
+ def smb_connect(location,username,password)
221
+ if is_windows?
222
+ smb_connect_win(location,username,password)
223
+ else
224
+ smb_connect_mac(location,username,password)
225
+ end
226
+ end
227
+
228
+ def smb_disconnect(mount_node)
229
+ if is_windows?
230
+ smb_disconnect_win(mount_node)
231
+ else
232
+ smb_disconnect_mac(mount_node)
233
+ end
234
+ end
235
+
236
+ def unzip_file (file, destination)
237
+ Zip::ZipFile.open(file) { |zip_file|
238
+ zip_file.each { |f|
239
+ f_path=File.join(destination, f.name)
240
+ FileUtils.mkdir_p(File.dirname(f_path))
241
+ zip_file.extract(f, f_path){ true }
242
+ }
243
+ }
244
+ end
245
+
246
+ def get_build
247
+ mount_node = smb_connect(@settings["build_drop_location"],
248
+ @settings["build_drop_username"],
249
+ @settings["build_drop_password"])
250
+ if ARGV.first == 'list'
251
+ # list build versions
252
+ branch_path = File.join(mount_node, @settings["build_drop_branch_dir"])
253
+ Dir.entries(branch_path).sort_by{|c| File.stat(File.join(branch_path,c)).ctime}.each do |d|
254
+ m = d.match(/^iPhone(\S+)$/)
255
+ if m != nil
256
+ puts m[1]
257
+ end
258
+ end
259
+ else
260
+ app_bundle = @settings["app_bundle"]
261
+ version = ARGV.shift
262
+ sim = (ARGV.shift == 'sim')?"Emulator":"Device"
263
+ if version == 'trunk'
264
+ # copy the trunk build
265
+ release_path = File.join(mount_node, @settings["build_drop_trunk_dir"], "ConcurMobile", sim)
266
+ else
267
+ # copy the version build
268
+ release_path = File.join(mount_node, @settings["build_drop_branch_dir"], "iPhone#{version}", "ConcurMobile", sim, "Release")
269
+ end
270
+ build_dir = Dir.entries(release_path).reject{|d|d.start_with?('.')}.sort_by{|c| File.stat(File.join(release_path,c)).ctime}.last
271
+ zip_file = build_dir + ".zip"
272
+ source = File.join(release_path, build_dir, zip_file)
273
+ raise "the file '#{source}' does not exist" if not File.exists?(source)
274
+ dest = File.join(FileUtils.pwd, zip_file)
275
+ FileUtils.copy(source, dest)
276
+ puts "Copy the build from #{source}"
277
+ FileUtils.rm_rf(File.join(FileUtils.pwd, (sim=='Emulator')?"Debug-iphonesimulator":"Release-iphoneos"))
278
+ unzip_file(dest, FileUtils.pwd)
279
+ FileUtils.rm_rf(File.join(FileUtils.pwd, app_bundle))
280
+ FileUtils.cp_r(File.join(FileUtils.pwd, (sim=='Emulator')?"Debug-iphonesimulator":"Release-iphoneos", app_bundle),
281
+ FileUtils.pwd)
282
+ end
283
+
284
+ smb_disconnect(mount_node)
285
+ end
286
+
287
+ def get_script
288
+ svn_location = @settings["svn_location"]
289
+ svn_location += '/' unless svn_location.end_with?('/')
290
+ username = @settings["svn_username"]
291
+ password = @settings["svn_password"]
292
+ uri = URI.join(svn_location, "Mobile/", "BVT/", "CTE/")
293
+
294
+ if ARGV.first == 'list'
295
+ puts `svn list #{uri} --username #{username} --password #{password}`
296
+ else
297
+ feature = ARGV.first
298
+ feature += '/' unless ARGV.first.end_with?('/')
299
+ uri = URI.join(uri, feature)
300
+ puts `svn export --force #{uri} features --username #{username} --password #{password}`
301
+
302
+ #uri = URI.join(@settings["svn_location"], "_support/", "support/")
303
+ #puts `svn export --force #{uri} features/support --username #{username} --password #{password}`
304
+ uri = URI.join(svn_location, "_support/", "step_definition/")
305
+ puts `svn export --force #{uri} features/step_definitions --username #{username} --password #{password}`
306
+ end
307
+ end
308
+
309
+ def get_source
310
+ username = @settings["svn_username"]
311
+ password = @settings["svn_password"]
312
+ location = @settings["svn_location_app"]
313
+ raise "Error: No SVN settings." if username.to_s.empty? or password.to_s.empty? or location.to_s.empty?
314
+ location += '/' unless location.end_with?('/')
315
+ uri_base = URI(location)
316
+
317
+ if ARGV.first == 'list'
318
+ uri = URI.join(uri_base, "branches/")
319
+ output = `svn list #{uri} --username #{username} --password #{password}`
320
+ ios_branches = output.scan(/^(iPhone\S*)$/)
321
+ ios_branches.each {|i| puts i[0]}
322
+ else
323
+ # calabash_setup want Xcode to be closed.
324
+ res = `ps x -o pid,command | grep -v grep | grep Contents/MacOS/Xcode`
325
+ if res != ""
326
+ puts "Xcode is running. We'll be changing the project file so we'd better stop it."
327
+ puts "Please stop XCode and run setup again"
328
+ exit(0)
329
+ end
330
+
331
+ branch = ARGV.first
332
+ branch += '/' unless branch.end_with?('/')
333
+
334
+ # remove the directory if it exists
335
+ FileUtils.rm_rf(File.join(FileUtils.pwd, branch))
336
+
337
+ if branch == 'trunk/'
338
+ uri_iphone = URI.join(uri_base, "trunk/", "iPhone/")
339
+ uri_images = URI.join(uri_base, "trunk/", "images/")
340
+ else
341
+ uri_iphone = URI.join(uri_base, "branches/", branch, "iPhone/")
342
+ uri_images = URI.join(uri_base, "branches/", branch, "images/")
343
+ end
344
+
345
+ # get the source
346
+ system("svn export --force #{uri_iphone} #{branch}iPhone --username #{username} --password #{password}")
347
+ system("svn export --force #{uri_images} #{branch}images --username #{username} --password #{password}")
348
+ setup_target(branch)
349
+ end
350
+ end
351
+
352
+ def setup_target(branch_dir)
353
+ system("echo ConcurMobile|calabash-ios setup #{branch_dir}/iPhone")
354
+ end
355
+
356
+ def fruitstrap_path
357
+ File.join(File.dirname(__FILE__), "fruitstrap")
358
+ end
359
+
360
+ def launcher_path
361
+ File.join(FileUtils.pwd, "tools", "AppLaunch", "AppLaunch.app")
362
+ end
363
+
364
+ def app_bundle_path
365
+ raise "No app bundle setting" if @settings["app_bundle"].to_s.empty?
366
+ File.join(FileUtils.pwd, @settings["app_bundle"])
367
+ end
368
+
369
+ def app_bundle_id(app_bundle)
370
+ plist = CFPropertyList::List.new(:file => File.join(app_bundle, "Info.plist"))
371
+ hash = CFPropertyList.native_types(plist.value)
372
+ hash['CFBundleURLTypes'][0]["CFBundleIdentifier"]
373
+ end
374
+
375
+ def app_bundle_url_schemes(app_bundle)
376
+ plist = CFPropertyList::List.new(:file => File.join(app_bundle, "Info.plist"))
377
+ hash = CFPropertyList.native_types(plist.value)
378
+ hash['CFBundleURLTypes'][0]["CFBundleURLSchemes"][0] + ":"
379
+ end
380
+
381
+ def install_app(app_bundle)
382
+ udid = @settings["device_udid"].to_s.strip
383
+ arg_udid = (udid == "" ? "" : "--id=#{udid}")
384
+ result = system("#{fruitstrap_path} install #{arg_udid} -t 10 --bundle=#{app_bundle}")
385
+ raise "Failed to install the app" if result == false
386
+ end
387
+
388
+ def uninstall_app(app_bundle_id)
389
+ udid = @settings["device_udid"].to_s.strip
390
+ arg_udid = (udid == "" ? "" : "--id=#{udid}")
391
+ result = system("#{fruitstrap_path} uninstall #{arg_udid} -t 10 --bundle-id=#{app_bundle_id}")
392
+ raise "Failed to install the app" if result == false
393
+ end
394
+
395
+ def launch_app(app_url)
396
+ udid = @settings["device_udid"].to_s
397
+ udids = Device.detect
398
+ raise "No device is connected" if udids.length <= 0
399
+ raise "There are two or more devices. Please provide unique device ID." if udids.length > 1 and udid == ''
400
+ if udid == ''
401
+ udid = udids.first
402
+ end
403
+ raise "The device #{udid} is not found." if not udids.include?(udid)
404
+ tracetempl = "/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"
405
+ launcher = "./AppLaunch.app"
406
+ script = 'LaunchApp.js'
407
+ text = File.read(File.join(File.dirname(__FILE__), script))
408
+ File.open(File.join(FileUtils.pwd, script), "w") {|file| file.puts text.gsub(/\[%app%\]/, app_url)}
409
+ script = File.join(FileUtils.pwd, script)
410
+ cmd = `instruments -w #{udid} -t #{tracetempl} #{launcher_path} -e UIASCRIPT #{script}`
411
+ end
412
+
413
+ def get_device_ip
414
+ app_url = app_bundle_url_schemes(app_bundle_path)
415
+ udid = @settings["device_udid"].to_s
416
+ udids = Device.detect
417
+ raise "No device is connected" if udids.length <= 0
418
+ raise "There are two or more devices. Please provide unique device ID." if udids.length > 1 and udid == ''
419
+ if udid == ''
420
+ udid = udids.first
421
+ end
422
+ raise "The device #{udid} is not found." if not udids.include?(udid)
423
+ tracetempl = "/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate"
424
+ launcher = "./AppLaunch.app"
425
+ script = 'GetIPAddress.js'
426
+ text = File.read(File.join(File.dirname(__FILE__), script))
427
+ File.open(File.join(FileUtils.pwd, script), "w") {|file| file.puts text}
428
+ script = File.join(FileUtils.pwd, script)
429
+ File.open(File.join(FileUtils.pwd, "Device.cfg"), "w") {|file| file.puts "IPAddress="}
430
+ cmd = `instruments -w #{udid} -t #{tracetempl} #{launcher_path} -e UIASCRIPT #{script}`
431
+ puts File.read(File.join(FileUtils.pwd, "Device.cfg"))
432
+ end
433
+
434
+ def start_sim
435
+ quit_sim
436
+ pid = spawn("/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\\ Simulator.app/Contents/MacOS/iPhone\\ Simulator")
437
+ end
438
+
439
+ def reset_sim
440
+ calabash_sim_reset
441
+ end
442
+
443
+ class Device
444
+ def self.call_device_detect(udid = nil)
445
+ udid_arg = (udid == nil) ? "" : "-i #{udid}"
446
+ `#{File.join(File.dirname(__FILE__), 'devicedetect')} #{udid_arg}`
447
+ end
448
+
449
+ def self.detect
450
+ udid_array = []
451
+ output = self.call_device_detect
452
+ foundDevReg = /^Found device \(([[:xdigit:]]*)\).*$/
453
+ output.split(/\r?\n/).select{ |i| i =~ foundDevReg }.each{ |foundDev| udid_array << foundDev.match(foundDevReg)[1] }
454
+ udid_array
455
+ end
456
+
457
+ attr_accessor :udid, :name, :wifi_address, :serial_number, :product_version, :product_type, :device_class, :model_number
458
+
459
+ def initialize(udid)
460
+ @udid = udid
461
+ output = self.class.call_device_detect(@udid)
462
+ raise "The device (#{@udid})is not found." if output == ""
463
+ @name = output.match(/^Device Name: (.*)$/)[1]
464
+ @wifi_address = output.match(/^WiFi Address: (.*)$/)[1]
465
+ @serial_number = output.match(/^Serial Number: (.*)$/)[1]
466
+ @product_version = output.match(/^Product Version: (.*)$/)[1]
467
+ @product_type = output.match(/^Product Type: (.*)$/)[1]
468
+ @device_class = output.match(/^Device Class: (.*)$/)[1]
469
+ @model_number = output.match(/^Model Number: (.*)$/)[1]
470
+ end
471
+ end
472
+
473
+ def list_devices
474
+ Device.detect.each{ |id| puts id }
475
+ end
476
+
477
+ def device_info(udid)
478
+ device = Device.new(udid)
479
+ puts "Unique Device ID: #{device.udid}"
480
+ puts "Device Name: #{device.name}"
481
+ puts "Serial Number: #{device.serial_number}"
482
+ puts "Model Number: #{device.model_number}"
483
+ puts "Product Version: #{device.product_version}"
484
+ puts "Product Type: #{device.product_type}"
485
+ puts "Device Class: #{device.device_class}"
486
+ puts "WiFi Address: #{device.wifi_address}"
487
+ end
488
+
489
+ def build_app(branch_dir,sim)
490
+ if sim == 'sim'
491
+ sdk = "iphonesimulator"
492
+ else
493
+ sdk = "iphoneos"
494
+ end
495
+ project = File.join(FileUtils.pwd, branch_dir, "iPhone", "ConcurMobile.xcodeproj")
496
+ target = "ConcurMobile-cal"
497
+ configuration = "Release"
498
+ system("/usr/bin/xcodebuild -project #{project} -target #{target} -configuration #{configuration} -sdk #{sdk} clean build")
499
+ app_bundle = @settings["app_bundle"]
500
+ source = File.join(FileUtils.pwd, branch_dir, "iPhone", "build", "#{configuration}-#{sdk}", app_bundle)
501
+ target = File.join(FileUtils.pwd, app_bundle)
502
+ FileUtils.rm_rf(target)
503
+ FileUtils.cp_r(source, target)
504
+ end
505
+
506
+ def install_tools
507
+ raise "Please configure Subversion location for tools, username, and password first by running setup" if @settings["svn_location_tools"].to_s.empty? or @settings["svn_username"].to_s.empty? or @settings["svn_password"].to_s.empty?
508
+
509
+ location = @settings["svn_location_tools"]
510
+ location += '/' unless location.end_with?('/')
511
+ username = @settings["svn_username"]
512
+ password = @settings["svn_password"]
513
+
514
+ # delete tools directory
515
+ FileUtils.rm_rf(File.join(FileUtils.pwd, "tools"))
516
+
517
+ system("svn export --force #{location} tools/ --username #{username} --password #{password}")
518
+ tools = `svn list #{location} -R --username #{username} --password #{password}`.split(/\n/).select{|i| i.end_with?('.zip')}
519
+ tools.each do |tool|
520
+ tool_zip = File.join(FileUtils.pwd, "tools", tool)
521
+ unzip_file(tool_zip, File.dirname(tool_zip))
522
+ tool_app = tool_zip.chomp(File.extname(tool_zip)) + ".app"
523
+ puts "Installing #{tool_app}"
524
+ install_app(tool_app)
525
+ end
526
+ end
527
+
528
+ def record_start
529
+ launch_app('concurrecorder://record')
530
+ end
531
+
532
+ def record_stop
533
+ launch_app('concurrecorder://stop')
534
+ end
535
+
536
+ if (ARGV.length == 0)
537
+ print_usage
538
+ exit 0
539
+ end
540
+
541
+ cmd = ARGV.shift
542
+
543
+ if cmd == 'help'
544
+ print_usage
545
+ exit 0
546
+
547
+ elsif cmd == 'setup'
548
+ setup
549
+ exit 0
550
+
551
+ elsif cmd == 'getbuild'
552
+ read_settings
553
+ File.open("#{Dir.tmpdir}/testauto.lock", 'w') { |f|
554
+ f.flock(File::LOCK_EX)
555
+ get_build
556
+ }
557
+ exit 0
558
+
559
+ elsif cmd == 'getscript'
560
+ read_settings
561
+ get_script
562
+ exit 0
563
+
564
+ elsif cmd == 'getsource'
565
+ read_settings
566
+ get_source
567
+ exit 0
568
+
569
+ elsif cmd == 'install'
570
+ read_settings
571
+ option = ARGV.shift
572
+ if option == 'tools'
573
+ install_tools
574
+ else
575
+ install_app(app_bundle_path)
576
+ end
577
+ exit 0
578
+
579
+ elsif cmd == 'uninstall'
580
+ read_settings
581
+ uninstall_app(app_bundle_id(app_bundle_path))
582
+
583
+ elsif cmd == 'launch'
584
+ read_settings
585
+ launch_app(app_bundle_url_schemes(app_bundle_path))
586
+ exit 0
587
+
588
+ elsif cmd == 'getip'
589
+ read_settings
590
+ get_device_ip
591
+ exit 0
592
+
593
+ elsif cmd == 'devices'
594
+ list_devices
595
+ exit 0
596
+
597
+ elsif cmd == 'sim'
598
+ option = ARGV.shift
599
+ read_settings
600
+ if option == 'start'
601
+ start_sim
602
+ elsif option == 'quit'
603
+ quit_sim
604
+ elsif option == 'build'
605
+ branch_dir = ARGV.shift
606
+ build_app(branch_dir, 'sim')
607
+ end
608
+ exit 0
609
+
610
+ elsif cmd == 'run' or cmd == 'console'
611
+ read_settings
612
+ run(cmd)
613
+
614
+ elsif cmd == 'build'
615
+ read_settings
616
+ branch_dir = ARGV.shift
617
+ sim = ARGV.shift
618
+ build_app(branch_dir, sim)
619
+
620
+ elsif cmd == 'gen'
621
+ gen
622
+
623
+ elsif cmd == 'go'
624
+ go
625
+
626
+ elsif cmd == 'record'
627
+ read_settings
628
+ option = ARGV.shift
629
+ if option == 'start'
630
+ record_start
631
+ elsif option == 'stop'
632
+ record_stop
633
+ end
634
+
635
+ elsif cmd == 'version'
636
+ require 'calabash-cucumber'
637
+ puts Calabash::Cucumber::VERSION
638
+ exit 0
639
+
640
+ else
641
+ print_usage
642
+ end
643
+