calabash-android 0.1.0 → 0.2.0.pre2
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/CHANGES.txt +10 -0
- data/bin/calabash-android +19 -2
- data/bin/calabash-android-build.rb +30 -14
- data/bin/calabash-android-generate.rb +0 -1
- data/bin/calabash-android-helpers.rb +0 -15
- data/bin/calabash-android-run.rb +12 -10
- data/features-skeleton/support/app_installation_hooks.rb +2 -1
- data/features-skeleton/support/app_life_cycle_hooks.rb +1 -22
- data/lib/calabash-android/helpers.rb +54 -0
- data/lib/calabash-android/lib/AXMLPrinter2.jar +0 -0
- data/lib/calabash-android/management/adb.rb +0 -11
- data/lib/calabash-android/operations.rb +180 -71
- data/lib/calabash-android/version.rb +2 -2
- data/test-server/build.xml +2 -0
- data/test-server/instrumentation-backend/AndroidManifest.xml +17 -11
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +10 -127
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +76 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/NanoHTTPD.java +1084 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +66 -10
- metadata +17 -11
- data/lib/calabash-android/management/app_installation.rb +0 -21
- data/test-server/instrumentation-backend/gen/com/lesspainful/simpleui/test/R.java +0 -23
data/CHANGES.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.2.0.pre2:
|
2
|
+
A HTTP server has been introduced in the test server so that we no
|
3
|
+
longer use socket for communication.
|
4
|
+
|
5
|
+
0.2.0.pre1:
|
6
|
+
The concept of a Device has been introduced. It will handle all setup
|
7
|
+
and communication with physical devices or emulators.
|
8
|
+
The device class is needed because we want to interact with more than
|
9
|
+
one device at the same time from Calabash.
|
10
|
+
|
1
11
|
0.1.0:
|
2
12
|
Added support for testing Xamarin Mono for Android apps.
|
3
13
|
Currently only Release builds are supported.
|
data/bin/calabash-android
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'calabash-android/helpers'
|
5
|
+
|
4
6
|
|
5
7
|
require File.join(File.dirname(__FILE__), "calabash-android-helpers")
|
6
8
|
require File.join(File.dirname(__FILE__), "calabash-android-generate")
|
@@ -14,6 +16,14 @@ require File.join(File.dirname(__FILE__), "calabash-android-submit")
|
|
14
16
|
@source_dir = File.join(File.dirname(__FILE__), '..', 'features-skeleton')
|
15
17
|
@script_dir = File.join(File.dirname(__FILE__), '..', 'scripts')
|
16
18
|
|
19
|
+
def is_apk_file?(file_path)
|
20
|
+
file_path.end_with? ".apk" and File.exist? file_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def relative_to_full_path(file_path)
|
24
|
+
File.expand_path(File.join(ENV["PWD"], file_path))
|
25
|
+
end
|
26
|
+
|
17
27
|
if (ARGV.length == 0)
|
18
28
|
print_usage
|
19
29
|
exit 0
|
@@ -23,10 +33,17 @@ if cmd == 'help'
|
|
23
33
|
print_help
|
24
34
|
exit 0
|
25
35
|
elsif cmd == 'build'
|
26
|
-
|
36
|
+
puts "Please specify the app you want to test" if (ARGV.empty? or not is_apk_file?(ARGV.first))
|
37
|
+
while not ARGV.empty? and is_apk_file?(ARGV.first)
|
38
|
+
calabash_build(relative_to_full_path(ARGV.shift))
|
39
|
+
end
|
27
40
|
exit 0
|
28
41
|
elsif cmd == 'run'
|
29
|
-
|
42
|
+
if ARGV.empty? or not is_apk_file?(ARGV.first)
|
43
|
+
calabash_run(nil, ARGV)
|
44
|
+
else
|
45
|
+
calabash_run(ARGV.shift)
|
46
|
+
end
|
30
47
|
exit 0
|
31
48
|
elsif cmd == 'gen'
|
32
49
|
calabash_scaffold
|
@@ -1,8 +1,10 @@
|
|
1
|
-
def calabash_build(
|
2
|
-
run_setup_if_settings_does_not_exist
|
1
|
+
def calabash_build(app)
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
|
5
|
+
keystore = read_keystore_info()
|
6
|
+
|
7
|
+
test_server_template_dir = File.join(File.dirname(__FILE__), '..', 'test-server')
|
6
8
|
|
7
9
|
Dir.mktmpdir do |workspace_dir|
|
8
10
|
|
@@ -15,14 +17,14 @@ def calabash_build(args)
|
|
15
17
|
ant_executable,
|
16
18
|
"clean",
|
17
19
|
"package",
|
18
|
-
"-Dtested.package_name=#{
|
19
|
-
"-Dtested.main_activity=#{
|
20
|
-
"-Dtested.project.apk=#{
|
21
|
-
"-Dandroid.api.level=#{
|
22
|
-
"-Dkey.store=#{
|
23
|
-
"-Dkey.store.password=#{
|
24
|
-
"-Dkey.alias=#{
|
25
|
-
"-Dkey.alias.password=#{
|
20
|
+
"-Dtested.package_name=#{package_name(app)}",
|
21
|
+
"-Dtested.main_activity=#{main_activity(app)}",
|
22
|
+
"-Dtested.project.apk=#{app}",
|
23
|
+
"-Dandroid.api.level=#{api_level}",
|
24
|
+
"-Dkey.store=#{keystore["keystore_location"]}",
|
25
|
+
"-Dkey.store.password=#{keystore["keystore_password"]}",
|
26
|
+
"-Dkey.alias=#{keystore["keystore_alias"]}",
|
27
|
+
"-Dkey.alias.password=#{keystore["keystore_alias_password"]}",
|
26
28
|
]
|
27
29
|
STDOUT.sync = true
|
28
30
|
IO.popen(args.join(" ")) do |io|
|
@@ -35,8 +37,22 @@ def calabash_build(args)
|
|
35
37
|
}
|
36
38
|
|
37
39
|
test_apk = File.join(@test_server_dir, "bin", "Test.apk")
|
38
|
-
|
39
|
-
|
40
|
+
test_server_file_name = "#{checksum(app)}.apk"
|
41
|
+
FileUtils.cp(test_apk, File.join(@support_dir, test_server_file_name))
|
42
|
+
puts "Done building the test server. Moved it to features/support/#{test_server_file_name}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_keystore_info
|
47
|
+
if File.exist? ".calabash_settings"
|
48
|
+
JSON.parse(IO.read(".calabash_settings"))
|
49
|
+
else
|
50
|
+
{
|
51
|
+
"keystore_location" => "#{ENV["HOME"]}/.android/debug.keystore",
|
52
|
+
"keystore_password" => "android",
|
53
|
+
"keystore_alias" => "androiddebugkey",
|
54
|
+
"keystore_alias_password" => "android"
|
55
|
+
}
|
40
56
|
end
|
41
57
|
end
|
42
58
|
|
@@ -43,25 +43,10 @@ def print_help
|
|
43
43
|
print_usage
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
46
|
def is_json?(str)
|
48
47
|
str[0..0] == '{'
|
49
48
|
end
|
50
49
|
|
51
|
-
def run_build_if_test_server_does_not_exist
|
52
|
-
unless File.exists?(File.join(@support_dir, "Test.apk"))
|
53
|
-
puts "Could not find the test server"
|
54
|
-
puts "Should I run calabash-android build for you?"
|
55
|
-
puts "Please answer yes (y) or no (n)"
|
56
|
-
if ['yes', 'y'].include? STDIN.gets.chomp
|
57
|
-
calabash_build([])
|
58
|
-
else
|
59
|
-
puts "Please run: calabash-android build"
|
60
|
-
exit 1
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
50
|
def run_setup_if_settings_does_not_exist
|
66
51
|
unless File.exists?(".calabash_settings")
|
67
52
|
puts "Could not find .calabash_settings."
|
data/bin/calabash-android-run.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
def calabash_run(
|
2
|
-
run_build_if_test_server_does_not_exist
|
1
|
+
def calabash_run(app_path)
|
3
2
|
|
4
3
|
old_runner = "android.test.InstrumentationTestRunner"
|
5
4
|
new_rummer = "sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner"
|
@@ -13,14 +12,17 @@ def calabash_run(args)
|
|
13
12
|
exit
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
if app_path
|
16
|
+
test_server_path = "features/support/#{checksum(app_path)}.apk"
|
17
|
+
env = "PACKAGE_NAME=#{package_name(app_path)} "\
|
18
|
+
"TEST_PACKAGE_NAME=#{package_name(test_server_path)} "\
|
19
|
+
"APP_PATH=#{app_path} "\
|
20
|
+
"TEST_APP_PATH=#{test_server_path} "\
|
21
|
+
"TEST_SERVER_PORT=34777"
|
22
|
+
else
|
23
|
+
env = ""
|
24
|
+
end
|
25
|
+
|
24
26
|
STDOUT.sync = true
|
25
27
|
cmd = "cucumber -c #{ARGV.join(" ")} #{env}"
|
26
28
|
puts cmd
|
@@ -8,8 +8,9 @@ Before do |scenario|
|
|
8
8
|
feature_name = scenario.feature.name
|
9
9
|
if FeatureNameMemory.feature_name != feature_name
|
10
10
|
log "Is first scenario - reinstalling apps"
|
11
|
-
|
11
|
+
uninstall_app(ENV["TEST_APP_PATH"])
|
12
12
|
install_app(ENV["TEST_APP_PATH"])
|
13
|
+
uninstall_app(ENV["APP_PATH"])
|
13
14
|
install_app(ENV["APP_PATH"])
|
14
15
|
FeatureNameMemory.feature_name = feature_name
|
15
16
|
end
|
@@ -3,26 +3,5 @@ require 'calabash-android/management/adb'
|
|
3
3
|
Before do |scenario|
|
4
4
|
|
5
5
|
return if scenario.failed? #No need to start the server is anything before this has failed.
|
6
|
-
|
7
|
-
log "Starting test server using:"
|
8
|
-
log cmd
|
9
|
-
if is_windows?
|
10
|
-
system(%Q(start /MIN cmd /C #{cmd}))
|
11
|
-
else
|
12
|
-
`#{cmd} 1>&2 &`
|
13
|
-
end
|
14
|
-
|
15
|
-
sleep 2
|
16
|
-
begin
|
17
|
-
connect_to_test_server
|
18
|
-
log "Connection established"
|
19
|
-
rescue Exception => e
|
20
|
-
log "Exception:#{e.backtrace}"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
After do |scenario|
|
27
|
-
disconnect_from_test_server
|
6
|
+
start_test_server_in_background
|
28
7
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rexml/xpath'
|
3
|
+
|
4
|
+
include REXML
|
5
|
+
|
6
|
+
def package_name(app)
|
7
|
+
require 'rexml/document'
|
8
|
+
require 'rexml/xpath'
|
9
|
+
|
10
|
+
manifest = Document.new(manifest(app))
|
11
|
+
manifest.root.attributes['package']
|
12
|
+
end
|
13
|
+
|
14
|
+
def main_activity(app)
|
15
|
+
manifest = Document.new(manifest(app))
|
16
|
+
main_activity = manifest.elements["//action[@name='android.intent.action.MAIN']/../.."].attributes['name']
|
17
|
+
#Handle situation where main activity is on the form '.class_name'
|
18
|
+
if main_activity.start_with? "."
|
19
|
+
main_activity = package_name(app) + main_activity
|
20
|
+
elsif not main_activity.include? "." #This is undocumentet behaviour but Android seems to accept shorthand naming that does not start with '.'
|
21
|
+
main_activity = "#{package_name(app)}.#{main_activity}"
|
22
|
+
end
|
23
|
+
main_activity
|
24
|
+
end
|
25
|
+
|
26
|
+
def api_level
|
27
|
+
api_levels = Dir["#{ENV["ANDROID_HOME"]}/platforms/android-*"].collect{|platform| platform.split("-").last.to_i}.sort
|
28
|
+
if api_levels.empty?
|
29
|
+
raise "Android SDK not found. Please install one of more using #{ENV["ANDROID_HOME"]}/tools/android"
|
30
|
+
end
|
31
|
+
|
32
|
+
api_levels = api_levels.find_all {|l| l > 7}
|
33
|
+
if api_levels.empty?
|
34
|
+
raise "Android SDK above 7 not found. Please install one of more using #{ENV["ANDROID_HOME"]}/tools/android"
|
35
|
+
end
|
36
|
+
api_levels.first
|
37
|
+
end
|
38
|
+
|
39
|
+
def manifest(app)
|
40
|
+
require 'tmpdir'
|
41
|
+
dir = Dir.mktmpdir
|
42
|
+
FileUtils.cp(app, File.join(dir, "app.apk"))
|
43
|
+
|
44
|
+
system "unzip -d #{dir} #{app} AndroidManifest.xml"
|
45
|
+
|
46
|
+
`java -jar #{File.dirname(__FILE__)}/lib/AXMLPrinter2.jar #{dir}/AndroidManifest.xml`
|
47
|
+
end
|
48
|
+
|
49
|
+
def checksum(file_path)
|
50
|
+
require 'digest/md5'
|
51
|
+
Digest::MD5.hexdigest(File.read(file_path))
|
52
|
+
end
|
53
|
+
|
54
|
+
|
Binary file
|
@@ -1,11 +0,0 @@
|
|
1
|
-
def adb_command
|
2
|
-
if is_windows?
|
3
|
-
%Q("#{ENV["ANDROID_HOME"]}\\platform-tools\\adb.exe" #{ENV["ADB_DEVICE_ARG"]})
|
4
|
-
else
|
5
|
-
%Q(#{ENV["ANDROID_HOME"]}/platform-tools/adb #{ENV["ADB_DEVICE_ARG"]})
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
def is_windows?
|
10
|
-
ENV["OS"] == "Windows_NT"
|
11
|
-
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'net/http'
|
2
3
|
require 'rubygems'
|
3
4
|
require 'json'
|
4
5
|
require 'socket'
|
5
6
|
require 'timeout'
|
7
|
+
require 'calabash-android/helpers'
|
6
8
|
|
7
9
|
|
8
10
|
module Calabash module Android
|
@@ -15,19 +17,7 @@ module Operations
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def take_screenshot
|
18
|
-
|
19
|
-
FileUtils.mkdir_p path unless File.exist? path
|
20
|
-
filename_prefix = FeatureNameMemory.feature_name.gsub(/\s+/, '_').downcase
|
21
|
-
begin
|
22
|
-
Timeout.timeout(30) do
|
23
|
-
file_name = "#{path}/#{filename_prefix}_#{StepCounter.step_line}.png"
|
24
|
-
log "Taking screenshoot to #{file_name} from device: #{ENV['ADB_DEVICE_ARG']}"
|
25
|
-
system("java -jar #{File.dirname(__FILE__)}/lib/screenShotTaker.jar #{file_name} #{ENV['ADB_DEVICE_ARG']}")
|
26
|
-
log "Screenshot stored in: #{file_name}"
|
27
|
-
end
|
28
|
-
rescue Timeout::Error
|
29
|
-
raise Exception, "take_screenshot timed out"
|
30
|
-
end
|
20
|
+
Device.default_device.take_screenshot
|
31
21
|
end
|
32
22
|
|
33
23
|
def macro(txt)
|
@@ -39,31 +29,23 @@ module Operations
|
|
39
29
|
end
|
40
30
|
|
41
31
|
def performAction(action, *arguments)
|
42
|
-
|
32
|
+
Device.default_device.perform_action(action, *arguments)
|
33
|
+
end
|
43
34
|
|
44
|
-
|
35
|
+
def install_app(app_path)
|
36
|
+
Device.default_device.install_app(app_path)
|
37
|
+
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
result = @@client.readline
|
50
|
-
rescue Exception => e
|
51
|
-
log "Error communicating with test server: #{e}"
|
52
|
-
raise e
|
53
|
-
end
|
54
|
-
log "Result:'" + result.strip + "'"
|
55
|
-
raise "Empty result from TestServer" if result.chomp.empty?
|
56
|
-
result = JSON.parse(result)
|
57
|
-
if not result["success"] then
|
58
|
-
take_screenshot
|
59
|
-
raise result["message"].to_s
|
60
|
-
end
|
61
|
-
return result
|
62
|
-
end
|
63
|
-
rescue Timeout::Error
|
64
|
-
raise Exception, "Step timed out"
|
39
|
+
def uninstall_apps
|
40
|
+
Device.default_device.uninstall_app(ENV["TEST_PACKAGE_NAME"])
|
41
|
+
Device.default_device.uninstall_app(ENV["PACKAGE_NAME"])
|
65
42
|
end
|
66
43
|
|
44
|
+
def start_test_server_in_background
|
45
|
+
Device.default_device.start_test_server_in_background()
|
46
|
+
end
|
47
|
+
|
48
|
+
|
67
49
|
def wait_for(timeout, &block)
|
68
50
|
begin
|
69
51
|
Timeout::timeout(timeout) do
|
@@ -93,16 +75,6 @@ module Operations
|
|
93
75
|
raise "Not yet implemented."
|
94
76
|
end
|
95
77
|
|
96
|
-
|
97
|
-
##adb
|
98
|
-
def adb_command
|
99
|
-
if is_windows?
|
100
|
-
%Q("#{ENV["ANDROID_HOME"]}\\platform-tools\\adb.exe" #{ENV["ADB_DEVICE_ARG"]})
|
101
|
-
else
|
102
|
-
%Q(#{ENV["ANDROID_HOME"]}/platform-tools/adb #{ENV["ADB_DEVICE_ARG"]})
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
78
|
def is_windows?
|
107
79
|
ENV["OS"] == "Windows_NT"
|
108
80
|
end
|
@@ -110,41 +82,179 @@ module Operations
|
|
110
82
|
|
111
83
|
### app life cycle
|
112
84
|
def connect_to_test_server
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
begin
|
117
|
-
Timeout.timeout(10) do
|
118
|
-
@@client = TCPSocket.open('127.0.0.1',ENV["TEST_SERVER_PORT"])
|
119
|
-
@@client.send("Ping!\n",0)
|
120
|
-
log "Got '#{@@client.readline.strip}' from testserver"
|
121
|
-
end
|
122
|
-
rescue Exception => e
|
123
|
-
log "Got exception:#{e}. Retrying!"
|
124
|
-
sleep(1)
|
125
|
-
retry unless Time.now > end_time
|
126
|
-
end
|
85
|
+
puts "Explicit calls to connect_to_test_server should be removed."
|
86
|
+
puts "Please take a look in your hooks file for calls to this methods."
|
87
|
+
puts "(Hooks are stored in features/support)"
|
127
88
|
end
|
128
89
|
|
129
90
|
def disconnect_from_test_server
|
130
|
-
|
131
|
-
|
91
|
+
puts "Explicit calls to disconnect_from_test_server should be removed."
|
92
|
+
puts "Please take a look in your hooks file for calls to this methods."
|
93
|
+
puts "(Hooks are stored in features/support)"
|
132
94
|
end
|
133
95
|
|
96
|
+
class Device
|
97
|
+
@@default_device = nil
|
134
98
|
|
99
|
+
def self.default_device
|
100
|
+
unless @@default_device
|
101
|
+
@@default_device = Device.new(ENV["ADB_DEVICE_ARG"], ENV["TEST_SERVER_PORT"], ENV["APP_PATH"], ENV["TEST_APP_PATH"])
|
102
|
+
end
|
103
|
+
@@default_device
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_default_device
|
107
|
+
@@default_device = self
|
108
|
+
end
|
135
109
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
110
|
+
def initialize(serial, server_port, app_path, test_server_path)
|
111
|
+
@serial = serial
|
112
|
+
@server_port = server_port
|
113
|
+
@app_path = app_path
|
114
|
+
@test_server_path = test_server_path
|
141
115
|
|
142
|
-
|
143
|
-
|
144
|
-
|
116
|
+
puts "#{adb_command} forward tcp:b#{server_port} tcp:7102"
|
117
|
+
log `#{adb_command} forward tcp:#{server_port} tcp:7102`
|
118
|
+
=begin
|
119
|
+
begin
|
120
|
+
Timeout::timeout(15) do
|
121
|
+
puts http("/ping")
|
122
|
+
end
|
123
|
+
rescue Timeout::Error
|
124
|
+
msg = "Unable to make connection to Calabash Test Server at http://127.0.0.1:#{@server_port}/\n"
|
125
|
+
msg << "Please check the logcat output for more info about what happened\n"
|
126
|
+
raise msg
|
127
|
+
end
|
128
|
+
=end
|
129
|
+
end
|
130
|
+
|
131
|
+
def reinstall_apps()
|
132
|
+
uninstall_app(package_name(@app_path))
|
133
|
+
install_app(@app_path)
|
134
|
+
uninstall_app(package_name(@test_server_path))
|
135
|
+
install_app(@test_server_path)
|
136
|
+
end
|
137
|
+
|
138
|
+
def install_app(app_path)
|
139
|
+
cmd = "#{adb_command} install #{app_path}"
|
140
|
+
log "Installing: #{app_path}"
|
141
|
+
result = `#{cmd}`
|
142
|
+
if result.include? "Success"
|
143
|
+
log "Success"
|
144
|
+
else
|
145
|
+
log "#Failure"
|
146
|
+
log "'#{cmd}' said:"
|
147
|
+
log result.strip
|
148
|
+
raise "Could not install app #{app_path}: #{result.strip}"
|
149
|
+
end
|
150
|
+
end
|
145
151
|
|
146
|
-
|
147
|
-
|
152
|
+
def uninstall_app(package_name)
|
153
|
+
log "Uninstalling: #{package_name}"
|
154
|
+
log `#{adb_command} uninstall #{package_name}`
|
155
|
+
end
|
156
|
+
|
157
|
+
def perform_action(action, *arguments)
|
158
|
+
log "Action: #{action} - Params: #{arguments.join(', ')}"
|
159
|
+
|
160
|
+
params = {"command" => action, "arguments" => arguments}
|
161
|
+
|
162
|
+
Timeout.timeout(300) do
|
163
|
+
begin
|
164
|
+
result = http("/", params)
|
165
|
+
rescue Exception => e
|
166
|
+
log "Error communicating with test server: #{e}"
|
167
|
+
raise e
|
168
|
+
end
|
169
|
+
log "Result:'" + result.strip + "'"
|
170
|
+
raise "Empty result from TestServer" if result.chomp.empty?
|
171
|
+
result = JSON.parse(result)
|
172
|
+
if not result["success"] then
|
173
|
+
take_screenshot
|
174
|
+
raise result["message"].to_s
|
175
|
+
end
|
176
|
+
return result
|
177
|
+
end
|
178
|
+
rescue Timeout::Error
|
179
|
+
raise Exception, "Step timed out"
|
180
|
+
end
|
181
|
+
|
182
|
+
def http(path, data = {})
|
183
|
+
begin
|
184
|
+
http = Net::HTTP.new "127.0.0.1", @server_port
|
185
|
+
resp, data = http.post(path, "command=#{data.to_json}", {})
|
186
|
+
data
|
187
|
+
rescue EOFError
|
188
|
+
sleep 0.5
|
189
|
+
retry
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def take_screenshot
|
194
|
+
path = ENV["SCREENSHOT_PATH_PREFIX"] || "results"
|
195
|
+
FileUtils.mkdir_p path unless File.exist? path
|
196
|
+
filename_prefix = FeatureNameMemory.feature_name.gsub(/\s+/, '_').downcase
|
197
|
+
begin
|
198
|
+
Timeout.timeout(30) do
|
199
|
+
file_name = "#{path}/#{filename_prefix}_#{StepCounter.step_line}.png"
|
200
|
+
log "Taking screenshoot to #{file_name} from device: #{@serial}"
|
201
|
+
system("java -jar #{File.dirname(__FILE__)}/lib/screenShotTaker.jar #{file_name} #{device_args}")
|
202
|
+
log "Screenshot stored in: #{file_name}"
|
203
|
+
end
|
204
|
+
rescue Timeout::Error
|
205
|
+
raise Exception, "take_screenshot timed out"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def adb_command
|
210
|
+
if is_windows?
|
211
|
+
%Q("#{ENV["ANDROID_HOME"]}\\platform-tools\\adb.exe" #{device_args})
|
212
|
+
else
|
213
|
+
%Q(#{ENV["ANDROID_HOME"]}/platform-tools/adb #{device_args})
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def device_args
|
218
|
+
if @serial
|
219
|
+
"-s #{@serial}"
|
220
|
+
else
|
221
|
+
""
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def is_windows?
|
226
|
+
ENV["OS"] == "Windows_NT"
|
227
|
+
end
|
228
|
+
|
229
|
+
def start_test_server_in_background
|
230
|
+
test_server_package = package_name(@test_server_path)
|
231
|
+
cmd = "#{adb_command} shell am instrument -w -e class sh.calaba.instrumentationbackend.InstrumentationBackend #{test_server_package}/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner"
|
232
|
+
log "Starting test server using:"
|
233
|
+
log cmd
|
234
|
+
if is_windows?
|
235
|
+
system(%Q(start /MIN cmd /C #{cmd}))
|
236
|
+
else
|
237
|
+
`#{cmd} 1>&2 &`
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def log(message)
|
242
|
+
$stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}" if (ARGV.include? "-v" or ARGV.include? "--verbose")
|
243
|
+
end
|
244
|
+
|
245
|
+
##location
|
246
|
+
def set_gps_coordinates_from_location(location)
|
247
|
+
require 'geocoder'
|
248
|
+
results = Geocoder.search(location)
|
249
|
+
raise Exception, "Got no results for #{location}" if results.empty?
|
250
|
+
|
251
|
+
best_result = results.first
|
252
|
+
set_gps_coordinates(best_result.latitude, best_result.longitude)
|
253
|
+
end
|
254
|
+
|
255
|
+
def set_gps_coordinates(latitude, longitude)
|
256
|
+
perform_action('set_gps_coordinates', latitude, longitude)
|
257
|
+
end
|
148
258
|
end
|
149
259
|
|
150
260
|
|
@@ -167,7 +277,6 @@ module Operations
|
|
167
277
|
query(q).map {|e| e['html']}
|
168
278
|
end
|
169
279
|
|
170
|
-
|
171
280
|
def set_text(uiquery, txt)
|
172
281
|
raise "Currently queries are only supported for webviews" unless uiquery.start_with? "webView"
|
173
282
|
|