1+ import json
12import logging
23import os
34import subprocess
4- import json
5- import telnetlib
6- import os
7-
5+ import requests
86
97THIS_DIR = os .path .dirname (os .path .abspath (__file__ ))
108execfile (os .path .join (THIS_DIR , 'version.py' ))
@@ -106,29 +104,28 @@ def stop_emulator(self):
106104
107105 self ._emulator_proc = None
108106
109- def set_package_name (self , package_name ):
110- self ._package_name = package_name
107+ def _execute_and_output_does_not_contain_error (self , * args ):
108+ output = self ._execute (* args )
109+ assert 'Error' not in output , output
110+ return output
111+
112+ def uninstall_application (self , package_name ):
113+ self ._execute_and_output_does_not_contain_error ([self ._adb , "uninstall" , package_name ])
111114
112- def install_apk (self , test_apk_path , app_apk_path ):
115+ def install_application (self , apk_file ):
113116 '''
114117 Installs the given Android application package file (APK) on the emulator along with the test server.
115118
116119 For instrumentation (and thus all remote keywords to work) both .apk
117120 files must be signed with the same key.
118121
119- `test_apk_path` Path to the Test.apk, usually at 'features/support/Test.apk'
120- `app_apk_path` Path the the application you want to test
122+ `apk_file` Path the the application to install
121123 '''
122124
123- def execute_and_output_does_not_contain_error (* args ):
124- output = self ._execute (* args )
125- assert 'Error' not in output , output
126- return output
125+ # TODO polling for package manager
126+ # http://code.google.com/p/android/issues/detail?id=842#c7
127127
128- execute_and_output_does_not_contain_error ([self ._adb , "uninstall" , "%s.test" % self ._package_name ])
129- execute_and_output_does_not_contain_error ([self ._adb , "uninstall" , self ._package_name ])
130- execute_and_output_does_not_contain_error ([self ._adb , "install" , "-r" , test_apk_path ])
131- execute_and_output_does_not_contain_error ([self ._adb , "install" , "-r" , app_apk_path ])
128+ self ._execute_and_output_does_not_contain_error ([self ._adb , "install" , "-r" , apk_file ])
132129
133130 def wait_for_device (self ):
134131 '''
@@ -150,29 +147,38 @@ def press_menu_button(self):
150147 '''
151148 self .send_key (82 )
152149
153- def start_testserver (self ):
150+ def start_testserver (self , package_name ):
154151 '''
155152 Start the remote test server inside the Android Application.
153+
154+ `package_name` fully qualified name of the application to test
155+
156156 '''
157157 self ._execute ([
158158 self ._adb ,
159+ "wait-for-device" ,
159160 "forward" ,
160161 "tcp:%d" % 34777 ,
161- "tcp:7101 "
162+ "tcp:7102 "
162163 ])
163164
164165 args = [
165166 self ._adb ,
167+ "wait-for-device" ,
166168 "shell" ,
167169 "am" ,
168170 "instrument" ,
169171 "-w" ,
170172 "-e" ,
171173 "class" ,
172174 "sh.calaba.instrumentationbackend.InstrumentationBackend" ,
173- "%s.test/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner" % self . _package_name ,
175+ "%s.test/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner" % package_name ,
174176 ]
175177
178+ self ._host = 'localhost'
179+ self ._port = 34777
180+ self ._url = 'http://%s:%d' % (self ._host , self ._port )
181+
176182 logging .debug ("$> %s" , ' ' .join (args ))
177183 self ._testserver_proc = subprocess .Popen (args )
178184
@@ -183,25 +189,27 @@ def connect_to_testserver(self):
183189 Application. Performs a handshake.
184190 '''
185191
186- host = 'localhost'
187- port = 34777
188-
189- self ._connection = telnetlib .Telnet (host , port )
192+ response = requests .get (self ._url + '/ping' )
190193
191- # secret calabash handshake
192- self ._connection .write ("Ping!\n " )
193- self ._connection .read_until ("Pong!\n " )
194+ assert response .status_code == 200 , "InstrumentationBackend sent status %d, expected 200" % response .status_code
195+ assert response .text == 'pong' , "InstrumentationBackend replied '%s', expected 'pong'" % response .text
194196
195197 def _perform_action (self , command , * arguments ):
196198 action = json .dumps ({
197199 "command" : command ,
198200 "arguments" : arguments ,
199- }) + '\n '
201+ })
202+
200203 logging .debug (">> %r" , action )
201- self ._connection .write (action )
202- result = self ._connection .read_until ('\n ' )
203- logging .debug ("<< %r" , result )
204- return json .loads (result )
204+
205+ response = requests .post (self ._url ,
206+ data = { 'command' : action },
207+ headers = { 'Content-Type' : 'application/x-www-form-urlencoded' },
208+ )
209+
210+ logging .debug ("<< %r" , response .text )
211+ assert response .status_code == 200 , "InstrumentationBackend sent status %d, expected 200" % response .status_code
212+ return response .json
205213
206214 # BEGIN: STOLEN FROM SELENIUM2LIBRARY
207215
@@ -234,23 +242,13 @@ def capture_screenshot(self, filename=None):
234242 '''
235243
236244 path , link = self ._get_screenshot_paths (filename )
245+ response = requests .get (self ._url + '/screenshot' )
237246
238- jar = os .path .join (os .path .dirname (__file__ ), 'screenShotTaker.jar' )
239-
240- args = ["java" , "-jar" , jar , path ]
241-
242- logging .debug ("$> %s" , ' ' .join (args ))
243-
244- screenshot_taking_proc = subprocess .Popen (args , env = {
245- "ANDROID_HOME" : self ._ANDROID_HOME
246- })
247- # TODO the screenshot taking command does not terminate if there is an
248- # error (such as a too small timeout)
249-
250- # details see
251- # https://github.com/calabash/calabash-android/issues/69
247+ with open (path , 'w' ) as f :
248+ f .write (response .content )
249+ f .close ()
252250
253- # screenshot_taking_proc.wait()
251+ assert response . status_code == 200 , "InstrumentationBackend sent status %d, expected 200" % response . status_code
254252
255253 logger .info ('</td></tr><tr><td colspan="3"><a href="%s">'
256254 '<img src="%s"></a>' % (link , link ), True , False )
0 commit comments