From e828d2c1de27784286a3d39eb69808a7e10350bc Mon Sep 17 00:00:00 2001 From: Vladimir Druzhinin <128374224+StateOf-Vlado@users.noreply.github.com> Date: Mon, 10 Jul 2023 17:55:10 +0200 Subject: [PATCH] test(pytest) Import squish as a python module. (#11421) #66 --- README.md | 153 +++++++++++++++++++++++++++++++++++ configs/__init__.py | 14 ++++ configs/_local.py.ci | 7 ++ configs/_local.py.default | 3 + configs/testpath.py | 15 ++++ configs/timeouts.py | 3 + conftest.py | 17 ++++ constants/__init__.py | 0 driver/__init__.py | 17 ++++ gui/__init__.py | 0 gui/components/__init__.py | 0 gui/elements/__init__.py | 1 + gui/main_window.py | 9 +++ gui/objects_map/__init__.py | 5 ++ gui/screens/__init__.py | 0 pytest.ini | 7 ++ requirements.txt | 1 + scripts/__init__.py | 0 scripts/tools/__init__.py | 0 scripts/utils/__init__.py | 0 scripts/utils/system_path.py | 14 ++++ tests/__init__.py | 0 tests/fixtures/__init__.py | 0 tests/fixtures/path.py | 38 +++++++++ tests/test_self.py | 13 +++ 25 files changed, 317 insertions(+) create mode 100644 README.md create mode 100644 configs/__init__.py create mode 100644 configs/_local.py.ci create mode 100644 configs/_local.py.default create mode 100644 configs/testpath.py create mode 100644 configs/timeouts.py create mode 100644 conftest.py create mode 100644 constants/__init__.py create mode 100755 driver/__init__.py create mode 100644 gui/__init__.py create mode 100644 gui/components/__init__.py create mode 100644 gui/elements/__init__.py create mode 100644 gui/main_window.py create mode 100644 gui/objects_map/__init__.py create mode 100644 gui/screens/__init__.py create mode 100644 pytest.ini create mode 100644 requirements.txt create mode 100644 scripts/__init__.py create mode 100644 scripts/tools/__init__.py create mode 100644 scripts/utils/__init__.py create mode 100644 scripts/utils/system_path.py create mode 100644 tests/__init__.py create mode 100644 tests/fixtures/__init__.py create mode 100644 tests/fixtures/path.py create mode 100755 tests/test_self.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..20a6939 --- /dev/null +++ b/README.md @@ -0,0 +1,153 @@ +# Status desktop ui-tests + +# Setup: +Skip any of the steps, if sure that you have the correct version of the required tool. +## All Platforms +### 1. Install Qt 5.15 +https://doc.qt.io/qt-6/get-and-install-qt.html +### 2. Setup Squish License Server +https://hackmd.io/@status-desktop/HkbWpk2e5 +### 3. Install PyCharm +Download and install: +https://www.jetbrains.com/pycharm/download/other.html +Please, select any build depending on OS, but NOT an Apple Silicon (dmg) + +How to: https://www.jetbrains.com/help/pycharm/installation-guide.html + +## Windows +### 4. Install Squish +https://status-misc.ams3.digitaloceanspaces.com/squish/squish-7.1-20230301-1424-qt515x-win64-msvc142.exe +### 5. Install Python +Download and install for all users: https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe +### 6. Install Requirements +``` +YOUR_PYTHON_PATH/pip3.exe install -r ./requirements.txt +``` +### 7. Setup Environment Variables +Add in system environment variables: +``` +SQUISH_DIR=PATH_TO_THE_SQUISH_ROOT_FOLDER +PYTHONPATH=%SQUISH_DIR%/lib;%SQUISH_DIR%/lib/python;%PYTHONPATH% +``` +RESTART PC +### 8. Verify environment variables +``` +echo %SQUISH_DIR% +echo %PYTHONPATH% +``` +### 9. Setup Python for Squish +Download 'PythonChanger.py' in %SQUISH_DIR%: +https://kb.froglogic.com/squish/howto/changing-python-installation-used-squish-binary-packages/PythonChanger.py +``` +YOUR_PYTHON_PATH/python3.10 SQUISH_DIR/PythonChanger.py --revert +YOUR_PYTHON_PATH/python3.10 SQUISH_DIR/PythonChanger.py +``` +- Replace "YOUR PYTHON PATH" on to Python3.10 file location path +- Replace "SQUISH DIR" on to the Squish root folder path +### 10 Test: +Executing tests located in 'test_self.py' file +``` +pytest ./tests/test_self.py +``` +Executing test 'test_import_squish' from 'test_self.py' file +``` +pytest ./tests/test_self.py::test_import_squish +``` +Executing all tests with 'import_squish' in test name +``` +pytest -k import_squish +``` +Executing all tests with tag 'self' +``` +pytest -m self +``` + +## Linux +### 4. Install Squish +https://status-misc.ams3.digitaloceanspaces.com/squish/squish-7.1-20230222-1555-qt515x-linux64.run +### 5. Install Python +```bash +sudo apt-get install software-properties-common +``` +```bash +sudo add-apt-repository ppa:deadsnakes/ppa +``` +```bash +sudo apt-get update +``` +```bash +sudo apt-get install python3.10 +``` +```bash +sudo apt install python3-pip +``` +### 6. Install Requirements +```bash +sudo pip3 install -r ./requirements.txt +``` +### 7. Setup Environment Variables +```bash +gedit ~/.profile +``` +``` +export SQUISH_DIR=PATH_TO_THE_SQUISH_ROOT_FOLDER +export PYTHONPATH=$SQUISH_DIR/lib:$SQUISH_DIR/lib/python:$PYTHONPATH +export LD_LIBRARY_PATH=$SQUISH_DIR/lib:$SQUISH_DIR/python3/lib:$LD_LIBRARY_PATH +``` +RESTART PC + +## Mac +### 4. Install Squish +https://status-misc.ams3.digitaloceanspaces.com/squish/squish-7.1-20230328-1608-qt515x-macaarch64.dmg +### 5. Install Python +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +``` +```bash +brew update --auto-update +brew install wget +brew install python@3.10 +``` +### 6. Install Requirements +```bash +sudo pip3 install -r ./requirements.txt +``` +### 7. Setup Environment Variables +```bash +touch ~/.zprofile +open ~/.zprofile +``` +``` +export SQUISH_DIR=PATH_TO_THE_SQUISH_ROOT_FOLDER +export PYTHONPATH=$SQUISH_DIR/lib:$SQUISH_DIR/lib/python:$PYTHONPATH +export LD_LIBRARY_PATH=$SQUISH_DIR/lib:$LD_LIBRARY_PATH +``` +RESTART PC + +## Linux or MAC: +### 8. Verify environment variables +```bash +echo $USERNAME +echo $PYTHONPATH +echo $LD_LIBRARY_PATH +``` +### 9. Setup Python for Squish +https://kb.froglogic.com/squish/howto/changing-python-installation-used-squish-binary-packages/ +```bash +brew install wget +wget -O $SQUISH_DIR/PythonChanger.py https://kb.froglogic.com/squish/howto/changing-python-installation-used-squish-binary-packages/PythonChanger.py +python3.10 $SQUISH_DIR/PythonChanger.py --revert +python3.10 $SQUISH_DIR/PythonChanger.py +``` +### 10 Test: +```bash +echo "Executing tests located in 'test_self.py' file" +pytest ./tests/test_self.py +echo "Executing test 'test_import_squish' from 'test_self.py' file" +pytest ./tests/test_self.py::test_import_squish +echo "Executing all tests with 'import_squish' in test name" +pytest -k import_squish +echo "Executing all tests with tag 'self'" +pytest -m self +``` +For more info, read: https://docs.pytest.org/en/latest/getting-started.html diff --git a/configs/__init__.py b/configs/__init__.py new file mode 100644 index 0000000..36bf648 --- /dev/null +++ b/configs/__init__.py @@ -0,0 +1,14 @@ +import logging + +from . import testpath, timeouts + +_logger = logging.getLogger(__name__) + +try: + from ._local import * +except ImportError: + exit( + 'Config file: "_local.py" not found in "./configs".\n' + 'Please use template "_.local.py.default" to create file or execute command: \n' + rf'cp {testpath.ROOT}/configs/_local.py.default {testpath.ROOT}/configs/_local.py' + ) diff --git a/configs/_local.py.ci b/configs/_local.py.ci new file mode 100644 index 0000000..46c5994 --- /dev/null +++ b/configs/_local.py.ci @@ -0,0 +1,7 @@ +import os + +from scripts.utils.system_path import SystemPath + +LOCAL_RUN = False + +APP_DIR = SystemPath(os.getenv('APP_DIR') diff --git a/configs/_local.py.default b/configs/_local.py.default new file mode 100644 index 0000000..0eae750 --- /dev/null +++ b/configs/_local.py.default @@ -0,0 +1,3 @@ +LOCAL_RUN = True + +APP_DIR = None diff --git a/configs/testpath.py b/configs/testpath.py new file mode 100644 index 0000000..d0a8e46 --- /dev/null +++ b/configs/testpath.py @@ -0,0 +1,15 @@ +import os +from datetime import datetime + +from scripts.utils.system_path import SystemPath + +ROOT: SystemPath = SystemPath(__file__).resolve().parent.parent + +# Test Directories +RUN_ID = os.getenv('RUN_DIR', f'run_{datetime.now():%d%m%Y_%H%M%S}') +TEMP: SystemPath = ROOT / 'tmp' +RESULTS: SystemPath = TEMP / 'results' +RUN: SystemPath = RESULTS / RUN_ID + +# Driver Directories +SQUISH_DIR = os.getenv('RUN_DIR') diff --git a/configs/timeouts.py b/configs/timeouts.py new file mode 100644 index 0000000..58d4cef --- /dev/null +++ b/configs/timeouts.py @@ -0,0 +1,3 @@ +# Timoeuts before raising errors + +UI_LOAD_TIMEOUT_MSEC = 5000 diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..d393c73 --- /dev/null +++ b/conftest.py @@ -0,0 +1,17 @@ +import pytest + +pytest_plugins = [ + 'tests.fixtures.path', +] + + +@pytest.fixture(scope='session', autouse=True) +def setup_session_scope( + run_dir, +): + yield + + +def pytest_exception_interact(node): + """Handles test on fail.""" + pass diff --git a/constants/__init__.py b/constants/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/driver/__init__.py b/driver/__init__.py new file mode 100755 index 0000000..e712a27 --- /dev/null +++ b/driver/__init__.py @@ -0,0 +1,17 @@ +import squishtest # noqa + +import configs + +imports = {module.__name__: module for module in [ + # import any modules from driver folder +]} + + +def __getattr__(name): + if name in imports: + return imports[name] + return getattr(squishtest, name) + + +squishtest.testSettings.waitForObjectTimeout = configs.timeouts.UI_LOAD_TIMEOUT_MSEC +squishtest.setHookSubprocesses(True) diff --git a/gui/__init__.py b/gui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gui/components/__init__.py b/gui/components/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gui/elements/__init__.py b/gui/elements/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/gui/elements/__init__.py @@ -0,0 +1 @@ + diff --git a/gui/main_window.py b/gui/main_window.py new file mode 100644 index 0000000..ac2189f --- /dev/null +++ b/gui/main_window.py @@ -0,0 +1,9 @@ +import logging + +_logger = logging.getLogger(__name__) + + +class MainWindow: + + def __init__(self): + pass diff --git a/gui/objects_map/__init__.py b/gui/objects_map/__init__.py new file mode 100644 index 0000000..80965aa --- /dev/null +++ b/gui/objects_map/__init__.py @@ -0,0 +1,5 @@ +from .component_names import * +from .main_window_names import * +from .messages_names import * +from .onboarding_names import * +from .settings_names import * diff --git a/gui/screens/__init__.py b/gui/screens/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..679ca18 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +log_format = %(asctime)s.%(msecs)03d %(levelname)7s %(name)s %(message).5000s +log_cli = true +log_cli_level = INFO + +markers = + self: framework tests diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..70613be --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pytest==7.4.0 diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/tools/__init__.py b/scripts/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/utils/__init__.py b/scripts/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/utils/system_path.py b/scripts/utils/system_path.py new file mode 100644 index 0000000..a12b24e --- /dev/null +++ b/scripts/utils/system_path.py @@ -0,0 +1,14 @@ +import logging +import os +import pathlib +import shutil + +_logger = logging.getLogger(__name__) + + +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): + shutil.rmtree(self, ignore_errors=ignore_errors) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/path.py b/tests/fixtures/path.py new file mode 100644 index 0000000..71ba2ec --- /dev/null +++ b/tests/fixtures/path.py @@ -0,0 +1,38 @@ +import logging +import re + +import pytest + +import configs +from scripts.utils.system_path import SystemPath + +_logger = logging.getLogger(__name__) + + +@pytest.fixture +def generate_test_data(request): + test_path, test_name, test_params = generate_test_info(request.node) + configs.testpath.TEST = configs.testpath.RUN / test_path / test_name + _logger.info(f'Start test: {test_name}') + + +def generate_test_info(node): + pure_path = SystemPath(node.location[0]).parts[1:] + test_path = SystemPath(*pure_path).with_suffix('') + test_name = node.originalname + test_params = re.sub('[^a-zA-Z0-9\n\-_]', '', node.name.strip(test_name)) + return test_path, test_name, test_params + + +@pytest.fixture(scope='session') +def run_dir(): + keep_results = 5 + run_name_pattern = 'run_????????_??????' + runs = list(sorted(configs.testpath.RESULTS.glob(run_name_pattern))) + if len(runs) > keep_results: + del_runs = runs[:len(runs) - keep_results] + for run in del_runs: + SystemPath(run).rmtree(ignore_errors=True) + _logger.info(f"Remove old test run directory: {run.relative_to(configs.testpath.ROOT)}") + configs.testpath.RUN.mkdir(parents=True, exist_ok=True) + _logger.info(f"Created new test run directory: {configs.testpath.RUN.relative_to(configs.testpath.ROOT)}") diff --git a/tests/test_self.py b/tests/test_self.py new file mode 100755 index 0000000..515e05a --- /dev/null +++ b/tests/test_self.py @@ -0,0 +1,13 @@ +import logging + +import pytest + +import driver + +_logger = logging.getLogger(__name__) + + +@pytest.mark.self +def test_import_squish(): + _logger.info(str(driver.__dict__)) + driver.snooze(1)