From 2e33f8f014e99e45ed4f366caa3f521f2610193c Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 30 Nov 2023 10:53:20 +0100 Subject: [PATCH] make-all-env-files-available (#4) Before, a test had only access to it's own env file / configuration (wordpress could see wordpress env file). Now, all env files are available. Wordpress test can also read authentik env file, for example to get the authentik domain. Reviewed-on: https://git.local-it.org/local-it-infrastructure/e2e_tests/pulls/4 Co-authored-by: Daniel Co-committed-by: Daniel --- src/dirmanager.py | 18 +++++-- src/runner.py | 61 ++++++++++++----------- src/tests_authentik/fixtures_authentik.py | 14 +++++- src/tests_wordpress/conftest.py | 2 +- src/tests_wordpress/test_wordpress.py | 17 +++---- 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/dirmanager.py b/src/dirmanager.py index 41dcfaa..c210d25 100644 --- a/src/dirmanager.py +++ b/src/dirmanager.py @@ -25,7 +25,9 @@ class DirManager: def create_all_dirs(self): self.create_dirs(self._output_dir, exist_ok=True) - self.create_dirs([self.SESSION, self.RECORDS, self.RECORDS / "html", self.STATES, self.RESULTS], exist_ok=True) + self.create_dirs( + [self.SESSION, self.RECORDS, self.HTML, self.STATES, self.ENV_FILES, self.RESULTS], exist_ok=True + ) @property def OUTPUT(self): @@ -37,15 +39,23 @@ class DirManager: @property def RECORDS(self): - return self.SESSION / Path("records") + return self.SESSION / "records" + + @property + def HTML(self): + return self.RECORDS / "html" @property def STATES(self): - return self.SESSION / Path("states") + return self.SESSION / "states" + + @property + def ENV_FILES(self): + return self.STATES / "env_files" @property def RESULTS(self): - return self.SESSION / Path("results") + return self.SESSION / "results" @staticmethod def create_dirs(dirs: Path | list[Path] | dict[str, Path], exist_ok=False): diff --git a/src/runner.py b/src/runner.py index d232334..7d0011a 100644 --- a/src/runner.py +++ b/src/runner.py @@ -33,28 +33,44 @@ class Runner: assert self.test_dir_name self.root_dir = Path(__file__).parent - def _run_main_setup_and_test(self): + def run_tests(self): + # check if required dependencies have passed + self._assert_dependencies_passed() + + # run main setup if available if isinstance(self.main_setup_name, str): - self._run_test_if_required( + self._run_or_skip_test( identifier_string=self.combine_names(self.name, self.main_setup_name), test_path=self.root_dir / self.test_dir_name / self.main_setup_name, ) + # run main test if available if isinstance(self.main_test_name, str): - self._run_test_if_required( + self._run_or_skip_test( identifier_string=self.combine_names(self.name, self.main_test_name), test_path=self.root_dir / self.test_dir_name / self.main_test_name, ) - def _run_test_if_required(self, identifier_string: str, test_path: Path): - if not self.prevent_skip and self._test_already_passed(identifier_string, remove_existing=True): + # run sub tests if conditions are met + for sub_test in self.sub_tests: + condition_function = sub_test["condition"] + sub_test_name = sub_test["test_file"] + identifier_string = self.combine_names(self.name, sub_test_name) + if condition_function(self.config): + test_path = self.root_dir / self.test_dir_name / sub_test_name + self._run_or_skip_test(identifier_string=identifier_string, test_path=test_path) + else: + self._create_result_file(result=-1, identifier_string=identifier_string) + + def _run_or_skip_test(self, identifier_string: str, test_path: Path): + if not self.prevent_skip and self._is_test_passed(identifier_string, remove_existing=True): logger.info(f"skipping {identifier_string}") else: logger.info(f"running {identifier_string}") result = self._call_pytest(test_path) self._create_result_file(result=result, identifier_string=identifier_string) - def _test_already_passed(self, identifier_string: str, remove_existing: bool = False) -> bool: + def _is_test_passed(self, identifier_string: str, remove_existing: bool = False) -> bool: """returns True if the selected test (matching test_name + sub_test_name) already passed This is determined by the presence of a specific output file in the RESULTS folder that @@ -116,19 +132,6 @@ class Runner: return pytest.main(command_arguments) - def run_tests(self): - self._assert_dependencies_passed() - self._run_main_setup_and_test() - for sub_test in self.sub_tests: - condition_function = sub_test["condition"] - sub_test_name = sub_test["test_file"] - identifier_string = self.combine_names(self.name, sub_test_name) - if condition_function(self.config): - test_path = self.root_dir / self.test_dir_name / sub_test_name - self._run_test_if_required(identifier_string=identifier_string, test_path=test_path) - else: - self._create_result_file(result=-1, identifier_string=identifier_string) - def _create_result_file( self, result: int, @@ -141,6 +144,16 @@ class Runner: with open(file_path, "w") as _: pass # create empty file + def _assert_dependencies_passed(self): + """assert that all dependencie setups passed before""" + + passed_tests = [r.name for r in self.DIRS.RESULTS.glob("*") if "passed" in r.name] + for dependencie in self.dependencies: + dependencie_identifier = self.combine_names(dependencie.name, dependencie.main_setup_name) + assert any( + dependencie_identifier in f for f in passed_tests + ), f"could not run {self.name} because {dependencie} did not run before" + @staticmethod def result_int_to_str(result_int: int) -> str: match result_int: @@ -154,13 +167,3 @@ class Runner: @staticmethod def combine_names(*names: str) -> str: return "-".join(names) - - def _assert_dependencies_passed(self): - """assert that all dependencie setups passed before""" - - passed_tests = [r.name for r in self.DIRS.RESULTS.glob("*") if "passed" in r.name] - for dependencie in self.dependencies: - dependencie_identifier = self.combine_names(dependencie.name, dependencie.main_setup_name) - assert any( - dependencie_identifier in f for f in passed_tests - ), f"could not run {self.name} because {dependencie} did not run before" diff --git a/src/tests_authentik/fixtures_authentik.py b/src/tests_authentik/fixtures_authentik.py index dab4e42..21bddbe 100644 --- a/src/tests_authentik/fixtures_authentik.py +++ b/src/tests_authentik/fixtures_authentik.py @@ -1,7 +1,8 @@ import json import pytest -from playwright.sync_api import BrowserContext +from dotenv import dotenv_values +from playwright.sync_api import BrowserContext, Page from src.dirmanager import DirManager @@ -17,6 +18,17 @@ def admin_context(context: BrowserContext, DIR: DirManager) -> BrowserContext: return context +@pytest.fixture +def authentik_admin_page(admin_context: BrowserContext, DIR: DirManager) -> Page: + page = admin_context.new_page() + page.pause() + authentik_env_file = DIR.ENV_FILES / "authentik" + authentik_config: dict[str, str] = dotenv_values(authentik_env_file) # type: ignore + url = "https://" + authentik_config["DOMAIN"] + page.goto(url) + return page + + @pytest.fixture def user_context(context: BrowserContext, DIR: DirManager) -> BrowserContext: state_file = DIR.STATES / "user_state.json" diff --git a/src/tests_wordpress/conftest.py b/src/tests_wordpress/conftest.py index c7a791d..df1eac3 100644 --- a/src/tests_wordpress/conftest.py +++ b/src/tests_wordpress/conftest.py @@ -1 +1 @@ -from src.tests_authentik.fixtures_authentik import admin_context, user_context +from src.tests_authentik.fixtures_authentik import admin_context, authentik_admin_page, user_context diff --git a/src/tests_wordpress/test_wordpress.py b/src/tests_wordpress/test_wordpress.py index 6c85114..bb9275d 100644 --- a/src/tests_wordpress/test_wordpress.py +++ b/src/tests_wordpress/test_wordpress.py @@ -1,14 +1,13 @@ -import re - -from playwright.sync_api import BrowserContext, expect - -from src.dirmanager import DirManager +from playwright.sync_api import Page, expect -def test_visit_from_authentik(admin_context: BrowserContext, dotenv_config: dict[str, str], DIR: DirManager): - page_authentik = admin_context.new_page() - with page_authentik.expect_popup() as event_context: - page_authentik.get_by_role("link", name="Wordpress").click() +def test_visit_from_authentik(authentik_admin_page: Page): + with authentik_admin_page.expect_popup() as event_context: + authentik_admin_page.get_by_role("link", name="Wordpress").click() page_wordpress = event_context.value + # look for content wrapper expect(page_wordpress.locator("#wpcontent")).to_be_visible() + + # look for admin bar + expect(page_wordpress.locator("#wpadminbar")).to_be_visible()