calabash 1.2.1 → 1.9.9.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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -0,0 +1,64 @@
1
+ module Calabash
2
+ # Contains the Android implementations of the Calabash APIs.
3
+ module Android
4
+ TEST_SERVER_CODE_PATH = File.join(File.dirname(__FILE__), '..', '..', 'android', 'test-server')
5
+ UNSIGNED_TEST_SERVER_APK = File.join(File.dirname(__FILE__), 'android', 'lib', 'TestServer.apk')
6
+ ANDROID_MANIFEST_PATH = File.join(File.dirname(__FILE__), 'android', 'lib', 'AndroidManifest.xml')
7
+
8
+ require 'calabash'
9
+ include Calabash
10
+
11
+ # @!visibility private
12
+ def self.extended(base)
13
+ Calabash.send(:extended, base)
14
+ end
15
+
16
+ # @!visibility private
17
+ def self.included(base)
18
+ Calabash.send(:included, base)
19
+ end
20
+
21
+ require 'calabash/android/environment'
22
+
23
+ require 'calabash/android/application'
24
+ require 'calabash/android/build'
25
+ require 'calabash/android/device'
26
+ require 'calabash/android/screenshot'
27
+ require 'calabash/android/server'
28
+ require 'calabash/android/adb'
29
+ require 'calabash/android/gestures'
30
+ require 'calabash/android/interactions'
31
+ require 'calabash/android/orientation'
32
+ require 'calabash/android/physical_buttons'
33
+ require 'calabash/android/text'
34
+ require 'calabash/android/console_helpers'
35
+ require 'calabash/android/life_cycle'
36
+
37
+ include Calabash::Android::Gestures
38
+ include Calabash::Android::Interactions
39
+ include Calabash::Android::LifeCycle
40
+ include Calabash::Android::Orientation
41
+ include Calabash::Android::PhysicalButtons
42
+ include Calabash::Android::Text
43
+
44
+ # @!visibility private
45
+ def self.binary_location(name, abi, using_pie)
46
+ binary_name = if using_pie
47
+ "#{name}-pie"
48
+ else
49
+ name
50
+ end
51
+
52
+ file = File.join(File.dirname(__FILE__), 'android', 'lib', name, abi, binary_name)
53
+
54
+ unless File.exist?(file)
55
+ raise "No such file '#{file}'"
56
+ end
57
+
58
+ file
59
+ end
60
+ end
61
+ end
62
+
63
+ # Setup environment on load
64
+ Calabash::Android::Environment.setup
@@ -0,0 +1,277 @@
1
+ require 'timeout'
2
+ require 'open3'
3
+
4
+ module Calabash
5
+ module Android
6
+ # @!visibility private
7
+ class ADB
8
+ # @!visibility private
9
+ class ADBCallError < StandardError
10
+ attr_reader :stderr, :stdout
11
+
12
+ def initialize(message, stderr=nil, stdout=nil)
13
+ super(message)
14
+
15
+ @stderr = stderr
16
+ @stdout = stdout
17
+ end
18
+ end
19
+
20
+ PROCESS_WAIT_TIME = 10
21
+
22
+ def self.open_pipe_with_timeout(timeout, *cmd, &block)
23
+ begin
24
+ i, o, e, t, pid = nil
25
+
26
+ Timeout.timeout(timeout, ProcessDidNotExitError) do
27
+ i, o, e, t = Open3.popen3(*cmd)
28
+ i.sync = true
29
+ o.sync = true
30
+ e.sync = true
31
+ pid = t.pid
32
+ block.call(i, o, e)
33
+
34
+ t.value.exitstatus
35
+ end
36
+ rescue ProcessDidNotExitError => _
37
+ raise ADBCallError, 'ADB process did not exit'
38
+ ensure
39
+ i.close unless i.nil? || i.closed?
40
+ o.close unless o.nil? || o.closed?
41
+ e.close unless e.nil? || e.closed?
42
+
43
+ if pid
44
+ begin
45
+ Process.kill(9, pid)
46
+ rescue Errno::ESRCH => _
47
+ # do nothing
48
+ end
49
+ end
50
+
51
+ t.join if t
52
+ end
53
+ end
54
+
55
+ def self.open_adb_pipe(*cmd, **options, &block)
56
+ timeout = options.fetch(:timeout, PROCESS_WAIT_TIME)
57
+
58
+ open_pipe_with_timeout(timeout, Environment.adb_path, *cmd) do |i, o, e|
59
+ block.call(i, o, e) if block
60
+ end
61
+ end
62
+
63
+ DAEMON_STARTED_MESSAGE = "* daemon not running. starting it now on port 5037 *\n* daemon started successfully *\n"
64
+
65
+ def self.command(*cmd, **args)
66
+ Logger.debug("ADB Command: #{cmd.join(', ')}")
67
+ Logger.debug("ADB input: #{args[:input]}")
68
+ stderr = nil
69
+ stdout = nil
70
+ exit_code = nil
71
+
72
+ input = args[:input]
73
+
74
+ begin
75
+ exit_code = open_adb_pipe(*cmd, args) do |i, o, e|
76
+ if input
77
+ input.each do |p_cmd|
78
+ begin
79
+ i.puts p_cmd
80
+ rescue Errno::EPIPE => err
81
+ i.close
82
+ stderr = e.readlines.join
83
+ stdout = o.readlines.join
84
+ raise ADBCallError.new(err, stderr, stdout)
85
+ end
86
+ end
87
+
88
+ i.close
89
+ end
90
+
91
+ unless args.fetch(:no_read, false)
92
+ stdout = o.readlines.join
93
+ stderr = e.readlines.join
94
+ end
95
+
96
+ if stdout && stdout.start_with?(DAEMON_STARTED_MESSAGE)
97
+ stdout = stdout[DAEMON_STARTED_MESSAGE.length..-1]
98
+ end
99
+ end
100
+ rescue IOError => e
101
+ raise ADBCallError, e
102
+ end
103
+
104
+ if exit_code != 0
105
+ Logger.debug("Adb process exited with #{exit_code}")
106
+ Logger.debug("Error message from ADB: ")
107
+ Logger.debug(stderr)
108
+
109
+ stderr_output = if stderr && !stderr.empty?
110
+ ": #{dot_string(stderr.lines.first, 100)}"
111
+ else
112
+ ''
113
+ end
114
+
115
+ raise ADBCallError.new(
116
+ "Adb process exited with #{exit_code}#{stderr_output}", stderr, stdout)
117
+ end
118
+
119
+ stdout
120
+ end
121
+
122
+ attr_reader :serial
123
+
124
+ def initialize(serial)
125
+ @serial = serial
126
+ end
127
+
128
+ def command(*argv, **args)
129
+ cmd = argv.dup
130
+
131
+ if serial
132
+ cmd.unshift('-s', serial)
133
+ end
134
+
135
+ ADB.command(*cmd, args)
136
+ end
137
+
138
+ END_STRING = '__CAL_END__'
139
+
140
+ def shell(shell_cmd, options={})
141
+ if shell_cmd.nil? || shell_cmd.empty?
142
+ raise ArgumentError, "Invalid shell command '#{shell_cmd}'"
143
+ end
144
+
145
+ input =
146
+ [
147
+ "#{shell_cmd}; echo \"#{END_STRING}$?\"; exit 0"
148
+ ]
149
+
150
+ args = options.merge(input: input)
151
+
152
+ result = command('shell', args)
153
+
154
+ # We get a result like this:
155
+ #
156
+ # [0] "getprop ro.build.version.release; echo \"\r\n",
157
+ # [1] "$?\"; exit 0\r\n",
158
+ # [2] "shell@hammerhead:/ $ getprop ro.build.version.release; echo \"\r\r\n",
159
+ # [3] "> $?\"; exit 0\r\r\n",
160
+ # [4] "4.4\r\n",
161
+ # [5] "\r\n",
162
+ # [6] "0\r\n"
163
+ #
164
+ # out =
165
+ # [4] "4.4\r\n"
166
+ # [5] "\r\n",
167
+ # [6] "0\r\n"
168
+ #
169
+ # command_result =
170
+ # [4] "4.4\r\n"
171
+ # [5] "\r\n",
172
+ #
173
+ # exit_code_s =
174
+ # [6] "0\r\n"
175
+
176
+ index = result.lines.index {|line| line.start_with?(shell_name)}
177
+
178
+ if index.nil?
179
+ raise ADBCallError.new("Could not parse output #{ADB.dot_string(result, 100)}", result)
180
+ end
181
+
182
+ # Remove the commands
183
+ out = result.lines[index+1..-1]
184
+
185
+ last_line = out.last
186
+ end_index = nil
187
+
188
+ 15.times do |i|
189
+ if last_line[-(END_STRING.length+i-1)..-i] == END_STRING
190
+ end_index = -i
191
+ break
192
+ end
193
+ end
194
+
195
+ if end_index.nil?
196
+ raise ADBCallError.new("Could not parse output #{ADB.dot_string(result, 100)}", result)
197
+ end
198
+
199
+ # Get the result from the command
200
+ command_result = out[0..-2].join + last_line[0..(end_index - END_STRING.length)]
201
+
202
+ # Get the exit code
203
+ exit_code_s = out[-1][end_index+1..-1]
204
+
205
+ unless options[:no_exit_code_check]
206
+ unless exit_code_s.to_i.to_s == exit_code_s.chomp
207
+ raise ADBCallError,
208
+ "Unable to obtain exit code. Result: '#{exit_code_s}'"
209
+ end
210
+
211
+ exit_code = exit_code_s.to_i
212
+
213
+ if exit_code != 0
214
+ Logger.debug("Adb shell command exited with #{exit_code}")
215
+ Logger.debug("Error message from ADB: ")
216
+ Logger.debug(command_result)
217
+
218
+ stderr_output = if command_result && !command_result.empty?
219
+ ": #{ADB.dot_string(command_result.lines.first, 100)}"
220
+ else
221
+ ''
222
+ end
223
+
224
+ raise ADBCallError.new(
225
+ "Adb shell command exited with #{exit_code}#{stderr_output}", command_result)
226
+ end
227
+ end
228
+
229
+ command_result
230
+ end
231
+
232
+ private
233
+
234
+ def self.dot_string(string, length)
235
+ if string.length > length
236
+ "#{string[0, length-3]}..."
237
+ else
238
+ string
239
+ end
240
+ end
241
+
242
+ def shell_name
243
+ if @shell_name
244
+ @shell_name
245
+ else
246
+ result = command('shell', input: ['echo "test"; exit 0'])
247
+
248
+ # result.lines =
249
+ # [
250
+ # [0] "echo \"foo\"; exit 0\r\n",
251
+ # [1] "shell@hammerhead:/ $ echo \"foo\"; exit 0\r\r\n",
252
+ # [2] "foo\r\n"
253
+ # ]
254
+ #
255
+ # OR
256
+ #
257
+ # result.lines =
258
+ # [
259
+ # [1] "shell@hammerhead:/ $ echo \"foo\"; exit 0\r\r\n",
260
+ # [2] "foo\r\n"
261
+ # ]
262
+
263
+ #result.lines.index {|line| !line.start_with?('echo')}
264
+
265
+ # "shell@hammerhead:/ $ echo \"foo\"; exit 0\r\r\n"
266
+ shell_name_line = result.lines[-2]
267
+
268
+ # "shell@hammerhead:/ $ "
269
+ @shell_name = shell_name_line.split('echo').first
270
+ end
271
+ end
272
+
273
+ # @!visibility private
274
+ class ProcessDidNotExitError < RuntimeError; end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,110 @@
1
+ module Calabash
2
+ module Android
3
+ # A class to represent an Android application (.apk).
4
+ class Application < Calabash::Application
5
+ attr_reader :test_server
6
+
7
+ def self.default_from_environment
8
+ application_path = Environment::APP_PATH
9
+
10
+ if application_path.nil?
11
+ raise 'No application path is set'
12
+ end
13
+
14
+ unless File.exist?(application_path)
15
+ raise "Application '#{application_path}' does not exist"
16
+ end
17
+
18
+ if File.directory?(application_path)
19
+ raise "Application '#{application_path}' is not a file"
20
+ end
21
+
22
+ build_test_server = Build::TestServer.new(application_path)
23
+ test_server_path = Environment::TEST_SERVER_PATH ||
24
+ build_test_server.path
25
+
26
+ unless File.exist?(test_server_path)
27
+ Logger.error "Test-server '#{test_server_path}' does not exist."
28
+ Logger.error "Build it using: 'calabash build \"#{application_path}\"'"
29
+ Logger.error ''
30
+ raise "Test-server '#{test_server_path}' does not exist."
31
+ end
32
+
33
+ Application.new(application_path, test_server_path)
34
+ end
35
+
36
+ def initialize(application_path, test_server_path, options = {})
37
+ super(application_path, options)
38
+ @test_server = Application.new(test_server_path, nil, options) if test_server_path
39
+ end
40
+
41
+ def extract_identifier
42
+ package_line = aapt_dump('package').first
43
+ raise "'package' not found in aapt output" unless package_line
44
+ m = package_line.match(/name='([^']+)'/)
45
+ raise "Unexpected output from aapt: #{package_line}" unless m
46
+ m[1]
47
+ end
48
+
49
+ def main_activity
50
+ begin
51
+ @logger.log("Trying to find launchable activity")
52
+ launchable_activity_line = aapt_dump('launchable-activity').first
53
+ raise "'launchable-activity' not found in aapt output" unless launchable_activity_line
54
+ m = launchable_activity_line.match(/name='([^']+)'/)
55
+ raise "Unexpected output from aapt: #{launchable_activity_line}" unless m
56
+ @logger.log("Found launchable activity '#{m[1]}'")
57
+ m[1]
58
+ rescue => e
59
+ @logger.log("Could not find launchable activity, trying to parse raw AndroidManifest. #{e.message}")
60
+
61
+ manifest_data = `"#{Environment.aapt_path}/aapt" dump xmltree "#{@path}" AndroidManifest.xml`
62
+ regex = /^\s*A:[\s*]android:name\(\w+\)\=\"android.intent.category.LAUNCHER\"/
63
+ lines = manifest_data.lines.collect(&:strip)
64
+ indicator_line = nil
65
+
66
+ lines.each_with_index do |line, index|
67
+ match = line.match(regex)
68
+
69
+ unless match.nil?
70
+ raise 'More than one launchable activity in AndroidManifest' unless indicator_line.nil?
71
+ indicator_line = index
72
+ end
73
+ end
74
+
75
+ raise 'No launchable activity found in AndroidManifest' unless indicator_line
76
+
77
+ intent_filter_found = false
78
+
79
+ (0..indicator_line).reverse_each do |index|
80
+ if intent_filter_found
81
+ match = lines[index].match(/\s*E:\s*activity-alias/)
82
+
83
+ raise 'Could not find target activity in activity alias' if match
84
+
85
+ match = lines[index].match(/^\s*A:\s*android:targetActivity\(\w*\)\=\"([^\"]+)/){$1}
86
+
87
+ if match
88
+ @logger.log("Found launchable activity '#{match}'")
89
+
90
+ return match
91
+ end
92
+ else
93
+ unless lines[index].match(/\s*E: intent-filter/).nil?
94
+ @logger.log("Read intent filter")
95
+ intent_filter_found = true
96
+ end
97
+ end
98
+ end
99
+
100
+ raise 'Could not find launchable activity'
101
+ end
102
+ end
103
+
104
+ def aapt_dump(key)
105
+ lines = `"#{Environment.aapt_path}" dump badging "#{path}"`.lines.collect(&:strip)
106
+ lines.select { |l| l.start_with?("#{key}:") }
107
+ end
108
+ end
109
+ end
110
+ end