-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathharness.py
202 lines (162 loc) · 6.53 KB
/
harness.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
import random
from . import utils
from . import log
from .utils import send_keystoke
from .utils import application_keypath
from .utils import send_char
from .utils import clear_last_char
from .interface import CDCSerial as serial
from .interface.error import TestError
from .interface.error import Error
from .interface.defs import key_codes
from .interface.defs import endpoint
from .interface.defs import method
from .interface.defs import default_pin
from .interface.defs import Method, Endpoint
from .request import Transaction, Request
class Harness:
'''
harness class
WARN: please see that variables below are not class local
'''
is_echo_mode = False
port_name = ''
def __init__(self, port):
self.port_name = port
self.connection = serial.CDCSerial(port)
self.phone_mode_lock = False
@classmethod
def from_detect(cls):
'''
Try to instantiate from first detected device.
Do not use this method if you need >1 unique devices.
'''
found = serial.CDCSerial.find_Devices()
if found:
port = found[0]
return cls(port)
else:
raise TestError(Error.PORT_NOT_FOUND)
def get_connection(self):
return self.connection
def set_connection(self, connection):
Harness.connection = connection
self.connection = connection
def get_application_name(self):
return self.connection.get_application_name()
def is_phone_locked(self):
return self.connection.is_phone_locked()
def set_phone_mode_lock_state(self, enabled: bool):
self.phone_mode_lock = enabled
def is_phone_mode_locked(self):
return self.phone_mode_lock
def enter_passcode(self, pin=default_pin):
utils.validate_pin(pin)
if self.connection.is_phone_locked():
self.connection.send_key_code(key_codes["enter"])
self.connection.send_key_code(key_codes["#"])
for digit in pin:
self.connection.send_key_code(digit)
def lock_phone(self):
if not self.is_phone_locked():
if not self.get_application_name() == "ApplicationDesktop":
self.return_to_home_screen()
self.connection.send_key_code(key_codes["#"], serial.Keytype.long_press)
log.info("Phone locked")
else:
log.info("Phone already locked")
def unlock_phone(self):
if self.is_phone_locked():
self.enter_passcode()
log.info("Phone unlocked")
else:
log.info("Phone already unlocked")
def with_phone_unlocked(self, func):
if self.is_phone_locked():
self.unlock_phone()
func(self.connection)
def return_to_last_screen(self):
self.connection.send_key_code(key_codes["fnRight"])
def return_to_home_screen(self):
self.connection.send_key_code(key_codes["fnRight"], serial.Keytype.long_press)
def connection_echo_mode_on(self):
if self.connection.enable_echo_mode():
self.is_echo_mode = True
def connection_echo_mode_off(self):
if self.connection.disable_echo_mode():
self.is_echo_mode = False
def open_application(self, app):
send_keystoke(application_keypath[app], self.connection)
def send_text(self, text: str):
clear_last_char()
for letter in text:
try:
send_char(letter, self.connection)
except KeyError as e:
available = ' '.join((f"'{_}'" for _ in utils.keymap.keys()))
raise LookupError(f"Character {e} not present in the keymap\nAvailable characters: {available}")
def send_number(self, number: str):
utils.send_number(number, self.connection)
def request(self, endpoint: Endpoint, method: Method, data: dict) -> Transaction:
'''
sends data to device and gets response
the same as endpoint_request except:
- works on types
- throws in case of error
- provides execution time
use example:
```
body = {"txID": txID, "chunkNo": chunkNo, "data": data}
ret = harness.request(Endpoint.FILESYSTEM, Method.PUT, body)
assert ret.response.body["txID"] != 0
```
'''
t = Transaction(Request(endpoint.value, method.value, data, random.randint(1, 32000)))
t.accept(self.connection.write(t.request.to_dict()))
r, w = self.connection.get_timing()
r = r.elapsed()
w = w.elapsed()
t.set_elapsed(r, w)
return t
def endpoint_request(self, ep_name: str, met: str, body: dict) -> dict:
ret = self.connection.write({
"endpoint": endpoint[ep_name],
"method": method[met],
"uuid": random.randint(1, 32000),
"body": body
})
return ret
def turn_phone_off(self):
log.info("Turning phone off...")
app_desktop = "ApplicationDesktop"
end_loop_counter = 10
while not self.get_application_name() == app_desktop:
if not end_loop_counter > 0:
raise LookupError("Filed to switch to {}".format(app_desktop))
log.info("Not on the Application Desktop, fnRight.")
self.connection.send_key_code(key_codes["fnRight"], serial.Keytype.long_press)
end_loop_counter -= 1
self.connection.send_key_code(key_codes["fnRight"], serial.Keytype.long_press)
self.connection.send_key_code(key_codes["right"])
self.connection.send_key_code(key_codes["enter"])
def set_tethering_state(self, enabled: bool):
state = 'on' if enabled else 'off'
body = {"tethering": state}
log.info(f"Set tethering state to: {state}")
return self.endpoint_request("developerMode", "put", body)
def press_fun_left(self):
self.connection.send_key_code(key_codes["fnLeft"])
def press_fun_right(self):
self.connection.send_key_code(key_codes["fnRight"])
def press_fun_center(self):
self.connection.send_key_code(key_codes["enter"])
def press_nav_left(self):
self.connection.send_key_code(key_codes["left"])
def press_nav_right(self):
self.connection.send_key_code(key_codes["right"])
def press_nav_up(self):
self.connection.send_key_code(key_codes["up"])
def press_nav_down(self):
self.connection.send_key_code(key_codes["down"])