parent
fc15f82e1b
commit
4da388b5bc
|
@ -1,23 +1,29 @@
|
||||||
|
import configs
|
||||||
import drivers.SquishDriver as driver
|
import drivers.SquishDriver as driver
|
||||||
import drivers.SquishDriverVerification as verification
|
import drivers.SquishDriverVerification as verification
|
||||||
import drivers.SDKeyboardCommands as keyCommands
|
import drivers.SDKeyboardCommands as keyCommands
|
||||||
|
|
||||||
def start_application(app_name: str):
|
|
||||||
driver.start_application(app_name)
|
def start_application(app_data_dir=configs.path.STATUS_APP_DATA, clear_user_data: bool = True):
|
||||||
|
driver.start_application(app_data_dir=app_data_dir, clear_user_data=clear_user_data)
|
||||||
|
|
||||||
|
|
||||||
def click_on_an_object(objName: str):
|
def click_on_an_object(objName: str):
|
||||||
driver.click_obj_by_name(objName)
|
driver.click_obj_by_name(objName)
|
||||||
|
|
||||||
|
|
||||||
def input_text(text: str, objName: str):
|
def input_text(text: str, objName: str):
|
||||||
driver.type_text(objName, text)
|
driver.type_text(objName, text)
|
||||||
|
|
||||||
|
|
||||||
def object_not_enabled(objName: str):
|
def object_not_enabled(objName: str):
|
||||||
verification.verify_object_enabled(objName, 500, False)
|
verification.verify_object_enabled(objName, 500, False)
|
||||||
|
|
||||||
|
|
||||||
def str_to_bool(string: str):
|
def str_to_bool(string: str):
|
||||||
return string.lower() in ["yes", "true", "1", "y", "enabled"]
|
return string.lower() in ["yes", "true", "1", "y", "enabled"]
|
||||||
|
|
||||||
|
|
||||||
def clear_input_text(objName: str):
|
def clear_input_text(objName: str):
|
||||||
keyCommands.press_select_all(objName)
|
keyCommands.press_select_all(objName)
|
||||||
keyCommands.press_backspace(objName)
|
keyCommands.press_backspace(objName)
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
from . import path
|
||||||
from . import squish
|
from . import squish
|
|
@ -0,0 +1,10 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from utils.system_path import SystemPath
|
||||||
|
|
||||||
|
ROOT: SystemPath = SystemPath(__file__).resolve().parent.parent.parent
|
||||||
|
TMP: SystemPath = ROOT / 'tmp'
|
||||||
|
|
||||||
|
AUT: SystemPath = SystemPath(os.getenv('AUT_PATH', ROOT.parent.parent / 'bin' / 'nim_status_client'))
|
||||||
|
STATUS_APP_DATA = TMP / 'Status'
|
||||||
|
STATUS_USER_DATA: SystemPath = STATUS_APP_DATA / 'data'
|
|
@ -1,3 +1,3 @@
|
||||||
|
|
||||||
UI_LOAD_TIMEOUT_MSEC = 5000
|
UI_LOAD_TIMEOUT_MSEC = 5000
|
||||||
APP_LOAD_TIMEOUT_MSEC = 60000
|
APP_LOAD_TIMEOUT_MSEC = 60000
|
||||||
|
PROCESS_LOAD_TIMEOUT_MSEC = 10000
|
||||||
|
|
|
@ -10,18 +10,20 @@
|
||||||
import copy
|
import copy
|
||||||
import sys
|
import sys
|
||||||
import test
|
import test
|
||||||
import time
|
|
||||||
|
|
||||||
import configs
|
import configs
|
||||||
import names
|
import names
|
||||||
import object
|
import object
|
||||||
import objectMap
|
import objectMap
|
||||||
|
import toplevelwindow
|
||||||
|
import utils.FileManager as filesMngr
|
||||||
# IMPORTANT: It is necessary to import manually the Squish drivers module by module.
|
# IMPORTANT: It is necessary to import manually the Squish drivers module by module.
|
||||||
# More info in: https://kb.froglogic.com/display/KB/Article+-+Using+Squish+functions+in+your+own+Python+modules+or+packages
|
# More info in: https://kb.froglogic.com/display/KB/Article+-+Using+Squish+functions+in+your+own+Python+modules+or+packages
|
||||||
import squish
|
|
||||||
import toplevelwindow
|
|
||||||
from objectmaphelper import Wildcard
|
from objectmaphelper import Wildcard
|
||||||
|
from utils.system_path import SystemPath
|
||||||
|
|
||||||
|
from .aut import * # noqa
|
||||||
|
from .context import * # noqa
|
||||||
from .elements import * # noqa
|
from .elements import * # noqa
|
||||||
|
|
||||||
# The default maximum timeout to find ui object
|
# The default maximum timeout to find ui object
|
||||||
|
@ -36,18 +38,16 @@ _MAX_WAIT_APP_TIMEOUT = 15000
|
||||||
_SEARCH_IMAGES_PATH = "../shared/searchImages/"
|
_SEARCH_IMAGES_PATH = "../shared/searchImages/"
|
||||||
|
|
||||||
|
|
||||||
def start_application(app_name: str, attempt=2):
|
def start_application(
|
||||||
try:
|
fp: SystemPath = configs.path.AUT,
|
||||||
ctx = squish.startApplication(app_name)
|
app_data_dir: SystemPath = configs.path.STATUS_APP_DATA,
|
||||||
assert squish.waitFor(lambda: ctx.isRunning, _MAX_WAIT_APP_TIMEOUT), 'Start application error'
|
clear_user_data: bool = True
|
||||||
|
):
|
||||||
|
if clear_user_data:
|
||||||
|
filesMngr.clear_directory(str(app_data_dir / 'data'))
|
||||||
|
app_data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
ExecutableAut(fp).start(f'--datadir={app_data_dir}')
|
||||||
toplevelwindow.ToplevelWindow(squish.waitForObject(names.statusDesktop_mainWindow)).maximize()
|
toplevelwindow.ToplevelWindow(squish.waitForObject(names.statusDesktop_mainWindow)).maximize()
|
||||||
except (AssertionError, RuntimeError):
|
|
||||||
if attempt:
|
|
||||||
[ctx.detach() for ctx in squish.applicationContextList()]
|
|
||||||
time.sleep(1)
|
|
||||||
start_application(app_name, attempt - 1)
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
# Waits for the given object is loaded, visible and enabled.
|
# Waits for the given object is loaded, visible and enabled.
|
||||||
|
|
|
@ -17,14 +17,17 @@ _MAX_WAIT_CLOSE_APP_TIMEOUT = 20
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
def verify_screen(objName: str, timeout: int=1000):
|
def verify_screen(objName: str, timeout: int=1000):
|
||||||
|
from drivers.SquishDriver import is_loaded_visible_and_enabled
|
||||||
result = is_loaded_visible_and_enabled(objName, timeout)
|
result = is_loaded_visible_and_enabled(objName, timeout)
|
||||||
test.verify(result, f'Verifying screen for real-name {objName}')
|
test.verify(result, f'Verifying screen for real-name {objName}')
|
||||||
|
|
||||||
def verify_object_enabled(objName: str, timeout: int=_MIN_WAIT_OBJ_TIMEOUT, condition: bool=True):
|
def verify_object_enabled(objName: str, timeout: int=_MIN_WAIT_OBJ_TIMEOUT, condition: bool=True):
|
||||||
|
from drivers.SquishDriver import is_loaded_visible_and_enabled
|
||||||
result = is_loaded_visible_and_enabled(objName, timeout)
|
result = is_loaded_visible_and_enabled(objName, timeout)
|
||||||
test.verify(result[0] == condition, "Checking if object enabled")
|
test.verify(result[0] == condition, "Checking if object enabled")
|
||||||
|
|
||||||
def verify_text_matching(objName: str, text: str):
|
def verify_text_matching(objName: str, text: str):
|
||||||
|
from drivers.SquishDriver import is_text_matching
|
||||||
test.verify(is_text_matching(objName, text), "Checking if text matches")
|
test.verify(is_text_matching(objName, text), "Checking if text matches")
|
||||||
|
|
||||||
def verify_text_matching_insensitive(obj, text: str):
|
def verify_text_matching_insensitive(obj, text: str):
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import configs
|
||||||
|
from utils.system_path import SystemPath
|
||||||
|
|
||||||
|
import squish
|
||||||
|
from . import context
|
||||||
|
|
||||||
|
|
||||||
|
class ExecutableAut:
|
||||||
|
|
||||||
|
def __init__(self, fp: SystemPath):
|
||||||
|
self.fp = fp
|
||||||
|
self.ctx = None
|
||||||
|
|
||||||
|
def start(self, *args, attempt: int = 2):
|
||||||
|
args = ' '.join([self.fp.name] + [str(arg) for arg in args])
|
||||||
|
try:
|
||||||
|
self.ctx = squish.startApplication(args)
|
||||||
|
assert squish.waitFor(lambda: self.ctx.isRunning, configs.squish.APP_LOAD_TIMEOUT_MSEC)
|
||||||
|
except (AssertionError, RuntimeError):
|
||||||
|
if attempt:
|
||||||
|
self.detach()
|
||||||
|
self.start(*args, attempt - 1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def detach():
|
||||||
|
context.detach()
|
|
@ -0,0 +1,12 @@
|
||||||
|
import configs
|
||||||
|
import squish
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def detach():
|
||||||
|
for ctx in squish.applicationContextList():
|
||||||
|
ctx.detach()
|
||||||
|
assert squish.waitFor(
|
||||||
|
lambda: not ctx.isRunning, configs.squish.PROCESS_LOAD_TIMEOUT_MSEC), 'Detach application failed'
|
||||||
|
# TODO: close by ctx.pid and then detach
|
||||||
|
time.sleep(5)
|
|
@ -0,0 +1,24 @@
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
|
class SystemPath(pathlib.Path):
|
||||||
|
_accessor = pathlib._normal_accessor # noqa
|
||||||
|
_flavour = pathlib._windows_flavour if os.name == 'nt' else pathlib._posix_flavour # noqa
|
||||||
|
|
||||||
|
def rmtree(self, ignore_errors=False):
|
||||||
|
children = list(self.iterdir())
|
||||||
|
for child in children:
|
||||||
|
if child.is_dir():
|
||||||
|
child.rmtree(ignore_errors=ignore_errors)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
child.unlink()
|
||||||
|
except OSError as e:
|
||||||
|
if not ignore_errors:
|
||||||
|
raise
|
||||||
|
try:
|
||||||
|
self.rmdir()
|
||||||
|
except OSError:
|
||||||
|
if not ignore_errors:
|
||||||
|
raise
|
|
@ -4,6 +4,7 @@
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../testSuites/global_shared/"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../testSuites/global_shared/"))
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
|
||||||
|
|
||||||
|
import drivers.SquishDriver as driver
|
||||||
from steps.commonInitSteps import context_init
|
from steps.commonInitSteps import context_init
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,11 +13,11 @@ def hook(context):
|
||||||
context_init(context, testSettings)
|
context_init(context, testSettings)
|
||||||
context.userData["scenario_name"] = context._data["title"]
|
context.userData["scenario_name"] = context._data["title"]
|
||||||
|
|
||||||
|
|
||||||
@OnScenarioEnd
|
@OnScenarioEnd
|
||||||
def hook(context):
|
def hook(context):
|
||||||
ctx = currentApplicationContext()
|
driver.detach()
|
||||||
ctx.detach()
|
|
||||||
assert waitFor(lambda: not ctx.isRunning, _app_closure_timeout), 'Detach application failed'
|
|
||||||
|
|
||||||
@OnStepEnd
|
@OnStepEnd
|
||||||
def hook(context):
|
def hook(context):
|
||||||
|
|
|
@ -4,6 +4,7 @@ import os
|
||||||
|
|
||||||
import utils.FileManager as filesMngr
|
import utils.FileManager as filesMngr
|
||||||
import common.Common as common
|
import common.Common as common
|
||||||
|
import configs
|
||||||
|
|
||||||
from screens.StatusWelcomeScreen import StatusWelcomeScreen
|
from screens.StatusWelcomeScreen import StatusWelcomeScreen
|
||||||
from screens.StatusMainScreen import StatusMainScreen
|
from screens.StatusMainScreen import StatusMainScreen
|
||||||
|
@ -58,13 +59,12 @@ def context_init(context, testSettings, screenshot_on_fail = True):
|
||||||
context.userData[_fixtures_root] = os.path.join(joined_path, "fixtures/")
|
context.userData[_fixtures_root] = os.path.join(joined_path, "fixtures/")
|
||||||
|
|
||||||
def a_first_time_user_lands_on(context):
|
def a_first_time_user_lands_on(context):
|
||||||
filesMngr.erase_directory(context.userData[_status_data_folder])
|
common.start_application()
|
||||||
common.start_application(context.userData[_aut_name])
|
|
||||||
|
|
||||||
def a_user_starts_the_application_with_a_specific_data_folder(context, data_folder_path):
|
def a_user_starts_the_application_with_a_specific_data_folder(context, data_folder_path):
|
||||||
filesMngr.clear_directory(context.userData["status_data_folder_path"])
|
filesMngr.clear_directory(configs.path.STATUS_USER_DATA)
|
||||||
filesMngr.copy_directory(data_folder_path, context.userData["status_data_folder_path"])
|
filesMngr.copy_directory(data_folder_path, str(configs.path.STATUS_USER_DATA))
|
||||||
common.start_application(context.userData[_aut_name])
|
common.start_application(clear_user_data=False)
|
||||||
|
|
||||||
def a_first_time_user_lands_on_and_generates_new_key(context):
|
def a_first_time_user_lands_on_and_generates_new_key(context):
|
||||||
a_first_time_user_lands_on(context)
|
a_first_time_user_lands_on(context)
|
||||||
|
@ -76,8 +76,7 @@ def a_user_lands_on_and_generates_new_key(context):
|
||||||
welcome_screen.generate_new_key()
|
welcome_screen.generate_new_key()
|
||||||
|
|
||||||
def a_first_time_user_lands_on_and_navigates_to_import_seed_phrase(context):
|
def a_first_time_user_lands_on_and_navigates_to_import_seed_phrase(context):
|
||||||
filesMngr.erase_directory(context.userData[_status_data_folder])
|
common.start_application()
|
||||||
filesMngr.start_application(context.userData[_aut_name])
|
|
||||||
welcome_screen = StatusWelcomeScreen()
|
welcome_screen = StatusWelcomeScreen()
|
||||||
welcome_screen.agree_terms_conditions_and_navigate_to_import_seed_phrase()
|
welcome_screen.agree_terms_conditions_and_navigate_to_import_seed_phrase()
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,14 @@ import time
|
||||||
# *****************************************************************************
|
# *****************************************************************************
|
||||||
import common.Common as common
|
import common.Common as common
|
||||||
import steps.commonInitSteps as init_steps
|
import steps.commonInitSteps as init_steps
|
||||||
from drivers.SquishDriver import start_application
|
import drivers.SquishDriver as driver
|
||||||
from screens.StatusChatScreen import StatusChatScreen
|
from screens.StatusChatScreen import StatusChatScreen
|
||||||
from screens.StatusMainScreen import StatusMainScreen
|
from screens.StatusMainScreen import StatusMainScreen
|
||||||
|
|
||||||
_statusMain = StatusMainScreen()
|
_statusMain = StatusMainScreen()
|
||||||
_statusChat = StatusChatScreen()
|
_statusChat = StatusChatScreen()
|
||||||
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
### PRECONDITIONS region:
|
### PRECONDITIONS region:
|
||||||
#########################
|
#########################
|
||||||
|
@ -32,30 +33,37 @@ _statusChat = StatusChatScreen()
|
||||||
def step(context, data_folder_path):
|
def step(context, data_folder_path):
|
||||||
init_steps.a_user_starts_the_application_with_a_specific_data_folder(context, data_folder_path)
|
init_steps.a_user_starts_the_application_with_a_specific_data_folder(context, data_folder_path)
|
||||||
|
|
||||||
|
|
||||||
@Given("the user restarts the app")
|
@Given("the user restarts the app")
|
||||||
def step(context):
|
def step(context):
|
||||||
the_user_restarts_the_app(context)
|
the_user_restarts_the_app(context)
|
||||||
|
|
||||||
|
|
||||||
@Given("the user joins chat room \"|any|\"")
|
@Given("the user joins chat room \"|any|\"")
|
||||||
def step(context, room):
|
def step(context, room):
|
||||||
the_user_joins_chat_room(room)
|
the_user_joins_chat_room(room)
|
||||||
|
|
||||||
|
|
||||||
@Given("the user clicks on escape key")
|
@Given("the user clicks on escape key")
|
||||||
def step(context):
|
def step(context):
|
||||||
_statusMain.click_escape()
|
_statusMain.click_escape()
|
||||||
|
|
||||||
|
|
||||||
@Given("the user clears input \"|any|\"")
|
@Given("the user clears input \"|any|\"")
|
||||||
def step(context, input_component):
|
def step(context, input_component):
|
||||||
common.clear_input_text(input_component)
|
common.clear_input_text(input_component)
|
||||||
|
|
||||||
|
|
||||||
@Given("the user inputs the following \"|any|\" with ui-component \"|any|\"")
|
@Given("the user inputs the following \"|any|\" with ui-component \"|any|\"")
|
||||||
def step(context, text, obj):
|
def step(context, text, obj):
|
||||||
the_user_inputs_the_following_text_with_uicomponent(text, obj)
|
the_user_inputs_the_following_text_with_uicomponent(text, obj)
|
||||||
|
|
||||||
|
|
||||||
@Given("the user clicks on the following ui-component \"|any|\"")
|
@Given("the user clicks on the following ui-component \"|any|\"")
|
||||||
def step(context: any, obj: str):
|
def step(context: any, obj: str):
|
||||||
the_user_clicks_on_the_following_ui_component(obj)
|
the_user_clicks_on_the_following_ui_component(obj)
|
||||||
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
### ACTIONS region:
|
### ACTIONS region:
|
||||||
#########################
|
#########################
|
||||||
|
@ -64,23 +72,28 @@ def step(context: any, obj: str):
|
||||||
def step(context):
|
def step(context):
|
||||||
the_user_restarts_the_app(context)
|
the_user_restarts_the_app(context)
|
||||||
|
|
||||||
|
|
||||||
@When("the user inputs the following \"|any|\" with ui-component \"|any|\"")
|
@When("the user inputs the following \"|any|\" with ui-component \"|any|\"")
|
||||||
def step(context, text, obj):
|
def step(context, text, obj):
|
||||||
the_user_inputs_the_following_text_with_uicomponent(text, obj)
|
the_user_inputs_the_following_text_with_uicomponent(text, obj)
|
||||||
|
|
||||||
|
|
||||||
@When("the user clicks on the following ui-component \"|any|\"")
|
@When("the user clicks on the following ui-component \"|any|\"")
|
||||||
def step(context: any, obj: str):
|
def step(context: any, obj: str):
|
||||||
init_steps.the_user_clicks_on_the_following_ui_component(obj)
|
init_steps.the_user_clicks_on_the_following_ui_component(obj)
|
||||||
|
|
||||||
|
|
||||||
@When("the user joins chat room \"|any|\"")
|
@When("the user joins chat room \"|any|\"")
|
||||||
def step(context, room):
|
def step(context, room):
|
||||||
the_user_joins_chat_room(room)
|
the_user_joins_chat_room(room)
|
||||||
|
|
||||||
|
|
||||||
# TODO remove when we have a reliable local mailserver
|
# TODO remove when we have a reliable local mailserver
|
||||||
@When("the user waits |any| seconds")
|
@When("the user waits |any| seconds")
|
||||||
def step(context, amount):
|
def step(context, amount):
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
### VERIFICATIONS region:
|
### VERIFICATIONS region:
|
||||||
#########################
|
#########################
|
||||||
|
@ -89,20 +102,23 @@ def step(context, amount):
|
||||||
def step(context, obj):
|
def step(context, obj):
|
||||||
common.object_not_enabled(obj)
|
common.object_not_enabled(obj)
|
||||||
|
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
### COMMON methods used in different steps given/when/then region:
|
### COMMON methods used in different steps given/when/then region:
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
def the_user_restarts_the_app(context: any):
|
def the_user_restarts_the_app(context: any):
|
||||||
[ctx.detach() for ctx in squish.applicationContextList()]
|
driver.detach()
|
||||||
start_application(context.userData["aut_name"])
|
driver.start_application(clear_user_data=False)
|
||||||
|
|
||||||
|
|
||||||
def the_user_joins_chat_room(room: str):
|
def the_user_joins_chat_room(room: str):
|
||||||
init_steps.the_user_joins_chat_room(room)
|
init_steps.the_user_joins_chat_room(room)
|
||||||
|
|
||||||
|
|
||||||
def the_user_inputs_the_following_text_with_uicomponent(text: str, obj):
|
def the_user_inputs_the_following_text_with_uicomponent(text: str, obj):
|
||||||
common.input_text(text, obj)
|
common.input_text(text, obj)
|
||||||
|
|
||||||
|
|
||||||
def the_user_clicks_on_the_following_ui_component(obj):
|
def the_user_clicks_on_the_following_ui_component(obj):
|
||||||
init_steps.the_user_clicks_on_the_following_ui_component(obj)
|
init_steps.the_user_clicks_on_the_following_ui_component(obj)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue