diff --git a/tests/e2e/models.py b/tests/e2e/models.py new file mode 100644 index 0000000..e9f003e --- /dev/null +++ b/tests/e2e/models.py @@ -0,0 +1,41 @@ +"""Shared data models for the Peregrine E2E test harness.""" +from __future__ import annotations +import fnmatch +from dataclasses import dataclass +from pathlib import Path +from typing import Callable, Any + + +@dataclass(frozen=True) +class ErrorRecord: + type: str # "exception" | "alert" + message: str + element_html: str + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ErrorRecord): + return NotImplemented + return (self.type, self.message) == (other.type, other.message) + + def __hash__(self) -> int: + return hash((self.type, self.message)) + + +def diff_errors(before: list[ErrorRecord], after: list[ErrorRecord]) -> list[ErrorRecord]: + """Return errors in `after` that were not present in `before`.""" + before_set = set(before) + return [e for e in after if e not in before_set] + + +@dataclass +class ModeConfig: + name: str + base_url: str + auth_setup: Callable[[Any], None] + expected_failures: list[str] # fnmatch glob patterns against element labels + results_dir: Path | None + settings_tabs: list[str] # tabs expected per mode + + def matches_expected_failure(self, label: str) -> bool: + """Return True if label matches any expected_failure pattern (fnmatch).""" + return any(fnmatch.fnmatch(label, pattern) for pattern in self.expected_failures) diff --git a/tests/test_e2e_helpers.py b/tests/test_e2e_helpers.py new file mode 100644 index 0000000..e07706d --- /dev/null +++ b/tests/test_e2e_helpers.py @@ -0,0 +1,64 @@ +"""Unit tests for E2E harness models and helper utilities.""" +import fnmatch +import pytest +from unittest.mock import patch, MagicMock +import time +from tests.e2e.models import ErrorRecord, ModeConfig, diff_errors + + +def test_error_record_equality(): + a = ErrorRecord(type="exception", message="boom", element_html="