diff --git a/pytest_abra/coordinator.py b/pytest_abra/coordinator.py index 4d9e2d9..86cecdf 100644 --- a/pytest_abra/coordinator.py +++ b/pytest_abra/coordinator.py @@ -52,7 +52,7 @@ class Coordinator: """Creates an instance of the correct Runner class for each given env file""" runners: list[Runner] = [] for index, env_file in enumerate(env_files): - RunnerClass = self.RUNNER_DICT[env_file.config["TYPE"]] + RunnerClass = self.RUNNER_DICT[env_file.env_config["TYPE"]] runners.append(RunnerClass(coordinator=self, runner_index=index)) return runners diff --git a/pytest_abra/custom_fixtures.py b/pytest_abra/custom_fixtures.py index e791c97..4ddbbd2 100644 --- a/pytest_abra/custom_fixtures.py +++ b/pytest_abra/custom_fixtures.py @@ -8,7 +8,7 @@ from pathlib import Path import pytest from dotenv import dotenv_values -from imbox import Imbox +from imbox import Imbox # type: ignore from playwright.sync_api import BrowserContext, expect from pytest import Parser @@ -73,7 +73,7 @@ def env_files(DIR: DirManager) -> list[EnvFile]: result = re.search(r"(\d+)-*", env_path.name) assert result runner_index = int(result[1]) - env_files_dict[runner_index] = EnvFile(env_path=env_path, config=config, env_type=env_type) + env_files_dict[runner_index] = EnvFile(env_path=env_path, env_config=config, env_type=env_type) keys = list(env_files_dict.keys()) keys.sort() return [env_files_dict[key] for key in keys] @@ -83,7 +83,7 @@ def env_files(DIR: DirManager) -> list[EnvFile]: def env_config(request, env_files: list[EnvFile]) -> dict[str, str]: """Current env_config""" runner_index = request.config.getoption("--runner_index") - return env_files[runner_index].config + return env_files[runner_index].env_config @pytest.fixture(scope="session") diff --git a/pytest_abra/env_manager.py b/pytest_abra/env_manager.py index 1fb2e37..f9d79cd 100644 --- a/pytest_abra/env_manager.py +++ b/pytest_abra/env_manager.py @@ -1,16 +1,17 @@ import shutil from pathlib import Path -from typing import NamedTuple +from typing import TYPE_CHECKING, NamedTuple from dotenv import dotenv_values -from pytest_abra.dir_manager import DirManager -from pytest_abra.runner import Runner +if TYPE_CHECKING: + from pytest_abra.dir_manager import DirManager + from pytest_abra.runner import Runner class EnvFile(NamedTuple): env_path: Path - config: dict[str, str] + env_config: dict[str, str] env_type: str def __repr__(self) -> str: @@ -37,7 +38,7 @@ class EnvManager: config: dict[str, str] = dotenv_values(env_path) # type: ignore assert "TYPE" in config, f"the env file {env_path} does not specify the required TYPE key." env_type = config["TYPE"] - env_files.append(EnvFile(env_path=env_path, config=config, env_type=env_type)) + env_files.append(EnvFile(env_path=env_path, env_config=config, env_type=env_type)) return env_files @staticmethod @@ -92,7 +93,7 @@ class EnvManager: "Could not resolve test order. This is possibly due to a circular dependency (a on b, b on c, c on a)" ) - def copy_env_files(self, DIR: DirManager) -> None: + def copy_env_files(self, DIR: "DirManager") -> None: """Copies all env files to STATES/env_files. Files will be renamed to -- 00-authentik-login.test.dev.local-it.cloud.env""" diff --git a/pytest_abra/runner.py b/pytest_abra/runner.py index d17b756..1a75d27 100644 --- a/pytest_abra/runner.py +++ b/pytest_abra/runner.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from pathlib import Path -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING, Callable, NamedTuple import pytest from loguru import logger @@ -10,10 +10,16 @@ if TYPE_CHECKING: from pytest_abra.env_manager import EnvFile +class ConditionArgs(NamedTuple): + env_config: dict[str, str] + runner_index: int + env_files: list["EnvFile"] + + @dataclass class Test: test_file: str - condition: Callable[[dict[str, str]], bool] | None = None + condition: Callable[[ConditionArgs], bool] | None = None prevent_skip: bool = False @@ -25,17 +31,13 @@ class Runner: dependencies: list[str] = [] def __init__(self, coordinator: "Coordinator", runner_index: int): - self.coordinator = coordinator # needed? - self.runner_index = runner_index # needed? + self.coordinator = coordinator + self.runner_index = runner_index self.DIR = coordinator.DIR self.ENV = coordinator.ENV self.RUNNER_DICT = coordinator.RUNNER_DICT - self.env_file: EnvFile = self.ENV.env_files[self.runner_index] - self.dotenv_path = self.env_file.env_path - self.config = self.env_file.config - logger.info(f"creating instance of {self.__class__.__name__}") def run_setups(self): @@ -81,16 +83,28 @@ class Runner: logger.info(f"skipping {identifier_string}, test has passed") return - if test.condition and not test.condition(self.config): - # test condition is defined but not met - logger.info(f"skipping {identifier_string}, test condition is not met") - return + if test.condition: + condition_result = self._run_condition(test.condition) + if not condition_result: + # test condition is defined but not met + logger.info(f"skipping {identifier_string}, test condition is not met") + return # test condition is undefined or not met logger.info(f"running {identifier_string}") result = self._call_pytest(full_test_path) self._create_result_file(result=result, identifier_string=identifier_string) + def _run_condition(self, condition_function: Callable[[ConditionArgs], bool]): + """run the test condition function with multiple arguments""" + # more arguments can be added later without changing the function signature + conditon_args = ConditionArgs( + env_files=self.ENV.env_files, + runner_index=self.runner_index, + env_config=self.ENV.env_files[self.runner_index].env_config, + ) + return condition_function(conditon_args) + def _is_test_passed(self, identifier_string: str, remove_existing: bool = False) -> bool: """returns True if the selected test matching identifier_string already passed diff --git a/tests/test_env_resolution.py b/tests/test_env_resolution.py index 4b11941..ddb5fc4 100644 --- a/tests/test_env_resolution.py +++ b/tests/test_env_resolution.py @@ -20,7 +20,7 @@ def test_complex_sorting() -> None: ] demo_types = ["a", "b", "c", "d", "e", "f", "g"] - env_files = [EnvFile(env_type=t, env_path=Path(), config=dict()) for t in demo_types] + env_files = [EnvFile(env_type=t, env_path=Path(), env_config=dict()) for t in demo_types] EnvManager.sort_env_files_by_rule sorted_env_files = EnvManager.sort_env_files_by_rule(env_files, demo_rules) @@ -36,7 +36,7 @@ def test_circular_import() -> None: ] demo_types = ["a", "b", "c"] - env_files = [EnvFile(env_type=t, env_path=Path(), config=dict()) for t in demo_types] + env_files = [EnvFile(env_type=t, env_path=Path(), env_config=dict()) for t in demo_types] with pytest.raises(ValueError): EnvManager.sort_env_files_by_rule(env_files, demo_rules)