feat(e2e): add ErrorRecord, ModeConfig, diff_errors models with tests
This commit is contained in:
parent
0317b9582a
commit
4d58d33567
2 changed files with 105 additions and 0 deletions
41
tests/e2e/models.py
Normal file
41
tests/e2e/models.py
Normal file
|
|
@ -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)
|
||||||
64
tests/test_e2e_helpers.py
Normal file
64
tests/test_e2e_helpers.py
Normal file
|
|
@ -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="<div>boom</div>")
|
||||||
|
b = ErrorRecord(type="exception", message="boom", element_html="<div>boom</div>")
|
||||||
|
assert a == b
|
||||||
|
|
||||||
|
|
||||||
|
def test_error_record_inequality():
|
||||||
|
a = ErrorRecord(type="exception", message="boom", element_html="")
|
||||||
|
b = ErrorRecord(type="alert", message="boom", element_html="")
|
||||||
|
assert a != b
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_errors_returns_new_only():
|
||||||
|
before = [ErrorRecord("exception", "old error", "")]
|
||||||
|
after = [
|
||||||
|
ErrorRecord("exception", "old error", ""),
|
||||||
|
ErrorRecord("alert", "new error", ""),
|
||||||
|
]
|
||||||
|
result = diff_errors(before, after)
|
||||||
|
assert result == [ErrorRecord("alert", "new error", "")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_errors_empty_when_no_change():
|
||||||
|
errors = [ErrorRecord("exception", "x", "")]
|
||||||
|
assert diff_errors(errors, errors) == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_errors_empty_before():
|
||||||
|
after = [ErrorRecord("alert", "boom", "")]
|
||||||
|
assert diff_errors([], after) == after
|
||||||
|
|
||||||
|
|
||||||
|
def test_mode_config_expected_failure_match():
|
||||||
|
config = ModeConfig(
|
||||||
|
name="demo",
|
||||||
|
base_url="http://localhost:8504",
|
||||||
|
auth_setup=lambda ctx: None,
|
||||||
|
expected_failures=["Fetch*", "Generate Cover Letter"],
|
||||||
|
results_dir=None,
|
||||||
|
settings_tabs=["👤 My Profile"],
|
||||||
|
)
|
||||||
|
assert config.matches_expected_failure("Fetch New Jobs")
|
||||||
|
assert config.matches_expected_failure("Generate Cover Letter")
|
||||||
|
assert not config.matches_expected_failure("View Jobs")
|
||||||
|
|
||||||
|
|
||||||
|
def test_mode_config_no_expected_failures():
|
||||||
|
config = ModeConfig(
|
||||||
|
name="local",
|
||||||
|
base_url="http://localhost:8502",
|
||||||
|
auth_setup=lambda ctx: None,
|
||||||
|
expected_failures=[],
|
||||||
|
results_dir=None,
|
||||||
|
settings_tabs=[],
|
||||||
|
)
|
||||||
|
assert not config.matches_expected_failure("Fetch New Jobs")
|
||||||
Loading…
Reference in a new issue