testautoi 0.9.127 → 0.9.133

Sign up to get free protection for your applications and to get access to all the features.
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
+