# Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
import time
import pytest
import sys
import os.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))
from harness import log
from harness.harness import Harness
from harness import utils
from harness.interface.error import TestError, Error
from harness.interface.CDCSerial import Keytype, CDCSerial as serial
from harness.interface.defs import key_codes
simulator_port = 'simulator'
def pytest_addoption(parser):
parser.addoption("--port", type=str, action="store", required=False)
parser.addoption("--timeout", type=int, action="store", default=15)
parser.addoption("--phone_number", type=int, action="store")
parser.addoption("--call_duration", type=int, action="store", default=30)
parser.addoption("--sms_text", type=str, action="store", default='')
parser.addoption("--bt_device", type=str, action="store", default='')
@pytest.fixture(scope='session')
def phone_number(request):
phone_number = request.config.option.phone_number
assert phone_number
return phone_number
@pytest.fixture(scope='session')
def call_duration(request):
call_duration = request.config.option.call_duration
assert call_duration
return call_duration
@pytest.fixture(scope='session')
def sms_text(request):
sms_text = request.config.option.sms_text
assert sms_text != ''
return sms_text
@pytest.fixture(scope='session')
def bt_device(request):
bt_device = request.config.option.bt_device
return bt_device
@pytest.fixture(scope='session')
def harness(request):
'''
Try to init one Pure phone with serial port path or automatically
'''
port_name = request.config.option.port
TIMEOUT = request.config.option.timeout
timeout_started = time.time()
RETRY_EVERY_SECONDS = 1.0
try:
if port_name is None:
log.warning("no port provided! trying automatic detection")
harness = None
with utils.Timeout.limit(seconds=TIMEOUT):
while not harness:
try:
harness = Harness.from_detect()
except TestError as e:
if e.get_error_code() == Error.PORT_NOT_FOUND:
log.info(f"waiting for a serial port… ({TIMEOUT- int(time.time() - timeout_started)})")
time.sleep(RETRY_EVERY_SECONDS)
else:
assert '/dev' in port_name or simulator_port in port_name
if simulator_port in port_name:
file = None
with utils.Timeout.limit(seconds=TIMEOUT):
while not file:
try:
file = open("/tmp/purephone_pts_name", "r")
except FileNotFoundError as err:
log.info(
f"waiting for a simulator port… ({TIMEOUT- int(time.time() - timeout_started)})")
time.sleep(RETRY_EVERY_SECONDS)
port_name = file.readline()
if port_name.isascii():
log.debug("found {} entry!".format(port_name))
else:
pytest.exit("not a valid sim pts entry!")
harness = Harness(port_name)
'''
Wait for endpoints to initialize
'''
testbody = {"ui": True, "getWindow": True}
result = None
with utils.Timeout.limit(seconds=305):
while not result:
try:
result = harness.endpoint_request("developerMode", "get", testbody)
except ValueError:
log.info("Endpoints not ready..")
except utils.Timeout:
pytest.exit("couldn't find any viable port. exiting")
else:
return harness
@pytest.fixture(scope='session')
def harnesses():
'''
Automatically init at least two Pure phones
'''
connected_devices = serial.find_Devices()
harnesses = [Harness(device) for device in connected_devices]
if not len(harnesses) >= 2:
pytest.skip("At least two phones are needed for this test")
assert len(harnesses) >= 2
return harnesses
@pytest.fixture(scope='session')
def phone_unlocked(harness):
harness.unlock_phone()
assert not harness.is_phone_locked()
@pytest.fixture(scope='session')
def phone_locked(harness):
harness.lock_phone()
assert harness.is_phone_locked()
@pytest.fixture(scope='session')
def phones_unlocked(harnesses):
for harness in harnesses:
harness.unlock_phone()
assert not harness.is_phone_locked()
@pytest.fixture(scope='session')
def phone_in_desktop(harness):
# go to desktop
if harness.get_application_name() != "ApplicationDesktop":
harness.connection.send_key_code(key_codes["fnRight"], Keytype.long_press)
# in some cases we have to do it twice
if harness.get_application_name() != "ApplicationDesktop":
harness.connection.send_key_code(key_codes["fnRight"], Keytype.long_press)
# assert that we are in ApplicationDesktop
assert harness.get_application_name() == "ApplicationDesktop"
@pytest.fixture(scope='function')
def phone_ends_test_in_desktop(harness):
yield
target_application = "ApplicationDesktop"
target_window = "MainWindow"
log.info(f"returning to {target_window} of {target_application} ...")
time.sleep(1)
if harness.get_application_name() != target_application :
body = {"switchApplication" : {"applicationName": target_application, "windowName" : target_window }}
harness.endpoint_request("developerMode", "put", body)
time.sleep(1)
max_retry_counter = 5
while harness.get_application_name() != target_application:
max_retry_counter -= 1
if max_retry_counter == 0:
break
log.info(f"Not in {target_application}, {max_retry_counter} attempts left...")
time.sleep(1)
else :
# switching window in case ApplicationDesktop is not on MainWindow:
body = {"switchWindow" : {"applicationName": target_application, "windowName" : target_window }}
harness.endpoint_request("developerMode", "put", body)
time.sleep(1)
# assert that we are in ApplicationDesktop
assert harness.get_application_name() == target_application
time.sleep(1)
def pytest_configure(config):
config.addinivalue_line("markers",
"service_desktop_test: mark test if it's related to service-desktop API")
config.addinivalue_line("markers",
"rt1051: mark test if it's target only (eg. calls, messages)")
config.addinivalue_line("markers",
"usb_cdc_echo: mark test if it's intended for usb-cdc echo mode")
config.addinivalue_line("markers",
"two_sim_cards: mark test in case when two sim cards are required")
config.addinivalue_line("markers",
"backup: subset of backup user data tests")
config.addinivalue_line("markers",
"restore: subset of restore user data tests")