From 81e55598bc1a9747fe22a067955f82dea5045acf Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:24:10 +0100 Subject: [PATCH 01/31] disable explicit plugin loading --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 8c2d739..eb4bc7b 100644 --- a/main.py +++ b/main.py @@ -49,7 +49,7 @@ for key, value in CREDENTIALS.items(): # add abra-testing dir -os.environ["PYTEST_PLUGINS"] = "abratest.plugin-abra" # "abratest.plugin,abratest.other" +# os.environ["PYTEST_PLUGINS"] = "abratest.plugin-abra" # os.environ["PWDEBUG"] = "1" -- 2.47.2 From 88a217c4f255b91f7dd09f575e85b9ea5a96a721 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:37:37 +0100 Subject: [PATCH 02/31] rename --- abratest/{plugin-abra.py => pytest_abra.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename abratest/{plugin-abra.py => pytest_abra.py} (100%) diff --git a/abratest/plugin-abra.py b/abratest/pytest_abra.py similarity index 100% rename from abratest/plugin-abra.py rename to abratest/pytest_abra.py -- 2.47.2 From f7161d5c2c154ff000cb9c74584f55029897cfb1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:53:46 +0100 Subject: [PATCH 03/31] WIP: make pytest-abra installable also turn it into a pytest plugin (autoloaded) --- pyproject.toml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ec0809f..e696744 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,18 +1,30 @@ [project] -name = "abratest" +name = "pytest-abra" +description = "A pytest plugin to test instances of abra recipes" +authors = [{name = "Local-IT e.V."}] +readme = "README.md" version = "0.2.0" requires-python = "~=3.11" dependencies = [ "pytest == 7.4.3", + "playwright >= 1.40", ] -[project.optional-dependencies] -dev = [ - "ruff >= 0.1.7", -] +[project.scripts] +pytest11 = "pytest_abra.pytest_abra" + +[project.classifiers] +Programming Language = "Python :: 3" +Programming Language = "Python :: 3.11" +Programming Language = "Python :: 3.12" +Framework = "Pytest" [tool.setuptools] -package-dir = {"" = "abratest"} +package-dir = {"" = "pytest_abra"} + +[build-system] +requires = ["setuptools>=42.0", "wheel", "pip >= 21.1"] +build-backend = "setuptools.build_meta" [tool.ruff] line-length = 120 -- 2.47.2 From 8c2897469289f2262ef0763e84e54632396da49b Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:55:37 +0100 Subject: [PATCH 04/31] rename dir to pytest_abra --- {abratest => pytest_abra}/__init__.py | 0 {abratest => pytest_abra}/coordinator.py | 0 {abratest => pytest_abra}/dir_manager.py | 0 {abratest => pytest_abra}/env_manager.py | 0 {abratest => pytest_abra}/html_helper.py | 0 {abratest => pytest_abra}/pytest_abra.py | 0 {abratest => pytest_abra}/runner.py | 0 {abratest => pytest_abra}/utils.py | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename {abratest => pytest_abra}/__init__.py (100%) rename {abratest => pytest_abra}/coordinator.py (100%) rename {abratest => pytest_abra}/dir_manager.py (100%) rename {abratest => pytest_abra}/env_manager.py (100%) rename {abratest => pytest_abra}/html_helper.py (100%) rename {abratest => pytest_abra}/pytest_abra.py (100%) rename {abratest => pytest_abra}/runner.py (100%) rename {abratest => pytest_abra}/utils.py (100%) diff --git a/abratest/__init__.py b/pytest_abra/__init__.py similarity index 100% rename from abratest/__init__.py rename to pytest_abra/__init__.py diff --git a/abratest/coordinator.py b/pytest_abra/coordinator.py similarity index 100% rename from abratest/coordinator.py rename to pytest_abra/coordinator.py diff --git a/abratest/dir_manager.py b/pytest_abra/dir_manager.py similarity index 100% rename from abratest/dir_manager.py rename to pytest_abra/dir_manager.py diff --git a/abratest/env_manager.py b/pytest_abra/env_manager.py similarity index 100% rename from abratest/env_manager.py rename to pytest_abra/env_manager.py diff --git a/abratest/html_helper.py b/pytest_abra/html_helper.py similarity index 100% rename from abratest/html_helper.py rename to pytest_abra/html_helper.py diff --git a/abratest/pytest_abra.py b/pytest_abra/pytest_abra.py similarity index 100% rename from abratest/pytest_abra.py rename to pytest_abra/pytest_abra.py diff --git a/abratest/runner.py b/pytest_abra/runner.py similarity index 100% rename from abratest/runner.py rename to pytest_abra/runner.py diff --git a/abratest/utils.py b/pytest_abra/utils.py similarity index 100% rename from abratest/utils.py rename to pytest_abra/utils.py -- 2.47.2 From 1fb1d4adfbe86254942f5d024c767f59310c0bcb Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:57:17 +0100 Subject: [PATCH 05/31] change all imports --- README.md | 16 ++++++++-------- main.py | 8 +++----- previous-work/wordpress_test.py | 2 +- pytest_abra/coordinator.py | 10 +++++----- pytest_abra/env_manager.py | 4 ++-- pytest_abra/pytest_abra.py | 4 ++-- pytest_abra/runner.py | 4 ++-- .../tests_authentik/fixtures_authentik.py | 4 ++-- .../tests_authentik/runner_authentik.py | 2 +- .../authentik/tests_authentik/setup_authentik.py | 4 ++-- recipes/demo/tests_demo/fixtures_demo.py | 4 ++-- recipes/demo/tests_demo/runner_demo.py | 2 +- recipes/nextcloud/tests_nextcloud/conftest.py | 4 ++-- .../tests_nextcloud/runner_nextcloud.py | 2 +- .../nextcloud/tests_nextcloud/setup_nextcloud.py | 4 ++-- recipes/wordpress/tests_wordpress/conftest.py | 2 +- .../tests_wordpress/runner_wordpress.py | 2 +- .../wordpress/tests_wordpress/setup_wordpress.py | 2 +- .../test_wordpress_localization.py | 2 +- tests/test_env_resolution.py | 4 ++-- tests/test_url.py | 2 +- 21 files changed, 43 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 2ceb297..6e91a5f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# AbraTest +# pytest-abra ...description... # Usage -To use AbraTest, follow these steps: +To use pytest-abra, follow these steps: ## 1. GIT Clone @@ -17,7 +17,7 @@ git submodule update --remote // update submodules ## Run -You can run AbraTest with and without Docker. Choose now and follow the steps accordingly: +You can run pytest-abra with and without Docker. Choose now and follow the steps accordingly: ## 2.1 Run without Docker @@ -33,17 +33,17 @@ playwright install Run the script with ```bash -python main.py # run abratest -pytest # test abratest -pytest --collect-only # debug test abratest +python main.py # run pytest-abra +pytest # test pytest-abra +pytest --collect-only # debug test pytest-abra ``` # 2.2 Run with Docker ```bash docker compose build # build the image -docker compose run --rm app ./run_abratest.sh # run AbraTest -docker compose run --rm app ./test_abratest.sh # test AbraTest +docker compose run --rm app ./run_pytest-abra.sh # run pytest-abra +docker compose run --rm app ./test_pytest-abra.sh # test pytest-abra ``` Force rebuild with cache diff --git a/main.py b/main.py index eb4bc7b..b939aa5 100644 --- a/main.py +++ b/main.py @@ -4,9 +4,9 @@ from pathlib import Path from loguru import logger -from abratest.coordinator import Coordinator -from abratest.dir_manager import DirManager -from abratest.utils import get_session_id +from pytest_abra.coordinator import Coordinator +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import get_session_id # ----------------------------- lookup env files ----------------------------- # @@ -48,8 +48,6 @@ for key, value in CREDENTIALS.items(): # -------------------------- enable playwright debug ------------------------- # -# add abra-testing dir -# os.environ["PYTEST_PLUGINS"] = "abratest.plugin-abra" # os.environ["PWDEBUG"] = "1" diff --git a/previous-work/wordpress_test.py b/previous-work/wordpress_test.py index bf61351..9f8173f 100644 --- a/previous-work/wordpress_test.py +++ b/previous-work/wordpress_test.py @@ -1,6 +1,6 @@ from playwright.sync_api import BrowserContext, expect -from abratest.dir_manager import DirManager +from pytest_abra.dir_manager import DirManager def test_wordpress(admin_session: BrowserContext, dotenv_config: dict[str, str], DIR: DirManager): diff --git a/pytest_abra/coordinator.py b/pytest_abra/coordinator.py index 28a5102..8dd6f0f 100644 --- a/pytest_abra/coordinator.py +++ b/pytest_abra/coordinator.py @@ -4,11 +4,11 @@ from pathlib import Path from loguru import logger -from abratest.dir_manager import DirManager -from abratest.env_manager import EnvFile, EnvManager -from abratest.html_helper import merge_html_files -from abratest.runner import Runner -from abratest.utils import rmtree +from pytest_abra.dir_manager import DirManager +from pytest_abra.env_manager import EnvFile, EnvManager +from pytest_abra.html_helper import merge_html_files +from pytest_abra.runner import Runner +from pytest_abra.utils import rmtree class Coordinator: diff --git a/pytest_abra/env_manager.py b/pytest_abra/env_manager.py index 780436f..f6f16b5 100644 --- a/pytest_abra/env_manager.py +++ b/pytest_abra/env_manager.py @@ -4,8 +4,8 @@ from typing import NamedTuple from dotenv import dotenv_values -from abratest.dir_manager import DirManager -from abratest.runner import Runner +from pytest_abra.dir_manager import DirManager +from pytest_abra.runner import Runner class EnvFile(NamedTuple): diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index c72b21b..e2f28ae 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -14,8 +14,8 @@ from dotenv import dotenv_values from playwright.sync_api import BrowserContext, expect from pytest import Parser -from abratest.dir_manager import DirManager -from abratest.utils import BaseUrl +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import BaseUrl # global timeout and LOCALE LOCALE = {"Accept-Language": "de_DE"} diff --git a/pytest_abra/runner.py b/pytest_abra/runner.py index c9cbc9e..7486be3 100644 --- a/pytest_abra/runner.py +++ b/pytest_abra/runner.py @@ -6,8 +6,8 @@ import pytest from loguru import logger if TYPE_CHECKING: - from abratest.coordinator import Coordinator - from abratest.env_manager import EnvFile + from pytest_abra.coordinator import Coordinator + from pytest_abra.env_manager import EnvFile @dataclass diff --git a/recipes/authentik/tests_authentik/fixtures_authentik.py b/recipes/authentik/tests_authentik/fixtures_authentik.py index 34ed3d7..fa50e3f 100644 --- a/recipes/authentik/tests_authentik/fixtures_authentik.py +++ b/recipes/authentik/tests_authentik/fixtures_authentik.py @@ -3,8 +3,8 @@ import json import pytest from playwright.sync_api import BrowserContext, Page -from abratest.dir_manager import DirManager -from abratest.utils import BaseUrl +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import BaseUrl @pytest.fixture diff --git a/recipes/authentik/tests_authentik/runner_authentik.py b/recipes/authentik/tests_authentik/runner_authentik.py index b83da2f..fb8c3b2 100644 --- a/recipes/authentik/tests_authentik/runner_authentik.py +++ b/recipes/authentik/tests_authentik/runner_authentik.py @@ -1,4 +1,4 @@ -from abratest.runner import Runner, Test +from pytest_abra.runner import Runner, Test def condition_always_true(dotenv_config: dict[str, str]) -> bool: diff --git a/recipes/authentik/tests_authentik/setup_authentik.py b/recipes/authentik/tests_authentik/setup_authentik.py index b7f7f37..680a85d 100644 --- a/recipes/authentik/tests_authentik/setup_authentik.py +++ b/recipes/authentik/tests_authentik/setup_authentik.py @@ -4,8 +4,8 @@ import re from playwright.sync_api import BrowserContext, expect -from abratest.dir_manager import DirManager -from abratest.utils import BaseUrl +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import BaseUrl ADMIN_USER = os.environ["ADMIN_USER"] ADMIN_PASS = os.environ["ADMIN_PASS"] diff --git a/recipes/demo/tests_demo/fixtures_demo.py b/recipes/demo/tests_demo/fixtures_demo.py index b271e60..c650202 100644 --- a/recipes/demo/tests_demo/fixtures_demo.py +++ b/recipes/demo/tests_demo/fixtures_demo.py @@ -5,7 +5,7 @@ depend on [demo]. For this to work 1. the Runner class of the other test needs to define the depencency as seen by referencing RunnerDemo in the dependencies list: -from abratest.tests_demo.runner_demo import RunnerDemo +from pytest_abra.tests_demo.runner_demo import RunnerDemo class RunnerOther(Runner): dependencies = [RunnerDemo] @@ -15,7 +15,7 @@ class RunnerOther(Runner): To globally import for all tests in 'other', the import should be done in conftest: in 'conftest.py' in 'test_other' dir: -from abratest.tests_demo.fixtures_demo import demo_fixture +from pytest_abra.tests_demo.fixtures_demo import demo_fixture """ import pytest diff --git a/recipes/demo/tests_demo/runner_demo.py b/recipes/demo/tests_demo/runner_demo.py index 2b9aa78..e735e5f 100644 --- a/recipes/demo/tests_demo/runner_demo.py +++ b/recipes/demo/tests_demo/runner_demo.py @@ -1,4 +1,4 @@ -from abratest.runner import Runner, Test +from pytest_abra.runner import Runner, Test class RunnerDemo(Runner): diff --git a/recipes/nextcloud/tests_nextcloud/conftest.py b/recipes/nextcloud/tests_nextcloud/conftest.py index abdf9f9..ce56379 100644 --- a/recipes/nextcloud/tests_nextcloud/conftest.py +++ b/recipes/nextcloud/tests_nextcloud/conftest.py @@ -4,8 +4,8 @@ import os import pytest from playwright.sync_api import BrowserContext, Page -from abratest.dir_manager import DirManager -from abratest.utils import BaseUrl +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import BaseUrl pytest_plugins = "authentik.tests_authentik.fixtures_authentik" diff --git a/recipes/nextcloud/tests_nextcloud/runner_nextcloud.py b/recipes/nextcloud/tests_nextcloud/runner_nextcloud.py index 5f7fe27..79b5050 100644 --- a/recipes/nextcloud/tests_nextcloud/runner_nextcloud.py +++ b/recipes/nextcloud/tests_nextcloud/runner_nextcloud.py @@ -1,4 +1,4 @@ -from abratest.runner import Runner, Test +from pytest_abra.runner import Runner, Test def condition_always_false(dotenv_config: dict[str, str]) -> bool: diff --git a/recipes/nextcloud/tests_nextcloud/setup_nextcloud.py b/recipes/nextcloud/tests_nextcloud/setup_nextcloud.py index 020d56d..f400ce3 100644 --- a/recipes/nextcloud/tests_nextcloud/setup_nextcloud.py +++ b/recipes/nextcloud/tests_nextcloud/setup_nextcloud.py @@ -1,7 +1,7 @@ from playwright.sync_api import Page, expect -from abratest.dir_manager import DirManager -from abratest.utils import BaseUrl +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import BaseUrl # url dashboard # https://files.test.dev.local-it.cloud/apps/dashboard/ diff --git a/recipes/wordpress/tests_wordpress/conftest.py b/recipes/wordpress/tests_wordpress/conftest.py index c91a525..77977a9 100644 --- a/recipes/wordpress/tests_wordpress/conftest.py +++ b/recipes/wordpress/tests_wordpress/conftest.py @@ -4,7 +4,7 @@ import pytest from dotenv import dotenv_values from playwright.sync_api import BrowserContext, Page -from abratest.dir_manager import DirManager +from pytest_abra.dir_manager import DirManager pytest_plugins = "authentik.tests_authentik.fixtures_authentik" diff --git a/recipes/wordpress/tests_wordpress/runner_wordpress.py b/recipes/wordpress/tests_wordpress/runner_wordpress.py index 846f069..eae53ee 100644 --- a/recipes/wordpress/tests_wordpress/runner_wordpress.py +++ b/recipes/wordpress/tests_wordpress/runner_wordpress.py @@ -1,4 +1,4 @@ -from abratest.runner import Runner, Test +from pytest_abra.runner import Runner, Test def condition_always_true(dotenv_config: dict[str, str]) -> bool: diff --git a/recipes/wordpress/tests_wordpress/setup_wordpress.py b/recipes/wordpress/tests_wordpress/setup_wordpress.py index 0d8243a..b9fd773 100644 --- a/recipes/wordpress/tests_wordpress/setup_wordpress.py +++ b/recipes/wordpress/tests_wordpress/setup_wordpress.py @@ -1,7 +1,7 @@ import pytest from playwright.sync_api import BrowserContext, Page, expect -from abratest.dir_manager import DirManager +from pytest_abra.dir_manager import DirManager def test_visit_from_domain(authentik_admin_context: BrowserContext, dotenv_config: dict[str, str]): diff --git a/recipes/wordpress/tests_wordpress/test_wordpress_localization.py b/recipes/wordpress/tests_wordpress/test_wordpress_localization.py index 1583a9f..a0c76ba 100644 --- a/recipes/wordpress/tests_wordpress/test_wordpress_localization.py +++ b/recipes/wordpress/tests_wordpress/test_wordpress_localization.py @@ -2,7 +2,7 @@ from playwright.sync_api import BrowserContext, expect -from abratest.dir_manager import DirManager +from pytest_abra.dir_manager import DirManager def test_welcome_message(context: BrowserContext, dotenv_config: dict[str, str], DIR: DirManager): diff --git a/tests/test_env_resolution.py b/tests/test_env_resolution.py index 87f6f7c..4b11941 100644 --- a/tests/test_env_resolution.py +++ b/tests/test_env_resolution.py @@ -2,8 +2,8 @@ from pathlib import Path import pytest -from abratest.coordinator import Coordinator -from abratest.env_manager import DependencyRule, EnvFile, EnvManager +from pytest_abra.coordinator import Coordinator +from pytest_abra.env_manager import DependencyRule, EnvFile, EnvManager RECIPES_DIR = Path("./recipes").resolve() RUNNER_DICT = Coordinator.create_runner_dict(RECIPES_DIR) diff --git a/tests/test_url.py b/tests/test_url.py index 680023f..82b9f44 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -1,4 +1,4 @@ -from abratest.utils import BaseUrl +from pytest_abra.utils import BaseUrl url_input = { "netloc": "blog.dev.local-it.cloud", -- 2.47.2 From 95c7a19eddae80aec3ed949ab76cd3f2329828f0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 12:59:02 +0100 Subject: [PATCH 06/31] update doc --- pytest_abra/pytest_abra.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index e2f28ae..aebfdee 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -1,9 +1,5 @@ -# regarding conftest: -# If you have conftest.py files which do not reside in a python package directory -# (i.e. one containing an __init__.py) then “import conftest” can be ambiguous -# because there might be other conftest.py files as well on your PYTHONPATH or -# sys.path. It is thus good practise for projects to either put conftest.py under -# a package scope or to never import anything from a conftest.py file. +# This file is registered as a pytest plugin, meaning it will automatically loaded. +# All fixtures in this file will be available without manual loading. import os from imaplib import IMAP4_SSL -- 2.47.2 From b76f031f1ea18df1531e8a0dee8e7f1bcdba9aa4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:07:39 +0100 Subject: [PATCH 07/31] fix syntax --- pyproject.toml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e696744..a6de8bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,20 +4,21 @@ description = "A pytest plugin to test instances of abra recipes" authors = [{name = "Local-IT e.V."}] readme = "README.md" version = "0.2.0" -requires-python = "~=3.11" +requires-python = ">=3.10" +classifiers = [ +"Programming Language :: Python :: 3", +"Programming Language :: Python :: 3.10", +"Programming Language :: Python :: 3.11", +"Programming Language :: Python :: 3.12", +"Framework :: Pytest", +] dependencies = [ "pytest == 7.4.3", "playwright >= 1.40", ] [project.scripts] -pytest11 = "pytest_abra.pytest_abra" - -[project.classifiers] -Programming Language = "Python :: 3" -Programming Language = "Python :: 3.11" -Programming Language = "Python :: 3.12" -Framework = "Pytest" +pytest11 = "pytest_abra:pytest_abra" [tool.setuptools] package-dir = {"" = "pytest_abra"} -- 2.47.2 From 188305421b396a4849c591674a967f72708dfda8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:07:54 +0100 Subject: [PATCH 08/31] add *.egg-info --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 46d7f87..78cd629 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ TestResults/ *.pyc *.json *.zip +*.egg-info credentials* \ No newline at end of file -- 2.47.2 From 9d18d4ad391b78efef3bd573a1eafb042ee659b2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:12:50 +0100 Subject: [PATCH 09/31] remove unused conftest --- conftest.py | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 conftest.py diff --git a/conftest.py b/conftest.py deleted file mode 100644 index 8704865..0000000 --- a/conftest.py +++ /dev/null @@ -1,2 +0,0 @@ -# this file exists so that tests inside /tests always find /src imports, -# because this will cause the root (/) to be added to sys.path -- 2.47.2 From 5c59c3b4446c29369d8fe4f32197856b9171cb7c Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:15:57 +0100 Subject: [PATCH 10/31] add hatchling --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 88b903b..be7218a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ icecream loguru beautifulsoup4 imbox +hatchling \ No newline at end of file -- 2.47.2 From bdf427224c69175810256ac9ead8ee51efedfd63 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:19:23 +0100 Subject: [PATCH 11/31] update dependencies, change build-system to hatchling --- pyproject.toml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a6de8bc..d7492d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,18 +14,26 @@ classifiers = [ ] dependencies = [ "pytest == 7.4.3", - "playwright >= 1.40", + "playwright == 1.40", + "pytest-html == 4.1.1", + "pytest-playwright == 0.4.3", + "python-dotenv == 1.0.0", + "loguru == 0.7.2", + "beautifulsoup4 == 4.12.2", + "imbox == 0.9.8", + "hatchling == 1.18.0", + "icecream", ] [project.scripts] pytest11 = "pytest_abra:pytest_abra" [tool.setuptools] -package-dir = {"" = "pytest_abra"} +package-dir = {"" = ""} [build-system] -requires = ["setuptools>=42.0", "wheel", "pip >= 21.1"] -build-backend = "setuptools.build_meta" +requires = ["hatchling"] +build-backend = "hatchling.build" [tool.ruff] line-length = 120 -- 2.47.2 From 87fcab5b29ad61fb4e43123c396e8acdb1d96a70 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 13:23:44 +0100 Subject: [PATCH 12/31] move testing to Development --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6e91a5f..d3d3604 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,7 @@ playwright install Run the script with ```bash -python main.py # run pytest-abra -pytest # test pytest-abra -pytest --collect-only # debug test pytest-abra +python main.py ``` # 2.2 Run with Docker @@ -43,7 +41,6 @@ pytest --collect-only # debug test pytest-abra ```bash docker compose build # build the image docker compose run --rm app ./run_pytest-abra.sh # run pytest-abra -docker compose run --rm app ./test_pytest-abra.sh # test pytest-abra ``` Force rebuild with cache @@ -64,4 +61,12 @@ Use playwright codegen to create code for new testes easily https://playwright.d ```bash playwright codegen demo.playwright.dev/todomvc -``` \ No newline at end of file +``` + +## Development + +```bash +pytest # test pytest-abra +pytest --collect-only # debug test pytest-abra +docker compose run --rm app ./test_pytest-abra.sh # test pytest-abra +``` -- 2.47.2 From a23a9810ddf2f870c3740d8fd1c5b93a7c47774d Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 14:25:25 +0100 Subject: [PATCH 13/31] fix pytest11 entrypoint, add wip scripts --- pyproject.toml | 19 +++++++++++++++---- pytest_abra/demo.py | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 pytest_abra/demo.py diff --git a/pyproject.toml b/pyproject.toml index d7492d4..9fafad8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,16 +25,27 @@ dependencies = [ "icecream", ] -[project.scripts] -pytest11 = "pytest_abra:pytest_abra" +[project.entry_points] +pytest11 = [ + "pytest_abra = pytest_abra.pytest_abra", +] -[tool.setuptools] -package-dir = {"" = ""} +[project.scripts] +abrademo = "pytest_abra:demo" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" +[tool.hatch.build] +include = [ + "pytest_abra/*.py", +] +exclude = [ + "*.json", +] + + [tool.ruff] line-length = 120 target-version = "py311" diff --git a/pytest_abra/demo.py b/pytest_abra/demo.py new file mode 100644 index 0000000..0ece3c2 --- /dev/null +++ b/pytest_abra/demo.py @@ -0,0 +1 @@ +print("wooooorking") -- 2.47.2 From e1dc085252e5b56bc1c867abd824917c9795ff48 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 21:55:21 +0100 Subject: [PATCH 14/31] fix env file path --- main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index b939aa5..4d3cee1 100644 --- a/main.py +++ b/main.py @@ -20,10 +20,11 @@ from pytest_abra.utils import get_session_id # At the moment, functionailty is only guaranteed if each env file use # a unique TYPE var. +ENV_FILES_ROOT = Path("../envfiles").resolve() ENV_FILES = [ - Path("envfiles/login.test.dev.local-it.cloud.env"), # authentik - Path("envfiles/blog.test.dev.local-it.cloud.env"), # wordpress - # Path("envfiles/files.test.dev.local-it.cloud.env"), # nextcloud + ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik + ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress + ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud ] @@ -31,7 +32,7 @@ ENV_FILES = [ OUTPUT_DIR = Path("./test-output").resolve() -RECIPES_DIR = Path("./recipes").resolve() +RECIPES_DIR = Path("../recipes").resolve() # --------------------- load credentials to env variables -------------------- # -- 2.47.2 From b9bf2f026eb2d97cba95fdc484ff36b5c3274bc9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 21:55:57 +0100 Subject: [PATCH 15/31] rename old main file --- main.py => main-old.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename main.py => main-old.py (100%) diff --git a/main.py b/main-old.py similarity index 100% rename from main.py rename to main-old.py -- 2.47.2 From a2a1e86d0e677ad5861def7c88de991bb9144620 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 21:56:05 +0100 Subject: [PATCH 16/31] add new main file --- pytest_abra/main.py | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 pytest_abra/main.py diff --git a/pytest_abra/main.py b/pytest_abra/main.py new file mode 100644 index 0000000..4d3cee1 --- /dev/null +++ b/pytest_abra/main.py @@ -0,0 +1,79 @@ +import json +import os +from pathlib import Path + +from loguru import logger + +from pytest_abra.coordinator import Coordinator +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import get_session_id + +# ----------------------------- lookup env files ----------------------------- # + + +# This list of env files is the input to testing framework. each env file +# triggers the execution of one test Runner and provides configuration to the +# tests inside the runner. There can be dependencies, for example wordpress +# requires that authentik ran first to create the admin session and the user +# session. At the moment, wrong ordering results in unsuccessful test +# (wrong ordering would be wordpress env file is before authentik env file). +# At the moment, functionailty is only guaranteed if each env file use +# a unique TYPE var. + +ENV_FILES_ROOT = Path("../envfiles").resolve() +ENV_FILES = [ + ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik + ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress + ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud +] + + +# ----------------------------- define ouptut dir ---------------------------- # + + +OUTPUT_DIR = Path("./test-output").resolve() +RECIPES_DIR = Path("../recipes").resolve() + + +# --------------------- load credentials to env variables -------------------- # + + +cred_file = Path("credentials.json") +with open(cred_file, "r") as f: + CREDENTIALS = json.load(f) + +for key, value in CREDENTIALS.items(): + os.environ[key] = value + + +# -------------------------- enable playwright debug ------------------------- # + + +# os.environ["PWDEBUG"] = "1" + + +# ----------------------------- define session_id ---------------------------- # + + +session_id = get_session_id() +# session_id = "abc" + + +# ------------------------------- setup logging ------------------------------ # + + +DIR = DirManager(output_dir=OUTPUT_DIR, session_id=session_id) +log_file = DIR.RECORDS / "coordinator.log" +logger.add(log_file) + + +# ---------------------------- initialize and run ---------------------------- # + + +coordinator = Coordinator( + env_paths_list=ENV_FILES, output_dir=OUTPUT_DIR, session_id=session_id, recipes_dir=RECIPES_DIR +) +coordinator.setup_test() +coordinator.run_test() +coordinator.combine_html() +coordinator.collect_traces() -- 2.47.2 From 808170c6c5efe47f4ae3a4fc89b14b8fa7298dc3 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 22:30:30 +0100 Subject: [PATCH 17/31] use session_id directly as dir --- pytest_abra/dir_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest_abra/dir_manager.py b/pytest_abra/dir_manager.py index 2104a68..0125522 100644 --- a/pytest_abra/dir_manager.py +++ b/pytest_abra/dir_manager.py @@ -46,7 +46,7 @@ class DirManager: @property def SESSION(self): - return self.OUTPUT_DIR / f"test-{self.session_id}" + return self.OUTPUT_DIR / self.session_id @property def RECORDS(self): -- 2.47.2 From 38d4a7fcf20b8f5783fc4bb1f31ec9d4add85064 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 22:32:32 +0100 Subject: [PATCH 18/31] rename to get_datetime_string --- pytest_abra/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest_abra/utils.py b/pytest_abra/utils.py index e98fa9b..b820416 100644 --- a/pytest_abra/utils.py +++ b/pytest_abra/utils.py @@ -17,7 +17,7 @@ class BaseUrl: return urlunparse((self.scheme, self.netloc, path, self.params, self.query, self.fragment)) -def get_session_id() -> str: +def get_datetime_string() -> str: current_datetime = datetime.now() return current_datetime.strftime("%Y-%m-%d-%H-%M-%S") -- 2.47.2 From a26d5f2e8415bbda68a16654fc5fb159b8a610f4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 22:33:29 +0100 Subject: [PATCH 19/31] fix project.scripts --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9fafad8..2536902 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ pytest11 = [ ] [project.scripts] -abrademo = "pytest_abra:demo" +abrademo = "pytest_abra.main:run" [build-system] requires = ["hatchling"] -- 2.47.2 From 35908ddc00153bf4dafac26ebbd878adf5b1a4ef Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:00:20 +0100 Subject: [PATCH 20/31] add note --- pytest_abra/pytest_abra.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index aebfdee..618d6fe 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -21,6 +21,9 @@ expect.set_options(timeout=TIMEOUT) @pytest.fixture def context(context: BrowserContext) -> BrowserContext: + # note: because this has the existing context fixture as an argument, it is ensured + # that the original fixture is called first and then overwritten by this custom one. + context.set_default_timeout(TIMEOUT) context.set_extra_http_headers(LOCALE) return context -- 2.47.2 From 93106df3b962c6cd79343948ed152301a662eefb Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:11:24 +0100 Subject: [PATCH 21/31] wip: add cli command with [project.scripts] --- pyproject.toml | 2 +- pytest_abra/cli.py | 68 ++++++++++++++++++++++++++++++++++++++ pytest_abra/main.py | 79 --------------------------------------------- 3 files changed, 69 insertions(+), 80 deletions(-) create mode 100644 pytest_abra/cli.py delete mode 100644 pytest_abra/main.py diff --git a/pyproject.toml b/pyproject.toml index 2536902..29d8ee9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ pytest11 = [ ] [project.scripts] -abrademo = "pytest_abra.main:run" +pytest-abra = "pytest_abra.cli:run" [build-system] requires = ["hatchling"] diff --git a/pytest_abra/cli.py b/pytest_abra/cli.py new file mode 100644 index 0000000..3d98853 --- /dev/null +++ b/pytest_abra/cli.py @@ -0,0 +1,68 @@ +import argparse +import os +from pathlib import Path + +from loguru import logger + +from pytest_abra.coordinator import Coordinator +from pytest_abra.dir_manager import DirManager +from pytest_abra.utils import get_datetime_string + + +def run(): + parser = argparse.ArgumentParser() + parser.add_argument("--debug", action="store_true", help="Enable Playwright debug mode") + parser.add_argument("--repeat", action="store_true", help="Re-run the most recent test") + args = parser.parse_args() + + # ----------------------------- lookup env files ----------------------------- # + + # This list of env files is the input to testing framework. each env file + # triggers the execution of one test Runner and provides configuration to the + # tests inside the runner. There can be dependencies, for example wordpress + # requires that authentik ran first to create the admin session and the user + # session. At the moment, wrong ordering results in unsuccessful test + # (wrong ordering would be wordpress env file is before authentik env file). + # At the moment, functionailty is only guaranteed if each env file use + # a unique TYPE var. + + ENV_FILES_ROOT = Path("../envfiles").resolve() + ENV_FILES = [ + ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik + ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress + ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud + ] + + # ----------------------------- define ouptut dir ---------------------------- # + + OUTPUT_DIR = Path("./test-output").resolve() + RECIPES_DIR = Path("../recipes").resolve() + + # -------------------------- enable playwright debug ------------------------- # + + if args.debug: + os.environ["PWDEBUG"] = "1" + + # ----------------------------- define session_id ---------------------------- # + + session_id = "test-" + get_datetime_string() + if args.repeat: + # look for previous session_id + pass + # session_id = "abc" + + # ------------------------------- setup logging ------------------------------ # + + DIR = DirManager(output_dir=OUTPUT_DIR, session_id=session_id) + log_file = DIR.RECORDS / "coordinator.log" + logger.add(log_file) + + # ---------------------------- initialize and run ---------------------------- # + + coordinator = Coordinator( + env_paths_list=ENV_FILES, output_dir=OUTPUT_DIR, session_id=session_id, recipes_dir=RECIPES_DIR + ) + coordinator.setup_test() + coordinator.run_test() + coordinator.combine_html() + coordinator.collect_traces() diff --git a/pytest_abra/main.py b/pytest_abra/main.py deleted file mode 100644 index 4d3cee1..0000000 --- a/pytest_abra/main.py +++ /dev/null @@ -1,79 +0,0 @@ -import json -import os -from pathlib import Path - -from loguru import logger - -from pytest_abra.coordinator import Coordinator -from pytest_abra.dir_manager import DirManager -from pytest_abra.utils import get_session_id - -# ----------------------------- lookup env files ----------------------------- # - - -# This list of env files is the input to testing framework. each env file -# triggers the execution of one test Runner and provides configuration to the -# tests inside the runner. There can be dependencies, for example wordpress -# requires that authentik ran first to create the admin session and the user -# session. At the moment, wrong ordering results in unsuccessful test -# (wrong ordering would be wordpress env file is before authentik env file). -# At the moment, functionailty is only guaranteed if each env file use -# a unique TYPE var. - -ENV_FILES_ROOT = Path("../envfiles").resolve() -ENV_FILES = [ - ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik - ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress - ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud -] - - -# ----------------------------- define ouptut dir ---------------------------- # - - -OUTPUT_DIR = Path("./test-output").resolve() -RECIPES_DIR = Path("../recipes").resolve() - - -# --------------------- load credentials to env variables -------------------- # - - -cred_file = Path("credentials.json") -with open(cred_file, "r") as f: - CREDENTIALS = json.load(f) - -for key, value in CREDENTIALS.items(): - os.environ[key] = value - - -# -------------------------- enable playwright debug ------------------------- # - - -# os.environ["PWDEBUG"] = "1" - - -# ----------------------------- define session_id ---------------------------- # - - -session_id = get_session_id() -# session_id = "abc" - - -# ------------------------------- setup logging ------------------------------ # - - -DIR = DirManager(output_dir=OUTPUT_DIR, session_id=session_id) -log_file = DIR.RECORDS / "coordinator.log" -logger.add(log_file) - - -# ---------------------------- initialize and run ---------------------------- # - - -coordinator = Coordinator( - env_paths_list=ENV_FILES, output_dir=OUTPUT_DIR, session_id=session_id, recipes_dir=RECIPES_DIR -) -coordinator.setup_test() -coordinator.run_test() -coordinator.combine_html() -coordinator.collect_traces() -- 2.47.2 From cb37e4b02334b56d24b3d3765c6e715bbe70fd89 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:11:46 +0100 Subject: [PATCH 22/31] add env testing prototype --- prototyping/env_var_subprocess.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 prototyping/env_var_subprocess.py diff --git a/prototyping/env_var_subprocess.py b/prototyping/env_var_subprocess.py new file mode 100644 index 0000000..aa0a027 --- /dev/null +++ b/prototyping/env_var_subprocess.py @@ -0,0 +1,17 @@ +import os +import subprocess + +# Set an environment variable in the parent process +os.environ["PARENT_VARIABLE"] = "12345s" + +# Spawn a subprocess and modify the environment variable +subprocess.run( + [ + "python", + "-c", + "import os; print('b', os.environ['PARENT_VARIABLE']); os.environ['PARENT_VARIABLE'] = 'modified_value'; print('c', os.environ['PARENT_VARIABLE'])", + ] +) + +# Check if the modification in the subprocess affected the parent process +print("a", os.environ["PARENT_VARIABLE"]) # This will print 'parent_value', not 'modified_value' -- 2.47.2 From 65d3753295065f80157ed8050cfa726348f7803e Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:14:40 +0100 Subject: [PATCH 23/31] add new main, run abratest through cli --- main.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..f91d0e3 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +import json +import os +import subprocess +from pathlib import Path + +# --------------------- load credentials to env variables -------------------- # + +cred_file = Path("credentials.json") +with open(cred_file, "r") as f: + CREDENTIALS = json.load(f) + +for key, value in CREDENTIALS.items(): + os.environ[key] = value + + +subprocess.run( + [ + "pytest-abra", + # "--debug", + ] +) -- 2.47.2 From 28b1af57a664aa87f7907c090651106a5848ae1c Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:26:20 +0100 Subject: [PATCH 24/31] add more arguments and move everything from cli to main --- main.py | 27 +++++++++++++++++++++++++++ pytest_abra/cli.py | 32 +++++++++++--------------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/main.py b/main.py index f91d0e3..84017e0 100644 --- a/main.py +++ b/main.py @@ -12,10 +12,37 @@ with open(cred_file, "r") as f: for key, value in CREDENTIALS.items(): os.environ[key] = value +# --------------------------------- env files -------------------------------- # + +# This list of env files is the input to testing framework. each env file +# triggers the execution of one test Runner and provides configuration to the +# tests inside the runner. + +ENV_FILES_ROOT = Path("../envfiles").resolve() +ENV_FILES = [ + ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik + ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress + ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud +] +ENV_PATHS = ";".join([x.as_posix() for x in ENV_FILES]) + +# ----------------------------------- dirs ----------------------------------- # + +RECIPES_DIR = Path("../recipes").resolve() +OUTPUT_DIR = Path("./test-output").resolve() + + +# exit() subprocess.run( [ "pytest-abra", + "--env_paths", + ENV_PATHS, + "--recipes_dir", + RECIPES_DIR, + "--output_dir", + OUTPUT_DIR, # "--debug", ] ) diff --git a/pytest_abra/cli.py b/pytest_abra/cli.py index 3d98853..5d1d414 100644 --- a/pytest_abra/cli.py +++ b/pytest_abra/cli.py @@ -11,32 +11,22 @@ from pytest_abra.utils import get_datetime_string def run(): parser = argparse.ArgumentParser() + parser.add_argument("--env_paths", type=str, help="List of loaded env files separated with ;") + parser.add_argument("--recipes_dir", type=str, help="List of loaded env files separated with ;") + parser.add_argument("--output_dir", type=str, help="List of loaded env files separated with ;") + parser.add_argument("--debug", action="store_true", help="Enable Playwright debug mode") - parser.add_argument("--repeat", action="store_true", help="Re-run the most recent test") + parser.add_argument( + "--resume", action="store_true", help="Re-run the most recent test, only running tests without status 'passed'" + ) args = parser.parse_args() - # ----------------------------- lookup env files ----------------------------- # - - # This list of env files is the input to testing framework. each env file - # triggers the execution of one test Runner and provides configuration to the - # tests inside the runner. There can be dependencies, for example wordpress - # requires that authentik ran first to create the admin session and the user - # session. At the moment, wrong ordering results in unsuccessful test - # (wrong ordering would be wordpress env file is before authentik env file). - # At the moment, functionailty is only guaranteed if each env file use - # a unique TYPE var. - - ENV_FILES_ROOT = Path("../envfiles").resolve() - ENV_FILES = [ - ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik - ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress - ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud - ] + ENV_FILES = [Path(s) for s in args.env_paths.split(";")] # ----------------------------- define ouptut dir ---------------------------- # - OUTPUT_DIR = Path("./test-output").resolve() - RECIPES_DIR = Path("../recipes").resolve() + RECIPES_DIR = Path(args.recipes_dir) + OUTPUT_DIR = Path(args.output_dir) # -------------------------- enable playwright debug ------------------------- # @@ -46,7 +36,7 @@ def run(): # ----------------------------- define session_id ---------------------------- # session_id = "test-" + get_datetime_string() - if args.repeat: + if args.resume: # look for previous session_id pass # session_id = "abc" -- 2.47.2 From e2f4ac5654a5c91c13d089f416ad8b7d80ddb970 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:26:39 +0100 Subject: [PATCH 25/31] remove old main --- main-old.py | 79 ----------------------------------------------------- 1 file changed, 79 deletions(-) delete mode 100644 main-old.py diff --git a/main-old.py b/main-old.py deleted file mode 100644 index 4d3cee1..0000000 --- a/main-old.py +++ /dev/null @@ -1,79 +0,0 @@ -import json -import os -from pathlib import Path - -from loguru import logger - -from pytest_abra.coordinator import Coordinator -from pytest_abra.dir_manager import DirManager -from pytest_abra.utils import get_session_id - -# ----------------------------- lookup env files ----------------------------- # - - -# This list of env files is the input to testing framework. each env file -# triggers the execution of one test Runner and provides configuration to the -# tests inside the runner. There can be dependencies, for example wordpress -# requires that authentik ran first to create the admin session and the user -# session. At the moment, wrong ordering results in unsuccessful test -# (wrong ordering would be wordpress env file is before authentik env file). -# At the moment, functionailty is only guaranteed if each env file use -# a unique TYPE var. - -ENV_FILES_ROOT = Path("../envfiles").resolve() -ENV_FILES = [ - ENV_FILES_ROOT / "login.test.dev.local-it.cloud.env", # authentik - ENV_FILES_ROOT / "blog.test.dev.local-it.cloud.env", # wordpress - ENV_FILES_ROOT / "files.test.dev.local-it.cloud.env", # nextcloud -] - - -# ----------------------------- define ouptut dir ---------------------------- # - - -OUTPUT_DIR = Path("./test-output").resolve() -RECIPES_DIR = Path("../recipes").resolve() - - -# --------------------- load credentials to env variables -------------------- # - - -cred_file = Path("credentials.json") -with open(cred_file, "r") as f: - CREDENTIALS = json.load(f) - -for key, value in CREDENTIALS.items(): - os.environ[key] = value - - -# -------------------------- enable playwright debug ------------------------- # - - -# os.environ["PWDEBUG"] = "1" - - -# ----------------------------- define session_id ---------------------------- # - - -session_id = get_session_id() -# session_id = "abc" - - -# ------------------------------- setup logging ------------------------------ # - - -DIR = DirManager(output_dir=OUTPUT_DIR, session_id=session_id) -log_file = DIR.RECORDS / "coordinator.log" -logger.add(log_file) - - -# ---------------------------- initialize and run ---------------------------- # - - -coordinator = Coordinator( - env_paths_list=ENV_FILES, output_dir=OUTPUT_DIR, session_id=session_id, recipes_dir=RECIPES_DIR -) -coordinator.setup_test() -coordinator.run_test() -coordinator.combine_html() -coordinator.collect_traces() -- 2.47.2 From 05423e0770597e6ea8b435d8e7d6e84c018b5234 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 6 Dec 2023 23:38:47 +0100 Subject: [PATCH 26/31] make abra pytest arguments non-required --- pytest_abra/pytest_abra.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index 618d6fe..be7c1e2 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -33,17 +33,14 @@ def pytest_addoption(parser: Parser): parser.addoption( "--env_file", action="store", - required=True, ) parser.addoption( "--output_dir", action="store", - required=True, ) parser.addoption( "--session_id", action="store", - required=True, ) @@ -58,8 +55,10 @@ def DIR(request) -> DirManager: DIR.RESULTS""" output_dir = request.config.getoption("--output_dir") + assert output_dir, "pytest argument --output_dir not set" output_dir = Path(output_dir) session_id = request.config.getoption("--session_id") + assert session_id, "pytest argument --session_id not set" dirmanager = DirManager(output_dir=output_dir, session_id=session_id) dirmanager.create_all_dirs() return dirmanager @@ -68,6 +67,7 @@ def DIR(request) -> DirManager: @pytest.fixture(scope="session", autouse=True) def dotenv_config(request) -> dict[str, str]: dotenv_path = request.config.getoption("--env_file") + assert dotenv_path, "pytest argument --dotenv_path not set" dotenv_path = Path(dotenv_path) assert dotenv_path.is_file() return dotenv_values(dotenv_path) # type: ignore -- 2.47.2 From aaf758b7069e7fc1b11eb98dda218ad33f325f90 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Dec 2023 01:19:52 +0100 Subject: [PATCH 27/31] pass runner_index instead of env_file_path to runner. add ENV_FILES fixture --- pytest_abra/pytest_abra.py | 42 ++++++++++++++++++++------------------ pytest_abra/runner.py | 6 +++--- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index be7c1e2..668c12d 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -2,6 +2,7 @@ # All fixtures in this file will be available without manual loading. import os +import re from imaplib import IMAP4_SSL from pathlib import Path @@ -11,6 +12,7 @@ from playwright.sync_api import BrowserContext, expect from pytest import Parser from pytest_abra.dir_manager import DirManager +from pytest_abra.env_manager import EnvFile from pytest_abra.utils import BaseUrl # global timeout and LOCALE @@ -30,21 +32,12 @@ def context(context: BrowserContext) -> BrowserContext: def pytest_addoption(parser: Parser): - parser.addoption( - "--env_file", - action="store", - ) - parser.addoption( - "--output_dir", - action="store", - ) - parser.addoption( - "--session_id", - action="store", - ) + parser.addoption("--runner_index", action="store", type=int) + parser.addoption("--output_dir", action="store", type=Path) + parser.addoption("--session_id", action="store", type=str) -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope="session") def DIR(request) -> DirManager: """Fixture holding test directories @@ -56,7 +49,6 @@ def DIR(request) -> DirManager: output_dir = request.config.getoption("--output_dir") assert output_dir, "pytest argument --output_dir not set" - output_dir = Path(output_dir) session_id = request.config.getoption("--session_id") assert session_id, "pytest argument --session_id not set" dirmanager = DirManager(output_dir=output_dir, session_id=session_id) @@ -65,12 +57,22 @@ def DIR(request) -> DirManager: @pytest.fixture(scope="session", autouse=True) -def dotenv_config(request) -> dict[str, str]: - dotenv_path = request.config.getoption("--env_file") - assert dotenv_path, "pytest argument --dotenv_path not set" - dotenv_path = Path(dotenv_path) - assert dotenv_path.is_file() - return dotenv_values(dotenv_path) # type: ignore +def ENV_FILES(DIR: DirManager) -> dict[int, EnvFile]: + out: dict[int, EnvFile] = dict() + for env_path in DIR.ENV_FILES.glob("*.env"): + config: dict[str, str] = dotenv_values(env_path) # type: ignore + env_type = config["TYPE"] + result = re.search(r"(\d+)-*", env_path.name) + assert result + runner_index = int(result[1]) + out[runner_index] = EnvFile(env_path=env_path, config=config, env_type=env_type) + return out + + +@pytest.fixture(scope="session", autouse=True) +def dotenv_config(request, ENV_FILES: dict[int, EnvFile]) -> dict[str, str]: + runner_index = request.config.getoption("--runner_index") + return ENV_FILES[runner_index].config @pytest.fixture(scope="session", autouse=True) diff --git a/pytest_abra/runner.py b/pytest_abra/runner.py index 7486be3..ef3ac06 100644 --- a/pytest_abra/runner.py +++ b/pytest_abra/runner.py @@ -123,8 +123,8 @@ class Runner: # command_arguments.append("-rx") command_arguments.append(str(full_test_path)) - command_arguments.append("--env_file") - command_arguments.append(str(self.dotenv_path)) + command_arguments.append("--runner_index") + command_arguments.append(str(self.runner_index)) # set root dir for tests output (used in DirManager). this is our custom argument command_arguments.append("--output_dir") @@ -146,7 +146,7 @@ class Runner: # command_arguments.append("on") # Disable capturing. With -s set, prints will go to console as if pytest is not there. - # command_arguments.append("-s") + command_arguments.append("-s") # headed # command_arguments.append("--headed") -- 2.47.2 From 9986e46019abf87cb09e1fc4ba66c880ec0c444c Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Dec 2023 01:21:52 +0100 Subject: [PATCH 28/31] remove autouse in plugin fixtures so that plugin usage is optional --- pytest_abra/pytest_abra.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index 668c12d..e8c3641 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -56,7 +56,7 @@ def DIR(request) -> DirManager: return dirmanager -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope="session") def ENV_FILES(DIR: DirManager) -> dict[int, EnvFile]: out: dict[int, EnvFile] = dict() for env_path in DIR.ENV_FILES.glob("*.env"): @@ -69,13 +69,13 @@ def ENV_FILES(DIR: DirManager) -> dict[int, EnvFile]: return out -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope="session") def dotenv_config(request, ENV_FILES: dict[int, EnvFile]) -> dict[str, str]: runner_index = request.config.getoption("--runner_index") return ENV_FILES[runner_index].config -@pytest.fixture(scope="session", autouse=True) +@pytest.fixture(scope="session") def URL(dotenv_config: dict[str, str]) -> BaseUrl: return BaseUrl(netloc=dotenv_config["DOMAIN"]) -- 2.47.2 From a499891fe8257d3232d64b264596cd46d0f08e82 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Dec 2023 01:26:23 +0100 Subject: [PATCH 29/31] add timeout parameter to pytest-abra --- pytest_abra/pytest_abra.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pytest_abra/pytest_abra.py b/pytest_abra/pytest_abra.py index e8c3641..21350af 100644 --- a/pytest_abra/pytest_abra.py +++ b/pytest_abra/pytest_abra.py @@ -15,26 +15,26 @@ from pytest_abra.dir_manager import DirManager from pytest_abra.env_manager import EnvFile from pytest_abra.utils import BaseUrl -# global timeout and LOCALE -LOCALE = {"Accept-Language": "de_DE"} -TIMEOUT = 20_000 -expect.set_options(timeout=TIMEOUT) - - -@pytest.fixture -def context(context: BrowserContext) -> BrowserContext: - # note: because this has the existing context fixture as an argument, it is ensured - # that the original fixture is called first and then overwritten by this custom one. - - context.set_default_timeout(TIMEOUT) - context.set_extra_http_headers(LOCALE) - return context - def pytest_addoption(parser: Parser): parser.addoption("--runner_index", action="store", type=int) parser.addoption("--output_dir", action="store", type=Path) parser.addoption("--session_id", action="store", type=str) + parser.addoption("--timeout", action="store", type=int, default=20_000) + + +@pytest.fixture +def context(context: BrowserContext, request) -> BrowserContext: + # note: because this has the existing context fixture as an argument, it is ensured + # that the original fixture is called first and then overwritten by this custom one. + + TIMEOUT = request.config.getoption("--timeout") + LOCALE = {"Accept-Language": "de_DE"} + + context.set_default_timeout(TIMEOUT) + context.set_extra_http_headers(LOCALE) + expect.set_options(timeout=TIMEOUT) + return context @pytest.fixture(scope="session") -- 2.47.2 From 8a136e5e6c535d945ce13ad93241a835fe1efb7d Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Dec 2023 01:40:35 +0100 Subject: [PATCH 30/31] add timeout parameter to cli and to pytest_abra --- main.py | 2 -- pytest_abra/cli.py | 24 +++++++++++------------- pytest_abra/coordinator.py | 5 ++++- pytest_abra/runner.py | 5 ++++- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/main.py b/main.py index 84017e0..03f61b0 100644 --- a/main.py +++ b/main.py @@ -32,8 +32,6 @@ RECIPES_DIR = Path("../recipes").resolve() OUTPUT_DIR = Path("./test-output").resolve() -# exit() - subprocess.run( [ "pytest-abra", diff --git a/pytest_abra/cli.py b/pytest_abra/cli.py index 5d1d414..2b1dfa7 100644 --- a/pytest_abra/cli.py +++ b/pytest_abra/cli.py @@ -12,22 +12,15 @@ from pytest_abra.utils import get_datetime_string def run(): parser = argparse.ArgumentParser() parser.add_argument("--env_paths", type=str, help="List of loaded env files separated with ;") - parser.add_argument("--recipes_dir", type=str, help="List of loaded env files separated with ;") - parser.add_argument("--output_dir", type=str, help="List of loaded env files separated with ;") - + parser.add_argument("--recipes_dir", type=Path, help="List of loaded env files separated with ;") + parser.add_argument("--output_dir", type=Path, help="List of loaded env files separated with ;") + parser.add_argument("--timeout", type=int, help="Set Playwright timeout in ms", default=20_000) parser.add_argument("--debug", action="store_true", help="Enable Playwright debug mode") - parser.add_argument( - "--resume", action="store_true", help="Re-run the most recent test, only running tests without status 'passed'" - ) + parser.add_argument("--resume", action="store_true", help="Re-run the most recent test, skipping passed tests") args = parser.parse_args() ENV_FILES = [Path(s) for s in args.env_paths.split(";")] - # ----------------------------- define ouptut dir ---------------------------- # - - RECIPES_DIR = Path(args.recipes_dir) - OUTPUT_DIR = Path(args.output_dir) - # -------------------------- enable playwright debug ------------------------- # if args.debug: @@ -43,14 +36,19 @@ def run(): # ------------------------------- setup logging ------------------------------ # - DIR = DirManager(output_dir=OUTPUT_DIR, session_id=session_id) + # todo: move to Coordinator + DIR = DirManager(output_dir=args.output_dir, session_id=session_id) log_file = DIR.RECORDS / "coordinator.log" logger.add(log_file) # ---------------------------- initialize and run ---------------------------- # coordinator = Coordinator( - env_paths_list=ENV_FILES, output_dir=OUTPUT_DIR, session_id=session_id, recipes_dir=RECIPES_DIR + env_paths_list=ENV_FILES, + output_dir=args.output_dir, + session_id=session_id, + recipes_dir=args.recipes_dir, + timeout=args.timeout, ) coordinator.setup_test() coordinator.run_test() diff --git a/pytest_abra/coordinator.py b/pytest_abra/coordinator.py index 8dd6f0f..fb0f422 100644 --- a/pytest_abra/coordinator.py +++ b/pytest_abra/coordinator.py @@ -12,7 +12,9 @@ from pytest_abra.utils import rmtree class Coordinator: - def __init__(self, env_paths_list: list[Path], output_dir: Path, session_id: str, recipes_dir: Path) -> None: + def __init__( + self, env_paths_list: list[Path], output_dir: Path, session_id: str, recipes_dir: Path, timeout: int + ) -> None: # logging out_string = "".join([e.name + "\n" for e in env_paths_list]) out_string += f"output_dir = {output_dir}\n" @@ -22,6 +24,7 @@ class Coordinator: self.RUNNER_DICT = self.create_runner_dict(recipes_dir) self.DIR = DirManager(output_dir=output_dir, session_id=session_id, recipes_dir=recipes_dir) self.ENV = EnvManager(env_paths_list, self.RUNNER_DICT) + self.TIMEOUT = timeout def setup_test(self) -> None: logger.info("calling setup_test()") diff --git a/pytest_abra/runner.py b/pytest_abra/runner.py index ef3ac06..d17b756 100644 --- a/pytest_abra/runner.py +++ b/pytest_abra/runner.py @@ -133,6 +133,9 @@ class Runner: command_arguments.append("--session_id") command_arguments.append(self.DIR.session_id) + command_arguments.append("--timeout") + command_arguments.append(str(self.coordinator.TIMEOUT)) + # artifacts dir from pytest # warning: https://github.com/microsoft/playwright-pytest/issues/111 # --output only works with the given context and page fixture @@ -146,7 +149,7 @@ class Runner: # command_arguments.append("on") # Disable capturing. With -s set, prints will go to console as if pytest is not there. - command_arguments.append("-s") + # command_arguments.append("-s") # headed # command_arguments.append("--headed") -- 2.47.2 From 5b2a929063d02e78f689a3cc2ac8ed015013bae0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 7 Dec 2023 11:31:18 +0100 Subject: [PATCH 31/31] change cli command to "abratest" --- main.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 03f61b0..e7b02a2 100644 --- a/main.py +++ b/main.py @@ -34,7 +34,7 @@ OUTPUT_DIR = Path("./test-output").resolve() subprocess.run( [ - "pytest-abra", + "abratest", "--env_paths", ENV_PATHS, "--recipes_dir", diff --git a/pyproject.toml b/pyproject.toml index 29d8ee9..c951457 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ pytest11 = [ ] [project.scripts] -pytest-abra = "pytest_abra.cli:run" +abratest = "pytest_abra.cli:run" [build-system] requires = ["hatchling"] -- 2.47.2