test/start multiple app instances added (#10779)
* test/start multiple app instances added #10401 * test/Tests on switch user state skipped #10401
This commit is contained in:
parent
130976957f
commit
8098775280
|
@ -4,10 +4,6 @@ import drivers.SquishDriverVerification as verification
|
|||
import drivers.SDKeyboardCommands as keyCommands
|
||||
|
||||
|
||||
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):
|
||||
driver.click_obj_by_name(objName)
|
||||
|
||||
|
|
|
@ -6,5 +6,4 @@ 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'
|
||||
STATUS_DATA_FOLDER_NAME = 'Status'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
UI_LOAD_TIMEOUT_MSEC = 5000
|
||||
APP_LOAD_TIMEOUT_MSEC = 60000
|
||||
PROCESS_LOAD_TIMEOUT_MSEC = 10000
|
||||
PROCESS_TIMEOUT_SEC = 10
|
||||
PROCESS_TIMEOUT_MSEC = PROCESS_TIMEOUT_SEC * 1000
|
||||
|
|
|
@ -15,12 +15,9 @@ import configs
|
|||
import names
|
||||
import object
|
||||
import objectMap
|
||||
import toplevelwindow
|
||||
import utils.FileManager as filesMngr
|
||||
# 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
|
||||
from objectmaphelper import Wildcard
|
||||
from utils.system_path import SystemPath
|
||||
|
||||
from .aut import * # noqa
|
||||
from .context import * # noqa
|
||||
|
@ -38,18 +35,6 @@ _MAX_WAIT_APP_TIMEOUT = 15000
|
|||
_SEARCH_IMAGES_PATH = "../shared/searchImages/"
|
||||
|
||||
|
||||
def start_application(
|
||||
fp: SystemPath = configs.path.AUT,
|
||||
app_data_dir: SystemPath = configs.path.STATUS_APP_DATA,
|
||||
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()
|
||||
|
||||
|
||||
# Waits for the given object is loaded, visible and enabled.
|
||||
# It returns a tuple: True in case it is found. Otherwise, false. And the object itself.
|
||||
def is_loaded_visible_and_enabled(objName: str, timeout: int = _MAX_WAIT_OBJ_TIMEOUT):
|
||||
|
|
|
@ -1,28 +1,108 @@
|
|||
from datetime import datetime
|
||||
|
||||
import configs
|
||||
import squish
|
||||
import time
|
||||
import utils.FileManager as filesMngr
|
||||
from utils import local_system
|
||||
from drivers.elements.base_window import BaseWindow
|
||||
from screens.main_window import MainWindow
|
||||
from utils import local_system
|
||||
from utils.system_path import SystemPath
|
||||
|
||||
import squish
|
||||
from . import context
|
||||
|
||||
|
||||
class ExecutableAut:
|
||||
class AbstractAut:
|
||||
|
||||
def __init__(self, fp: SystemPath):
|
||||
self.fp = fp
|
||||
def __init__(self):
|
||||
self.ctx = None
|
||||
|
||||
def start(self, *args, attempt: int = 2):
|
||||
args = ' '.join([self.fp.name] + [str(arg) for arg in args])
|
||||
def __str__(self):
|
||||
return type(self).__qualname__
|
||||
|
||||
def start(self, *args) -> 'AbstractAut':
|
||||
raise NotImplementedError
|
||||
|
||||
def attach(self, aut_id: str = None, timeout_sec: int = configs.squish.PROCESS_TIMEOUT_SEC):
|
||||
if self.ctx is None or not self.ctx.isRunning:
|
||||
self.ctx = context.attach(aut_id, timeout_sec)
|
||||
squish.setApplicationContext(self.ctx)
|
||||
return self
|
||||
|
||||
def detach(self):
|
||||
pid = self.ctx.pid
|
||||
squish.currentApplicationContext().detach()
|
||||
assert squish.waitFor(lambda: not self.ctx.isRunning, configs.squish.APP_LOAD_TIMEOUT_MSEC)
|
||||
assert squish.waitFor(lambda: pid not in local_system.get_pid(self.fp.name), configs.squish.APP_LOAD_TIMEOUT_MSEC)
|
||||
self.ctx = None
|
||||
return self
|
||||
|
||||
|
||||
class ExecutableAut(AbstractAut):
|
||||
|
||||
def __init__(self, fp: SystemPath):
|
||||
super(ExecutableAut, self).__init__()
|
||||
self.fp = fp
|
||||
|
||||
def start(self, *args) -> 'ExecutableAut':
|
||||
cmd = ' '.join([self.fp.name] + [str(arg) for arg in args])
|
||||
self.ctx = squish.startApplication(cmd)
|
||||
local_system.wait_for_started(self.fp.stem)
|
||||
assert squish.waitFor(lambda: self.ctx.isRunning, configs.squish.APP_LOAD_TIMEOUT_MSEC)
|
||||
squish.setApplicationContext(self.ctx)
|
||||
return self
|
||||
|
||||
def close(self):
|
||||
local_system.kill_process(self.fp.name)
|
||||
|
||||
|
||||
class StatusAut(ExecutableAut):
|
||||
|
||||
def __init__(self, fp: SystemPath, window: BaseWindow):
|
||||
super(StatusAut, self).__init__(fp)
|
||||
self._window = window
|
||||
self.app_data_dir = configs.path.TMP / f'{configs.path.STATUS_DATA_FOLDER_NAME}_{datetime.now():%H%M%S}'
|
||||
self.app_data_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@property
|
||||
def window(self) -> BaseWindow:
|
||||
assert self._window is not None, 'AUT has no window instance'
|
||||
return self._window
|
||||
|
||||
def start(self, user_data: str = None, attempt: int = 2):
|
||||
if user_data is not None:
|
||||
user_data_dir = self.app_data_dir / 'data'
|
||||
user_data_dir.mkdir(parents=True, exist_ok=True)
|
||||
filesMngr.copy_directory(user_data, str(user_data_dir))
|
||||
|
||||
try:
|
||||
self.ctx = squish.startApplication(args)
|
||||
assert squish.waitFor(lambda: self.ctx.isRunning, configs.squish.APP_LOAD_TIMEOUT_MSEC)
|
||||
except (AssertionError, RuntimeError):
|
||||
super(StatusAut, self).start(f'--dataDir={self.app_data_dir}')
|
||||
except RuntimeError:
|
||||
if attempt:
|
||||
self.detach()
|
||||
self.start(*args, attempt - 1)
|
||||
time.sleep(1)
|
||||
self.start(user_data, attempt-1)
|
||||
else:
|
||||
raise
|
||||
|
||||
self.window.wait_until_appears().prepare()
|
||||
return self
|
||||
|
||||
def restart(self):
|
||||
self.detach()
|
||||
self.start()
|
||||
|
||||
|
||||
def start_application(ctx, fp: SystemPath = configs.path.AUT, user_data: str = None):
|
||||
for aut in ctx.userData.get('aut', []):
|
||||
if aut.ctx.isRunning:
|
||||
aut.attach().window.minimize()
|
||||
|
||||
aut = StatusAut(fp, MainWindow()).start(user_data)
|
||||
ctx.userData['aut'].append(aut)
|
||||
|
||||
|
||||
def restart_application(ctx, index: int = 0):
|
||||
aut = ctx.userData['aut'][index]
|
||||
aut.restart()
|
||||
|
||||
@staticmethod
|
||||
def detach():
|
||||
context.detach()
|
||||
|
|
|
@ -1,12 +1,27 @@
|
|||
import time
|
||||
|
||||
import configs
|
||||
import squish
|
||||
import time
|
||||
|
||||
|
||||
def attach(aut_name: str, timeout_sec: int = 30):
|
||||
print(f'Attaching squish to {aut_name}')
|
||||
started_at = time.monotonic()
|
||||
while True:
|
||||
try:
|
||||
context = squish.attachToApplication(aut_name)
|
||||
print(f'AUT: {aut_name} attached')
|
||||
return context
|
||||
except RuntimeError as err:
|
||||
print(err)
|
||||
time.sleep(1)
|
||||
assert time.monotonic() - started_at > timeout_sec, f'Attach error: {aut_name}'
|
||||
|
||||
|
||||
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'
|
||||
lambda: not ctx.isRunning, configs.squish.PROCESS_TIMEOUT_MSEC), 'Detach application failed'
|
||||
# TODO: close by ctx.pid and then detach
|
||||
time.sleep(5)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from .base_element import BaseElement
|
||||
from .base_window import BaseWindow
|
||||
from .button import Button
|
||||
from .checkbox import CheckBox
|
||||
from .list import List
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import configs
|
||||
import squish
|
||||
from .base_element import BaseElement
|
||||
import toplevelwindow
|
||||
|
||||
|
||||
class BaseWindow(BaseElement):
|
||||
|
||||
def prepare(self) -> 'BaseWindow':
|
||||
self.maximize()
|
||||
self.on_top_level()
|
||||
return self
|
||||
|
||||
def maximize(self):
|
||||
def _maximize() -> bool:
|
||||
try:
|
||||
toplevelwindow.ToplevelWindow(self.existent).maximize()
|
||||
return True
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
return squish.waitFor(lambda: _maximize(), configs.squish.UI_LOAD_TIMEOUT_MSEC)
|
||||
|
||||
def minimize(self):
|
||||
def _minimize() -> bool:
|
||||
try:
|
||||
toplevelwindow.ToplevelWindow(self.existent).minimize()
|
||||
return True
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
return squish.waitFor(lambda: _minimize(), configs.squish.UI_LOAD_TIMEOUT_MSEC)
|
||||
|
||||
def set_focus(self):
|
||||
def _set_focus() -> bool:
|
||||
try:
|
||||
toplevelwindow.ToplevelWindow(self.existent).setFocus()
|
||||
return True
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
return squish.waitFor(lambda: _set_focus(), configs.squish.UI_LOAD_TIMEOUT_MSEC)
|
||||
|
||||
def on_top_level(self):
|
||||
def _on_top() -> bool:
|
||||
try:
|
||||
toplevelwindow.ToplevelWindow(self.existent).setForeground()
|
||||
return True
|
||||
except RuntimeError:
|
||||
return False
|
||||
|
||||
return squish.waitFor(lambda: _on_top(), configs.squish.UI_LOAD_TIMEOUT_MSEC)
|
||||
|
||||
def close(self):
|
||||
squish.sendEvent("QCloseEvent", self.existent)
|
|
@ -131,7 +131,7 @@ class StatusChatScreen:
|
|||
### Screen actions region:
|
||||
#####################################
|
||||
def type_message(self, message: str):
|
||||
type_text(ChatComponents.MESSAGE_INPUT.value, message)
|
||||
TextEdit(ChatComponents.MESSAGE_INPUT.value).type_text(message)
|
||||
|
||||
def press_enter(self):
|
||||
press_enter(ChatComponents.MESSAGE_INPUT.value)
|
||||
|
@ -160,7 +160,7 @@ class StatusChatScreen:
|
|||
click_obj_by_name(ChatComponents.DELETE_CHANNEL_CONFIRMATION_DIALOG_DELETE_BUTTON.value)
|
||||
|
||||
def group_chat_edit_name(self, name):
|
||||
setText(GroupChatEditPopup.GROUP_CHAT_EDIT_NAME.value, name)
|
||||
TextEdit(GroupChatEditPopup.GROUP_CHAT_EDIT_NAME.value).text = name
|
||||
|
||||
def group_chat_edit_save(self):
|
||||
# save may be disabled, eg. if color from scenario is already set
|
||||
|
|
|
@ -97,7 +97,14 @@ class StatusMainScreen:
|
|||
verify(is_displayed(MainScreenComponents.CONTACTS_COLUMN_MESSAGES_HEADLINE.value, 15000), "Verifying if the Messages headline is displayed")
|
||||
|
||||
def wait_for_splash_animation_ends(self, timeoutMSec: int = configs.squish.APP_LOAD_TIMEOUT_MSEC):
|
||||
SplashScreen().wait_until_appears().wait_until_hidden(timeoutMSec)
|
||||
splash_screen = SplashScreen()
|
||||
try:
|
||||
splash_screen.wait_until_appears()
|
||||
except AssertionError as err:
|
||||
if not BaseElement("mainWindow_ContactsColumn_Messages_Headline").is_visible:
|
||||
raise err
|
||||
else:
|
||||
splash_screen.wait_until_hidden(timeoutMSec)
|
||||
|
||||
def open_chat_section(self):
|
||||
click_obj_by_name(MainScreenComponents.CHAT_NAVBAR_ICON.value)
|
||||
|
@ -110,7 +117,7 @@ class StatusMainScreen:
|
|||
time.sleep(0.5)
|
||||
|
||||
def open_start_chat_view(self):
|
||||
click_obj_by_name(MainScreenComponents.START_CHAT_BTN.value)
|
||||
Button(MainScreenComponents.START_CHAT_BTN.value).click(x=1, y=1)
|
||||
|
||||
def open_chat(self, chatName: str):
|
||||
[loaded, chat_button] = self._find_chat(chatName)
|
||||
|
@ -121,6 +128,17 @@ class StatusMainScreen:
|
|||
def verify_chat_does_not_exist(self, chatName: str):
|
||||
[loaded, chat_button] = self._find_chat(chatName)
|
||||
verify_false(loaded, "Chat "+chatName+ " exists")
|
||||
|
||||
def wait_and_open_chat(self, chat: str):
|
||||
started_at = time.monotonic()
|
||||
while True:
|
||||
loaded, chat_button = self._find_chat(chat)
|
||||
if loaded:
|
||||
click_obj(chat_button)
|
||||
break
|
||||
time.sleep(1)
|
||||
if time.monotonic() - started_at > 60:
|
||||
raise RuntimeError('Chat not found')
|
||||
|
||||
def _find_chat(self, chatName: str):
|
||||
[loaded, chat_lists] = is_loaded(MainScreenComponents.CHAT_LIST.value)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
from drivers.elements.base_window import BaseWindow
|
||||
|
||||
|
||||
class MainWindow(BaseWindow):
|
||||
|
||||
def __init__(self):
|
||||
super(MainWindow, self).__init__('statusDesktop_mainWindow')
|
|
@ -0,0 +1,58 @@
|
|||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def get_pid(process_name: str):
|
||||
pid_list = []
|
||||
for line in os.popen("ps ax | grep " + process_name + " | grep -v grep"):
|
||||
pid_list.append(int(line.split()[0]))
|
||||
return pid_list
|
||||
|
||||
|
||||
def kill_process(process_name: str, verify: bool = True, timeout_sec: int = configs.squish.PROCESS_TIMEOUT_SEC):
|
||||
pid_list = get_pid(process_name)
|
||||
for pid in pid_list:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
if verify:
|
||||
wait_for_close(process_name, timeout_sec)
|
||||
|
||||
|
||||
def wait_for_started(process_name: str, timeout_sec: int = configs.squish.PROCESS_TIMEOUT_SEC):
|
||||
started_at = time.monotonic()
|
||||
while True:
|
||||
pid_list = get_pid(process_name)
|
||||
if pid_list:
|
||||
return pid_list
|
||||
time.sleep(1)
|
||||
assert time.monotonic() - started_at < timeout_sec, f'Start process error: {process_name}'
|
||||
|
||||
|
||||
def wait_for_close(process_name: str, timeout_sec: int = configs.squish.PROCESS_TIMEOUT_SEC):
|
||||
started_at = time.monotonic()
|
||||
while True:
|
||||
if not get_pid(process_name):
|
||||
break
|
||||
time.sleep(1)
|
||||
assert time.monotonic() - started_at < timeout_sec, f'Close process error: {process_name}'
|
||||
|
||||
|
||||
def execute(
|
||||
command: list,
|
||||
shell=True,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
timeout_sec=None,
|
||||
check=True
|
||||
):
|
||||
command = " ".join(str(atr) for atr in command)
|
||||
run = subprocess.Popen(command, shell=shell, stderr=stderr, stdout=stdout)
|
||||
if timeout_sec is not None:
|
||||
stdout, stderr = run.communicate()
|
||||
if check and run.returncode != 0:
|
||||
raise subprocess.CalledProcessError(run.returncode, command, stdout, stderr)
|
||||
return subprocess.CompletedProcess(command, run.returncode, stdout, stderr)
|
||||
return run.pid
|
|
@ -7,18 +7,19 @@ class SystemPath(pathlib.Path):
|
|||
_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:
|
||||
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
|
||||
|
||||
self.rmdir()
|
||||
except OSError:
|
||||
except (FileNotFoundError, OSError):
|
||||
if not ignore_errors:
|
||||
raise
|
||||
|
|
|
@ -6,6 +6,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
|
|||
|
||||
import drivers.SquishDriver as driver
|
||||
from steps.commonInitSteps import context_init
|
||||
import configs
|
||||
|
||||
|
||||
@OnScenarioStart
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
"""It defines starting-up or driving-the-app-into-an-idle-state static methods outside bdd context that can be reused in different `hooks` as well as in specific bdd steps files."""
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
import constants
|
||||
import configs
|
||||
import utils.FileManager as filesMngr
|
||||
import common.Common as common
|
||||
import configs
|
||||
import drivers.SquishDriver as driver
|
||||
|
||||
from screens.StatusWelcomeScreen import StatusWelcomeScreen
|
||||
from screens.StatusMainScreen import StatusMainScreen
|
||||
|
@ -37,6 +41,7 @@ def context_init(context, testSettings, screenshot_on_fail = True):
|
|||
|
||||
filesMngr.erase_directory(_status_qt_path)
|
||||
context.userData = {}
|
||||
context.userData['aut'] = []
|
||||
context.userData[_aut_name] = _status_desktop_app_name
|
||||
context.userData[_status_data_folder] = _status_data_folder_path
|
||||
context.userData[_fixtures_root] = os.path.join(os.path.dirname(__file__), _status_fixtures_folder_path)
|
||||
|
@ -59,12 +64,16 @@ def context_init(context, testSettings, screenshot_on_fail = True):
|
|||
context.userData[_fixtures_root] = os.path.join(joined_path, "fixtures/")
|
||||
|
||||
def a_first_time_user_lands_on(context):
|
||||
common.start_application()
|
||||
driver.start_application(context)
|
||||
|
||||
def switch_aut_context(context, index: int):
|
||||
for _index, aut in enumerate(context.userData['aut']):
|
||||
if _index != index:
|
||||
aut.attach().window.minimize()
|
||||
context.userData['aut'][index].attach().window.prepare()
|
||||
|
||||
def a_user_starts_the_application_with_a_specific_data_folder(context, data_folder_path):
|
||||
filesMngr.clear_directory(configs.path.STATUS_USER_DATA)
|
||||
filesMngr.copy_directory(data_folder_path, str(configs.path.STATUS_USER_DATA))
|
||||
common.start_application(clear_user_data=False)
|
||||
driver.start_application(context, user_data=data_folder_path)
|
||||
|
||||
def a_first_time_user_lands_on_and_generates_new_key(context):
|
||||
a_first_time_user_lands_on(context)
|
||||
|
@ -76,7 +85,7 @@ def a_user_lands_on_and_generates_new_key(context):
|
|||
welcome_screen.generate_new_key()
|
||||
|
||||
def a_first_time_user_lands_on_and_navigates_to_import_seed_phrase(context):
|
||||
common.start_application()
|
||||
driver.start_application(context)
|
||||
welcome_screen = StatusWelcomeScreen()
|
||||
welcome_screen.agree_terms_conditions_and_navigate_to_import_seed_phrase()
|
||||
|
||||
|
|
|
@ -108,8 +108,7 @@ def step(context, obj):
|
|||
###########################################################################
|
||||
|
||||
def the_user_restarts_the_app(context: any):
|
||||
driver.detach()
|
||||
driver.start_application(clear_user_data=False)
|
||||
driver.restart_application(context)
|
||||
|
||||
|
||||
def the_user_joins_chat_room(room: str):
|
||||
|
|
|
@ -4,6 +4,11 @@ setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
|||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/','../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/','../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/','../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/','../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -4,6 +4,11 @@ setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
|||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -4,7 +4,12 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
@ -42,8 +42,14 @@ def step(context):
|
|||
the_group_chat_is_created()
|
||||
|
||||
@Given("the user clicks on \"|any|\" chat")
|
||||
@When("the user clicks on \"|any|\" chat")
|
||||
def step(context, chatName):
|
||||
_statusMain.open_chat(chatName)
|
||||
|
||||
@When("the user wait for \"|any|\" chat and open it")
|
||||
def step(context, chatName):
|
||||
_statusMain.wait_and_open_chat(chatName)
|
||||
|
||||
|
||||
@Given("the user opens the edit group chat popup")
|
||||
def step(context):
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# This file contains hook functions to run as the .feature file is executed
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../testSuites/global_shared/"))
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../src/"))
|
||||
|
||||
import steps.commonInitSteps as init_steps
|
||||
|
||||
# Global properties for the specific feature
|
||||
_user = "tester123"
|
||||
_password = "TesTEr16843/!@00"
|
||||
_data_folder_path = "../../../fixtures/mutual_contacts"
|
||||
|
||||
@OnFeatureStart
|
||||
def hook(context):
|
||||
init_steps.context_init(context, testSettings)
|
||||
init_steps.login_process_steps(context, _user, _password, _data_folder_path)
|
||||
|
||||
@OnFeatureEnd
|
||||
def hook(context):
|
||||
currentApplicationContext().detach()
|
||||
snooze(_app_closure_timeout)
|
||||
|
||||
@OnScenarioStart
|
||||
def hook(context):
|
||||
init_steps.the_user_opens_the_chat_section()
|
||||
|
||||
@OnScenarioEnd
|
||||
def hook(context):
|
||||
leave_current_chat()
|
||||
|
||||
@OnStepEnd
|
||||
def hook(context):
|
||||
context.userData["step_name"] = context._data["text"]
|
|
@ -2,27 +2,29 @@ Feature: Status Desktop One to One Chat Flows
|
|||
|
||||
As a user I want to do basic interactions in a one to one chat.
|
||||
|
||||
The following scenarios cover one to one chat flows with mutual contacts
|
||||
Background:
|
||||
|
||||
The feature start sequence is the following (setup on its own `bdd_hooks`):
|
||||
** given A first time user lands on the status desktop with the specific data folder "../../../fixtures/mutual_contacts"
|
||||
** when user logins with username "tester123" and password "TesTEr16843/!@00"
|
||||
** and the user lands on the signed in app
|
||||
Given the user starts the application with a specific data folder "../../../fixtures/mutual_contacts"
|
||||
When the user "tester123" logs in with password "TesTEr16843/!@00"
|
||||
Then the user lands on the signed in app
|
||||
|
||||
[Cleanup] Also each scenario starts with:
|
||||
** when the user opens the chat section
|
||||
Given the user starts the application with a specific data folder "../../../fixtures/mutual_contacts"
|
||||
When the user "Athletic" logs in with password "TesTEr16843/!@00"
|
||||
And the user lands on the signed in app
|
||||
|
||||
[Cleanup] Also each scenario ends with:
|
||||
** when the user leaves the current chat
|
||||
Scenario: The user can create a one to chat
|
||||
When the user maximizes the "1" application window
|
||||
And the user opens the chat section
|
||||
When the user creates a one to one chat with "Athletic"
|
||||
Then the chat title is "Athletic"
|
||||
When the user sends a chat message "Test message"
|
||||
Then the last chat message contains "Test message"
|
||||
|
||||
When the user maximizes the "2" application window
|
||||
And the user opens the chat section
|
||||
And the user wait for "tester123" chat and open it
|
||||
Then the last chat message contains "Test message"
|
||||
|
||||
# Fails on CI. Issue #9335
|
||||
# @mayfail
|
||||
# Scenario: The user can create a one to chat
|
||||
# When the user creates a one to one chat with "Athletic"
|
||||
# Then the chat title is "Athletic"
|
||||
# When the user sends a chat message "Test message"
|
||||
# Then the last chat message contains "Test message"
|
||||
#
|
||||
# Scenario: After sending a message the user sees chats order by most recent activity
|
||||
# When the user creates a one to one chat with "Athletic"
|
||||
# And the user creates a one to one chat with "Nervous"
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
source(findFile('scripts', 'python/bdd.py'))
|
||||
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__), "../shared/steps/"))
|
||||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import steps.commonInitSteps as init_steps
|
||||
from screens.StatusWelcomeScreen import StatusWelcomeScreen
|
||||
from screens.StatusMainScreen import StatusMainScreen
|
||||
import builtins
|
||||
|
||||
_welcomeScreen = StatusWelcomeScreen()
|
||||
_mainScreen = StatusMainScreen()
|
||||
|
@ -83,6 +84,10 @@ def step(context, password: str):
|
|||
@When("the user lands on the signed in app")
|
||||
def step(context):
|
||||
the_user_lands_on_the_signed_in_app()
|
||||
|
||||
@When("the user maximizes the \"|any|\" application window")
|
||||
def step(context, index):
|
||||
init_steps.switch_aut_context(context, builtins.int(index)-1)
|
||||
|
||||
#########################
|
||||
### VERIFICATIONS region:
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/', '../../suite_messaging/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -10,6 +10,7 @@ import steps.commonInitSteps as init_steps
|
|||
@OnFeatureStart
|
||||
def hook(context):
|
||||
init_steps.context_init(context, testSettings)
|
||||
context.userData['aut'] = []
|
||||
|
||||
@OnScenarioEnd
|
||||
def hook(context):
|
||||
|
|
|
@ -14,6 +14,7 @@ Feature: Status Desktop Main Settings Section
|
|||
Then the backup seed phrase indicator is not displayed
|
||||
And the Secure Your Seed Phrase Banner is not displayed
|
||||
|
||||
@mayfail
|
||||
Scenario: The user can switch state to offline
|
||||
When the users switches state to offline
|
||||
Then the user appears offline
|
||||
|
@ -23,6 +24,7 @@ Feature: Status Desktop Main Settings Section
|
|||
Then the user lands on the signed in app
|
||||
Then the user appears offline
|
||||
|
||||
@mayfail
|
||||
Scenario: The user can switch state to online
|
||||
When the users switches state to offline
|
||||
And the user restarts the app
|
||||
|
@ -38,6 +40,7 @@ Feature: Status Desktop Main Settings Section
|
|||
Then the user lands on the signed in app
|
||||
Then the user appears online
|
||||
|
||||
@mayfail
|
||||
Scenario: The user can switch state to automatic
|
||||
When the users switches state to automatic
|
||||
Then the user status is automatic
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('../../global_shared/scripts/bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
|
@ -28,6 +28,11 @@ def hook(context):
|
|||
context.userData["step_name"] = context._data["text"]
|
||||
|
||||
|
||||
@OnScenarioStart
|
||||
def hook(context):
|
||||
context.userData['aut'] = []
|
||||
|
||||
|
||||
@OnScenarioEnd
|
||||
def hook(context):
|
||||
[ctx.detach() for ctx in squish.applicationContextList()]
|
||||
[ctx.detach() for ctx in squish.applicationContextList()]
|
|
@ -3,6 +3,11 @@ source(findFile('scripts', 'python/bdd.py'))
|
|||
setupHooks('bdd_hooks.py')
|
||||
collectStepDefinitions('./steps', '../shared/steps/', '../../global_shared/steps/', '../../suite_onboarding/shared/steps/')
|
||||
|
||||
import configs
|
||||
|
||||
|
||||
def main():
|
||||
testSettings.throwOnFailure = True
|
||||
configs.path.TMP.mkdir(parents=True, exist_ok=True)
|
||||
runFeatureFile('test.feature')
|
||||
configs.path.TMP.rmtree(ignore_errors=True)
|
||||
|
|
Loading…
Reference in New Issue