from pathlib import Path from typing import Callable, Optional, TypedDict import pytest from dotenv import dotenv_values from icecream import ic from src.dirmanager import DirManager class SubTest(TypedDict): condition: Callable[[Path], bool] test_file: str class Runner: name: Optional[str] = None test_dir_name: Optional[str] = None main_setup_name: Optional[str] = None main_test_name: Optional[str] = None sub_tests: list[SubTest] = [] dependencies: list[str] = [] def __init__(self, dotenv_path: Path, output_dir: Path, session_id: str): self.dotenv_path = dotenv_path self.config: dict[str, str] = dotenv_values(dotenv_path) # type: ignore self.output_dir = output_dir self.session_id = session_id self.dir_manager = DirManager(output_dir, session_id) ic(f"creating instance of {self.__class__.__name__}") assert self.test_dir_name is not None self.root_dir = Path(__file__).parent def _run_main_test(self): if isinstance(self.main_setup_name, str): full_path = self.root_dir / self.test_dir_name / self.main_setup_name self._run_pytest(full_path) if isinstance(self.main_test_name, str): full_path = self.root_dir / self.test_dir_name / self.main_test_name self._run_pytest(full_path) def _run_pytest(self, full_test_path: Path): """runs pytest programmatically will run all tests in the file at full_test_path with some command line arguments""" ic(f"running test: {full_test_path}") command_arguments = [] # command_arguments.append("-v") # 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("--output_dir") command_arguments.append(str(self.output_dir)) command_arguments.append("--session_id") command_arguments.append(self.session_id) # artifacts dir output = self.dir_manager.RESULTS / full_test_path.stem command_arguments.append("--output") command_arguments.append(str(output)) # tracing command_arguments.append("--tracing") # command_arguments.append("retain-on-failure") command_arguments.append("on") # warning: https://github.com/microsoft/playwright-pytest/issues/111 # --output only works with the given context and page fixture # Disable capturing. With -s set, prints will go to console as if pytest is not there. # command_arguments.append("-s") # headed # command_arguments.append("--headed") pytest.main(command_arguments) def run_tests(self): self._check_dependencies() self._run_main_test() for sub_test in self.sub_tests: condition_function = sub_test["condition"] if condition_function(self.dotenv_path): test_name = sub_test["test_file"] full_test_path = self.root_dir / self.test_dir_name / test_name self._run_pytest(full_test_path) self._create_complete_file() def _create_complete_file(self): file_path = self.dir_manager.RESULTS / self.name with open(file_path, "w") as _: pass # pass does nothing, so the file remains empty def _check_dependencies(self): for dependencie in self.dependencies: ic(f"checking {dependencie}") assert dependencie in self.dir_manager.RESULTS.glob("*")