Skip to content
This repository was archived by the owner on Sep 27, 2021. It is now read-only.

Commit df126b9

Browse files
committed
Use HTTP to talk to calabash-android (>0.2.0)
also, revamp tests to be more reliable
1 parent 9743cef commit df126b9

File tree

9 files changed

+95
-89
lines changed

9 files changed

+95
-89
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ MANIFEST
55
dist/
66
parts/
77
src/robotframework_androidlibrary.egg-info/
8-
features/
98
develop-eggs/robotframework-androidlibrary.egg-link
10-
.calabash_settings
119
android-screenshot-*.png
1210
log.html
1311
output.xml
1412
report.html
1513
ApiDemos.apk
14+
test_servers/

DEVELOPMENT.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ Prerequisites
1111
=============
1212

1313
- Install the `Android SDK <http://developer.android.com/sdk/index.html>`_
14-
- Install calabash-android v0.1.0::
14+
- Install calabash-android v0.2.9::
1515

16-
gem install --version '= 0.1.0' calabash-android
16+
gem install --version '= 0.2.9' calabash-android
1717

1818
- Create a debug keystore::
1919

README.rst

+2-7
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,9 @@ To install, just fetch the latest version from PyPI::
2121
Prepare your App
2222
++++++++++++++++
2323

24-
robotframework-androidlibrary works only with::
24+
robotframework-androidlibrary uses calabash-android underneath. To install calabash-android (we've only tested this with v0.2.9 yet), use the following command::
2525

26-
calabash-android 0.1.0
27-
28-
29-
To install calabash-android::
30-
31-
gem install --version '= 0.1.0' calabash-android
26+
gem install --version '= 0.2.9' calabash-android
3227

3328
To prepare your android app look at <https://github.com/calabash/calabash-android#installation>
3429

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
zip_safe = False,
2828
classifiers = CLASSIFIERS.splitlines(),
2929
package_dir = {'' : 'src'},
30-
install_requires = ['robotframework'],
30+
install_requires = ['robotframework', 'requests'],
3131
packages = ['AndroidLibrary'],
3232
package_data = {'AndroidLibrary': ['src/AndroidLibrary/*.jar']}
3333
)

src/AndroidLibrary/__init__.py

+45-47
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1+
import json
12
import logging
23
import os
34
import subprocess
4-
import json
5-
import telnetlib
6-
import os
7-
5+
import requests
86

97
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
108
execfile(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)
-1.51 MB
Binary file not shown.

tests/apidemos/__init__.txt

+29-29
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,13 @@ Resource variables.txt
55
Library AndroidLibrary
66
Library OperatingSystem
77

8-
Suite Setup Setup Suite
9-
Suite Teardown Stop Emulator
8+
#Suite Setup Setup Suite
9+
#Suite Teardown Stop Emulator
1010

1111
Documentation Tests the ApiDemos.apk that is included in the Android SDK
1212

1313
*** Keywords ***
1414

15-
Execute [Arguments] ${command}
16-
${rc} ${output} = Run And Return Rc And Output ${command}
17-
Should Be Equal As Integers ${rc} 0
18-
1915
Setup Suite
2016

2117
Android SDK Should Exist
@@ -29,7 +25,7 @@ Setup Suite
2925
Re-Sign ApiDemos.apk with Debug Keystore
3026
Build Instrumentation App
3127

32-
Wait Until Keyword Succeeds 1m 5s Install App
28+
Install App
3329

3430
Stop Emulator
3531

@@ -44,38 +40,42 @@ Create Android Virtual Device
4440
Execute echo "no" | %{ANDROID_HOME}/tools/android --silent create avd --name ${EMULATOR_NAME} --force -t android-${API_LEVEL}
4541

4642
Pull ApiDemos.apk from Device
47-
[Timeout] 120s
48-
Wait For Device
43+
[Timeout] 2 minutes
44+
45+
Wait Until Keyword Succeeds 5 seconds 30 seconds
46+
... Wait For Device
47+
4948
Remove File ApiDemos.apk
50-
Execute %{ANDROID_HOME}/platform-tools/adb pull /data/app/ApiDemos.apk
49+
50+
Wait Until Keyword Succeeds 5 seconds 30 seconds
51+
... Execute %{ANDROID_HOME}/platform-tools/adb pull /data/app/ApiDemos.apk
5152

5253
Re-Sign ApiDemos.apk with Debug Keystore
5354
File Should Exist ApiDemos.apk
5455
Execute zip -d ApiDemos.apk META-INF/*
5556
Execute echo "android" | jarsigner -verbose -keystore $HOME/.android/debug.keystore ApiDemos.apk androiddebugkey
5657

5758
Build Instrumentation App
58-
Remove File .calabash_settings
59-
${settings}= Catenate
60-
... {
61-
... "activity_name": "com.example.android.apis.ApiDemos",
62-
... "api_level": "${API_LEVEL}",
63-
... "app_path": "%{PWD}/ApiDemos.apk",
64-
... "keystore_alias": "androiddebugkey",
65-
... "keystore_alias_password": "debug",
66-
... "keystore_location": "%{HOME}/.android/debug.keystore",
67-
... "keystore_password": "android",
68-
... "package_name": "com.example.android.apis"
69-
... }
70-
Set Package Name com.example.android.apis
71-
Create File .calabash_settings ${settings}
72-
Execute calabash-android build
59+
Remove Directory ${EXECDIR}/test_servers/ recursive=True
60+
Execute calabash-android build ApiDemos.apk
61+
62+
${TEST_SERVERS}= List Directory ${EXECDIR}/test_servers/
63+
Set Global Variable ${TEST_APK} ${TEST_SERVERS[0]}
7364

7465
Install App
75-
[Timeout] 120s
66+
[Timeout] 2 minutes
67+
7668
Wait for Device
7769

78-
Install APK
79-
... ${EXECDIR}/features/support/Test.apk
80-
... ${EXECDIR}/ApiDemos.apk
70+
Wait Until Keyword Succeeds 5 seconds 30 seconds
71+
... Uninstall Application com.example.android.apis
72+
73+
Wait Until Keyword Succeeds 5 seconds 30 seconds
74+
... Uninstall Application com.example.android.apis.test
75+
76+
Wait Until Keyword Succeeds 5 seconds 30 seconds
77+
... Install Application ${EXECDIR}/test_servers/${TEST_APK}
78+
79+
Wait Until Keyword Succeeds 5 seconds 30 seconds
80+
... Install Application ${EXECDIR}/ApiDemos.apk
8181

tests/apidemos/apidemos.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ Setup Suite
1616
Start Emulator ${EMULATOR_NAME} no_window=${HEADLESS_BOOL}
1717
Wait For Device
1818
Press Menu Button
19+
Execute %{ANDROID_HOME}/platform-tools/adb shell setprop log.redirect-stdio true
1920

2021
Setup Test
21-
Start Testserver
22+
Start Testserver com.example.android.apis
23+
24+
Sleep 5 seconds
25+
2226
Wait Until Keyword Succeeds
2327
... 1min
2428
... 5sec

tests/apidemos/variables.txt

+10
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@ ${API_LEVEL}= 8
55
${SKIP_SETUP}= False
66
${HEADLESS}= True
77

8+
*** Settings ***
9+
10+
Library OperatingSystem
11+
12+
*** Keywords ***
13+
14+
Execute [Arguments] ${command}
15+
${rc} ${output} = Run And Return Rc And Output ${command}
16+
Should Be Equal As Integers ${rc} 0
17+

0 commit comments

Comments
 (0)