e2e_tests/pytest_abra/pytest_abra.py

133 lines
4 KiB
Python

# 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
import re
from datetime import datetime, timedelta
from pathlib import Path
import pytest
from dotenv import dotenv_values
from imbox import Imbox
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
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(autouse=True)
def set_expect_timeout(request):
TIMEOUT = request.config.getoption("--timeout")
expect.set_options(timeout=TIMEOUT)
@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)
return context
@pytest.fixture(scope="session")
def DIR(request) -> DirManager:
"""Fixture holding test directories
DIR.OUTPUT
DIR.SESSION
DIR.RECORDS
DIR.STATES
DIR.RESULTS"""
output_dir = request.config.getoption("--output_dir")
assert output_dir, "pytest argument --output_dir not set"
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
@pytest.fixture(scope="session")
def ENV_FILES(DIR: DirManager) -> dict[int, EnvFile]:
"""Dictionary of all EnvFile instances of the current test run
key: runner_index
value: EnvFile of the related env file
"""
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")
def env_config(request, ENV_FILES: dict[int, EnvFile]) -> dict[str, str]:
"""Current env_config"""
runner_index = request.config.getoption("--runner_index")
return ENV_FILES[runner_index].config
@pytest.fixture(scope="session")
def URL(env_config: dict[str, str]) -> BaseUrl:
"""BaseUrl object based on current DOMAIN"""
return BaseUrl(netloc=env_config["DOMAIN"])
@pytest.fixture(scope="session")
def imap_client() -> None:
"""imap email client using credentials from environment variables"""
assert os.environ["IMAP_HOST"]
assert os.environ["IMAP_PORT"]
assert os.environ["IMAP_USER"]
assert os.environ["IMAP_PASS"]
imbox = Imbox(
hostname=os.environ["IMAP_HOST"],
port=os.environ["IMAP_PORT"],
username=os.environ["IMAP_USER"],
password=os.environ["IMAP_PASS"],
ssl=True,
ssl_context=None,
starttls=False,
)
yield imbox
imbox.logout()
@pytest.fixture
def imap_recent_messages(imap_client: Imbox, n_minutes: int):
"""Get all messages from [n_minutes] ago till now.
# iterate with
for uid, message in messages:
print(uid, message.subject, message.date)"""
n_minutes_ago = datetime.now() - timedelta(minutes=n_minutes)
uids_and_messages = imap_client.messages(date__gt=n_minutes_ago)
uids, messages = zip(*uids_and_messages)
print(type(messages))
return messages