testautoa 0.4.1 → 0.4.2.pre1
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/calabash-android +18 -0
- data/bin/calabash-android-build.rb +4 -0
- data/bin/calabash-android-console.rb +0 -4
- data/bin/calabash-android-run.rb +1 -2
- data/bin/testautoa +79 -19
- data/lib/calabash-android/lib/TestServer.apk +0 -0
- data/lib/calabash-android/operations.rb +19 -5
- data/lib/calabash-android/version.rb +1 -1
- data/test-server/AndroidManifest.xml +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/CalabashInstrumentationTestRunner.java +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +4 -10
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +1 -0
- metadata +21 -5
data/bin/calabash-android
CHANGED
@@ -11,6 +11,24 @@ unless defined? RbConfig.ruby
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
|
15
|
+
if File.exist? "features/support/app_life_cycle_hooks.rb"
|
16
|
+
content = IO.read("features/support/app_life_cycle_hooks.rb")
|
17
|
+
if content.include? "include Calabash::Android::Operations"
|
18
|
+
puts """
|
19
|
+
Fatal Error!
|
20
|
+
Your Calabash hooks are not compatible with this version of calabash-android.
|
21
|
+
Please remove the following line from 'features/support/app_life_cycle_hooks.rb'.
|
22
|
+
|
23
|
+
include Calabash::Android::Operations
|
24
|
+
|
25
|
+
"""
|
26
|
+
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
14
32
|
require File.join(File.dirname(__FILE__), "calabash-android-helpers")
|
15
33
|
require File.join(File.dirname(__FILE__), "calabash-android-generate")
|
16
34
|
require File.join(File.dirname(__FILE__), "calabash-android-build")
|
@@ -22,6 +22,10 @@ def calabash_build(app)
|
|
22
22
|
raise "Could not replace package name in manifest"
|
23
23
|
end
|
24
24
|
|
25
|
+
unless system %Q{"#{RbConfig.ruby}" -pi.bak -e "gsub(/#testPackage#/, '#{package_name(app)}.test')" AndroidManifest.xml}
|
26
|
+
raise "Could not replace test package name in manifest"
|
27
|
+
end
|
28
|
+
|
25
29
|
unless system %Q{"#{ENV["ANDROID_HOME"]}/platform-tools/aapt" package -M AndroidManifest.xml -I "#{android_platform}/android.jar" -F dummy.apk}
|
26
30
|
raise "Could not create dummy.apk"
|
27
31
|
end
|
@@ -7,10 +7,6 @@ def calabash_console(app_path = nil)
|
|
7
7
|
|
8
8
|
ENV["IRBRC"] = File.join(File.dirname(__FILE__), '..', 'irbrc')
|
9
9
|
|
10
|
-
unless ENV["PACKAGE_NAME"]
|
11
|
-
ENV["PACKAGE_NAME"] = package_name(app_path)
|
12
|
-
end
|
13
|
-
|
14
10
|
unless ENV["MAIN_ACTIVITY"]
|
15
11
|
ENV["MAIN_ACTIVITY"] = main_activity(app_path)
|
16
12
|
end
|
data/bin/calabash-android-run.rb
CHANGED
@@ -21,8 +21,7 @@ def calabash_run(app_path = nil)
|
|
21
21
|
else
|
22
22
|
test_server_port = "34777"
|
23
23
|
end
|
24
|
-
env = "
|
25
|
-
"MAIN_ACTIVITY=#{main_activity(app_path)} "\
|
24
|
+
env = "MAIN_ACTIVITY=#{main_activity(app_path)} "\
|
26
25
|
"APP_PATH=\"#{app_path}\" "\
|
27
26
|
"TEST_APP_PATH=\"#{test_server_path}\" "\
|
28
27
|
"TEST_SERVER_PORT=#{test_server_port}"
|
data/bin/testautoa
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'calabash-android/version'
|
4
|
+
require 'calabash-android/operations'
|
3
5
|
require 'fileutils'
|
4
6
|
require 'json'
|
5
7
|
require 'uri'
|
@@ -29,6 +31,8 @@ def print_usage
|
|
29
31
|
Start an Android Virtual Device
|
30
32
|
devices
|
31
33
|
List connected Android Devices
|
34
|
+
install tools
|
35
|
+
Install all tools
|
32
36
|
getbuild list
|
33
37
|
List available builds in the build drop
|
34
38
|
getbuild <Version>
|
@@ -39,6 +43,8 @@ def print_usage
|
|
39
43
|
List available scripts
|
40
44
|
getscript <Script>
|
41
45
|
Download the specified script
|
46
|
+
go <Version> <Script>
|
47
|
+
Download the build with <Version> and start test automation with <Script>
|
42
48
|
version
|
43
49
|
prints the gem version
|
44
50
|
|
@@ -137,29 +143,30 @@ def setup
|
|
137
143
|
read_settings
|
138
144
|
puts "Settings for Test Automation"
|
139
145
|
|
140
|
-
ask_for_setting(
|
141
|
-
ask_for_setting(
|
142
|
-
ask_for_setting(
|
146
|
+
ask_for_setting("svn_location", "Please enter svn location for scripts", @settings["svn_location"])
|
147
|
+
ask_for_setting("svn_location_tools", "Please enter svn location for tools", @settings["svn_location_tools"])
|
148
|
+
ask_for_setting("svn_username", "Please enter svn username", @settings["svn_username"])
|
149
|
+
ask_for_setting("svn_password", "Please enter svn password", @settings["svn_password"])
|
143
150
|
|
144
|
-
ask_for_setting(
|
145
|
-
ask_for_setting(
|
146
|
-
ask_for_setting(
|
151
|
+
ask_for_setting("build_drop_location", "Please enter build drop location", @settings["build_drop_location"])
|
152
|
+
ask_for_setting("build_drop_username", "Please enter the username", @settings["build_drop_username"])
|
153
|
+
ask_for_setting("build_drop_password", "Please enter the password", @settings["build_drop_password"])
|
147
154
|
|
148
|
-
ask_for_setting(
|
149
|
-
ask_for_setting(
|
150
|
-
ask_for_setting(
|
155
|
+
ask_for_setting("app_package", "Please enter the name of app package", @settings["app_package"])
|
156
|
+
ask_for_setting("device_serialno", "Please enter the serial number of the device", @settings["device_serialno"])
|
157
|
+
ask_for_setting("test_server_port", "Please enter the test server port", @settings["test_server_port"] ||= "34777")
|
151
158
|
|
152
|
-
ask_for_setting(
|
159
|
+
ask_for_setting("avd_name", "Please enter the name of Android emulator", @settings["avd_name"] ||= "testauto_avd")
|
153
160
|
puts "Available Targets:"
|
154
161
|
get_target_names.each{|i| puts "* #{i}" }
|
155
|
-
ask_for_setting(
|
162
|
+
ask_for_setting("avd_target", "Please enter the target of Android emulator", @settings["avd_target"] ||= "android-16")
|
156
163
|
puts "Available CPUs:"
|
157
164
|
get_abis(@settings["avd_target"]).each{|i| puts "* #{i}"}
|
158
|
-
ask_for_setting(
|
159
|
-
ask_for_setting(
|
160
|
-
ask_for_setting(
|
161
|
-
@settings[
|
162
|
-
@settings[
|
165
|
+
ask_for_setting("avd_cpu", "Please enter the CPU of Android emulator", @settings["avd_cpu"] ||= "armeabi-v7a")
|
166
|
+
ask_for_setting("avd_sdcard_size", "Please enter the SD card size of Android emulator", @settings["avd_sdcard_size"] ||= "64M")
|
167
|
+
ask_for_setting("avd_ram_size", "Please enter the RAM size of Android emulator", @settings["avd_ram_size"] ||= "1024")
|
168
|
+
@settings["build_drop_branch_dir"] = "Mobile/Android/branch"
|
169
|
+
@settings["build_drop_trunk_dir"] = "Mobile/Android/trunk"
|
163
170
|
|
164
171
|
open('.testautoa_settings', 'w') do |f|
|
165
172
|
f.puts @settings.to_json
|
@@ -227,6 +234,12 @@ def smb_connect_mac(location,username,password)
|
|
227
234
|
location = location.tr('\\','/')
|
228
235
|
username = username.tr('\\',';').tr('/',';')
|
229
236
|
raise "The build drop location is incorrect" if not location.start_with?("//")
|
237
|
+
paths = location.split('/')
|
238
|
+
if paths.size > 4
|
239
|
+
location = paths.shift(4).join('/')
|
240
|
+
@settings["build_drop_branch_dir"] = [paths.join('/'), @settings["build_drop_branch_dir"]].join('/')
|
241
|
+
@settings["build_drop_trunk_dir"] = [paths.join('/'), @settings["build_drop_trunk_dir"]].join('/')
|
242
|
+
end
|
230
243
|
cmd = "mount -t smbfs //'#{username}':#{password}@#{location[2..-1]} #{mount_node}"
|
231
244
|
output=`#{cmd}` ; result=$?.success?
|
232
245
|
raise "the command '#{cmd}' failed" if result == false
|
@@ -257,6 +270,8 @@ def smb_disconnect(mount_node)
|
|
257
270
|
end
|
258
271
|
|
259
272
|
def get_build
|
273
|
+
raise "Please configure build drop location, username, and password first by running setup" if @settings["build_drop_location"].to_s.empty? or @settings["build_drop_username"].to_s.empty? or @settings["build_drop_password"].to_s.empty?
|
274
|
+
|
260
275
|
mount_node = smb_connect(@settings["build_drop_location"],
|
261
276
|
@settings["build_drop_username"],
|
262
277
|
@settings["build_drop_password"])
|
@@ -277,7 +292,9 @@ def get_build
|
|
277
292
|
# copy the version build
|
278
293
|
release_path = File.join(mount_node, @settings["build_drop_branch_dir"], "Android#{ARGV.first}/Release")
|
279
294
|
end
|
280
|
-
|
295
|
+
raise "No builds found in #{release_path}" unless File.directory?(release_path)
|
296
|
+
build_dir = Dir.entries(release_path).reject{|d|d.start_with?('.')}.sort_by{|c| File.stat(File.join(release_path,c)).ctime}.last
|
297
|
+
raise "No builds found in #{release_path}" if build_dir == nil
|
281
298
|
apk_file = "ConcurMobile.apk"
|
282
299
|
source = File.join(release_path, build_dir, apk_file)
|
283
300
|
raise "the file '#{source}' does not exist" if not File.exists?(source)
|
@@ -289,6 +306,8 @@ def get_build
|
|
289
306
|
end
|
290
307
|
|
291
308
|
def get_script
|
309
|
+
raise "Please configure Subversion location, username, and password first by running setup" if @settings["svn_location"].to_s.empty? or @settings["svn_username"].to_s.empty? or @settings["svn_password"].to_s.empty?
|
310
|
+
|
292
311
|
username = @settings["svn_username"]
|
293
312
|
password = @settings["svn_password"]
|
294
313
|
uri = URI.join(@settings["svn_location"], "Mobile/", "BVT/", "CTE/")
|
@@ -300,8 +319,8 @@ def get_script
|
|
300
319
|
uri = URI.join(uri, feature)
|
301
320
|
puts `svn export --force #{uri} features --username #{username} --password #{password}`
|
302
321
|
|
303
|
-
|
304
|
-
|
322
|
+
uri = URI.join(@settings["svn_location"], "_support/", "support/")
|
323
|
+
puts `svn export --force #{uri} features/support --username #{username} --password #{password}`
|
305
324
|
uri = URI.join(@settings["svn_location"], "_support/", "step_definition/")
|
306
325
|
puts `svn export --force #{uri} features/step_definitions --username #{username} --password #{password}`
|
307
326
|
end
|
@@ -312,6 +331,17 @@ def adb_path
|
|
312
331
|
File.join(ENV['ANDROID_HOME'], 'platform-tools', 'adb')
|
313
332
|
end
|
314
333
|
|
334
|
+
def adb_path_w_sn
|
335
|
+
raise_if_android_home_not_set
|
336
|
+
serial_number = @settings["device_serialno"].to_s.strip
|
337
|
+
serial_number = " -s #{serial_number}" unless serial_number.empty?
|
338
|
+
adb_path + serial_number
|
339
|
+
end
|
340
|
+
|
341
|
+
def adb_shell(command)
|
342
|
+
system("#{adb_path_w_sn} shell #{command}")
|
343
|
+
end
|
344
|
+
|
315
345
|
def android_path
|
316
346
|
raise_if_android_home_not_set
|
317
347
|
File.join(ENV['ANDROID_HOME'], 'tools', 'android')
|
@@ -383,6 +413,29 @@ def run_avd
|
|
383
413
|
end
|
384
414
|
end
|
385
415
|
|
416
|
+
def install_tools
|
417
|
+
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?
|
418
|
+
|
419
|
+
location = @settings["svn_location_tools"]
|
420
|
+
location += '/' unless location.end_with?('/')
|
421
|
+
username = @settings["svn_username"]
|
422
|
+
password = @settings["svn_password"]
|
423
|
+
serial_number = @settings["device_serialno"].to_s.strip
|
424
|
+
adb_dev_arg = ''
|
425
|
+
adb_dev_arg = "-s #{serial_number}" unless serial_number.empty?
|
426
|
+
|
427
|
+
# delete tools directory
|
428
|
+
FileUtils.rm_rf(File.join(FileUtils.pwd, "tools"))
|
429
|
+
|
430
|
+
system("svn export --force #{location} tools/ --username #{username} --password #{password}")
|
431
|
+
tools = `svn list #{location} -R --username #{username} --password #{password}`.split(/\n/).select{|i| i.end_with?('.apk')}
|
432
|
+
tools.each do |tool|
|
433
|
+
tool_apk = File.join(FileUtils.pwd, "tools", tool)
|
434
|
+
puts "Installing #{tool_apk}"
|
435
|
+
system("#{adb_path} #{adb_dev_arg} install #{tool_apk}")
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
386
439
|
if (ARGV.length == 0)
|
387
440
|
print_usage
|
388
441
|
exit 0
|
@@ -415,6 +468,13 @@ elsif cmd == 'devices'
|
|
415
468
|
list_devices
|
416
469
|
exit 0
|
417
470
|
|
471
|
+
elsif cmd == 'install'
|
472
|
+
read_settings
|
473
|
+
tools = ARGV.shift
|
474
|
+
if tools == 'tools'
|
475
|
+
install_tools
|
476
|
+
end
|
477
|
+
|
418
478
|
elsif cmd == 'list'
|
419
479
|
option = ARGV.shift
|
420
480
|
if option == 'target'
|
Binary file
|
@@ -59,8 +59,8 @@ module Operations
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def uninstall_apps
|
62
|
-
default_device.uninstall_app(
|
63
|
-
default_device.uninstall_app(
|
62
|
+
default_device.uninstall_app(package_name(default_device.test_server_path))
|
63
|
+
default_device.uninstall_app(package_name(default_device.app_path))
|
64
64
|
end
|
65
65
|
|
66
66
|
def wake_up
|
@@ -104,6 +104,10 @@ module Operations
|
|
104
104
|
default_device.press_back_key
|
105
105
|
end
|
106
106
|
|
107
|
+
def switch_wifi(on)
|
108
|
+
default_device.switch_wifi(on)
|
109
|
+
end
|
110
|
+
|
107
111
|
#def wait_for(timeout, &block)
|
108
112
|
# value = nil
|
109
113
|
# begin
|
@@ -166,15 +170,18 @@ module Operations
|
|
166
170
|
end
|
167
171
|
|
168
172
|
class Device
|
173
|
+
attr_reader :app_path, :test_server_path, :serial, :server_port, :test_server_port
|
174
|
+
|
175
|
+
def initialize(cucumber_world, serial, server_port, app_path, test_server_path, test_server_port = 7102)
|
169
176
|
|
170
|
-
def initialize(cucumber_world, serial, server_port, app_path, test_server_path)
|
171
177
|
@cucumber_world = cucumber_world
|
172
178
|
@serial = serial
|
173
179
|
@server_port = server_port
|
174
180
|
@app_path = app_path
|
175
181
|
@test_server_path = test_server_path
|
182
|
+
@test_server_port = test_server_port
|
176
183
|
|
177
|
-
forward_cmd = "#{adb_command} forward tcp:#{server_port} tcp
|
184
|
+
forward_cmd = "#{adb_command} forward tcp:#{@server_port} tcp:#{@test_server_port}"
|
178
185
|
log forward_cmd
|
179
186
|
log `#{forward_cmd}`
|
180
187
|
end
|
@@ -334,8 +341,10 @@ module Operations
|
|
334
341
|
wake_up
|
335
342
|
end
|
336
343
|
|
344
|
+
puts "app_path: #{@app_path}"
|
337
345
|
env_options = {:target_package => options[:target_package] || package_name(@app_path),
|
338
346
|
:main_activity => options[:main_activity] || main_activity(@app_path),
|
347
|
+
:test_server_port => @test_server_port,
|
339
348
|
:debug => options[:debug] || false,
|
340
349
|
:class => options[:class] || "sh.calaba.instrumentationbackend.InstrumentationBackend"}
|
341
350
|
|
@@ -347,7 +356,7 @@ module Operations
|
|
347
356
|
cmd_arr << val.to_s
|
348
357
|
end
|
349
358
|
|
350
|
-
cmd_arr << "
|
359
|
+
cmd_arr << "#{package_name(@test_server_path)}/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner"
|
351
360
|
|
352
361
|
cmd = cmd_arr.join(" ")
|
353
362
|
|
@@ -435,6 +444,11 @@ module Operations
|
|
435
444
|
def press_back_key
|
436
445
|
input_keyevent(4)
|
437
446
|
end
|
447
|
+
|
448
|
+
def switch_wifi(on)
|
449
|
+
cmd = "#{adb_command} shell am start -n com.concur.wifiswitch/." + (on ? "On" : "Off") + "Activity"
|
450
|
+
result = `#{cmd}`
|
451
|
+
end
|
438
452
|
end
|
439
453
|
|
440
454
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
2
2
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
3
|
-
package="
|
3
|
+
package="#testPackage#"
|
4
4
|
android:versionCode="3"
|
5
5
|
android:versionName="0.3.0">
|
6
6
|
<application android:label="instrumentation_backend">
|
@@ -21,7 +21,7 @@ public class CalabashInstrumentationTestRunner extends InstrumentationTestRunner
|
|
21
21
|
}
|
22
22
|
|
23
23
|
// Start the HttpServer as soon as possible in a not-ready state
|
24
|
-
HttpServer.instantiate();
|
24
|
+
HttpServer.instantiate(Integer.parseInt(arguments.getString("test_server_port")));
|
25
25
|
|
26
26
|
InstrumentationBackend.testPackage = arguments.getString("target_package");
|
27
27
|
|
@@ -42,20 +42,14 @@ public class HttpServer extends NanoHTTPD {
|
|
42
42
|
*
|
43
43
|
* Can only be called once. Otherwise, you'll get an IllegalStateException.
|
44
44
|
*/
|
45
|
-
public synchronized static HttpServer instantiate() {
|
45
|
+
public synchronized static HttpServer instantiate(int testServerPort) {
|
46
46
|
if (instance != null) {
|
47
47
|
throw new IllegalStateException("Can only instantiate once!");
|
48
48
|
}
|
49
|
-
instance = new HttpServer();
|
49
|
+
instance = new HttpServer(testServerPort);
|
50
50
|
return instance;
|
51
51
|
}
|
52
52
|
|
53
|
-
/**
|
54
|
-
* Returns the singleton instance for HttpServer.
|
55
|
-
*
|
56
|
-
* If {@link #instantiate()} hasn't already been called, an
|
57
|
-
* IllegalStateException is thrown.
|
58
|
-
*/
|
59
53
|
public synchronized static HttpServer getInstance() {
|
60
54
|
if (instance == null) {
|
61
55
|
throw new IllegalStateException("Must be initialized!");
|
@@ -63,8 +57,8 @@ public class HttpServer extends NanoHTTPD {
|
|
63
57
|
return instance;
|
64
58
|
}
|
65
59
|
|
66
|
-
private HttpServer() {
|
67
|
-
super(
|
60
|
+
private HttpServer(int testServerPort) {
|
61
|
+
super(testServerPort, new File("/"));
|
68
62
|
}
|
69
63
|
|
70
64
|
@SuppressWarnings("rawtypes")
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testautoa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.2.pre1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- jimtsay
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cucumber
|
@@ -107,6 +107,22 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rest-client
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
110
126
|
description: Description
|
111
127
|
email:
|
112
128
|
executables:
|
@@ -848,9 +864,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
848
864
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
849
865
|
none: false
|
850
866
|
requirements:
|
851
|
-
- - ! '
|
867
|
+
- - ! '>'
|
852
868
|
- !ruby/object:Gem::Version
|
853
|
-
version:
|
869
|
+
version: 1.3.1
|
854
870
|
requirements: []
|
855
871
|
rubyforge_project:
|
856
872
|
rubygems_version: 1.8.25
|