je_web_runner.api.quality

Façade: a11y diff / a11y trend / perf budgets / perf drift / trend / cluster.

class je_web_runner.api.quality.A11yDiff(added: 'List[Dict[str, Any]]'=<factory>, resolved: 'List[Dict[str, Any]]'=<factory>, persisting: 'List[Dict[str, Any]]'=<factory>)

Bases: object

added: List[Dict[str, Any]]
persisting: List[Dict[str, Any]]
property regressed: bool
resolved: List[Dict[str, Any]]
property total_baseline: int
property total_current: int
exception je_web_runner.api.quality.A11yDiffError

Bases: WebRunnerException

Raised when input shape is invalid.

exception je_web_runner.api.quality.A11yTrendError

Bases: WebRunnerException

Raised when the history JSON has the wrong shape.

class je_web_runner.api.quality.A11yTrendPoint(label: 'str', impacts: 'Dict[str, int]'=<factory>)

Bases: object

impacts: Dict[str, int]
label: str
property total: int
class je_web_runner.api.quality.BudgetCheckResult(route: 'str', matched_rule: 'Optional[RouteBudget]', breaches: 'List[Dict[str, Any]]'=<factory>)

Bases: object

breaches: List[Dict[str, Any]]
matched_rule: RouteBudget | None
property passed: bool
route: str
class je_web_runner.api.quality.DriftReport(metrics: 'List[_MetricResult]' = <factory>)

Bases: object

property has_regressions: bool
metrics: List[_MetricResult]
property regressions: List[_MetricResult]
class je_web_runner.api.quality.FailureCluster(signature: str, representative: str, count: int = 0, members: Dict[str, ~typing.Any]]=<factory>, files: List[str] = <factory>)

Bases: object

One bucket of failures sharing a normalised signature.

count: int = 0
files: List[str]
members: List[Dict[str, Any]]
representative: str
signature: str
exception je_web_runner.api.quality.FailureClusterError

Bases: WebRunnerException

Raised when the failures iterable has the wrong shape.

exception je_web_runner.api.quality.PerfBudgetError

Bases: WebRunnerException

Raised when budget config is invalid or assertions fail.

exception je_web_runner.api.quality.PerfDriftError

Bases: WebRunnerException

Raised on bad input shape or impossible windowing.

class je_web_runner.api.quality.RouteBudget(path: str | None = None, path_glob: str | None = None, metrics: Dict[str, float]=<factory>)

Bases: object

Single budget entry.

matches(route_path: str) bool
metrics: Dict[str, float]
path: str | None = None
path_glob: str | None = None
exception je_web_runner.api.quality.TrendDashboardError

Bases: WebRunnerException

Raised when the ledger is missing or has an unexpected shape.

je_web_runner.api.quality.aggregate_history(history: Iterable[Dict[str, Any]]) List[A11yTrendPoint]

[{timestamp, violations:[{impact,...}]}, …] 按天彙總每個 impact 的計數。 Bucket history entries by day and count each violation’s impact (critical / serious / moderate / minor / unknown).

je_web_runner.api.quality.assert_no_regressions(diff: A11yDiff, allow_rules: Sequence[str] | None = None) None

Raise if diff.added is non-empty (after applying allow_rules).

je_web_runner.api.quality.assert_within_budget(result: BudgetCheckResult) None
je_web_runner.api.quality.cluster_failures(failures: Iterable[Dict[str, Any]], top_n: int | None = None) List[FailureCluster]

[{function_name, exception, file_path?}, …] 分群並依 count 排序。 Group failures by normalised signature; clusters are sorted by count descending. top_n truncates the result to the largest buckets.

je_web_runner.api.quality.compute_drift(samples: Sequence[float], *, baseline_window: int, recent_window: int, tolerance: float = 0.1, higher_is_better: bool = False, pct: float = 95.0, metric: str = 'metric') _MetricResult

Compare recent P95 to a baseline P95.

The baseline window covers the runs immediately preceding the recent window: samples = […baseline_window…, …recent_window…].

je_web_runner.api.quality.compute_trend(ledger_path: str) Dict[str, Any]

依日期分桶,回傳 {daily: [...], totals: {...}} Bucket the ledger by day and return per-day pass / fail / duration.

je_web_runner.api.quality.detect_drift(metrics: Dict[str, Sequence[float]], *, baseline_window: int = 20, recent_window: int = 5, tolerance: float = 0.1, higher_is_better: Iterable[str] | None = None, pct: float = 95.0) DriftReport

Run compute_drift() for every metric in metrics and aggregate.

je_web_runner.api.quality.diff_violations(baseline: Sequence[Any], current: Sequence[Any]) A11yDiff

Diff two axe-core violations arrays.

je_web_runner.api.quality.evaluate_metrics(route_path: str, metrics: Dict[str, float], budgets: Sequence[RouteBudget]) BudgetCheckResult

Find the first matching rule and check every configured metric.

je_web_runner.api.quality.load_budgets(source: str | Path | list) List[RouteBudget]

Load budgets from a path, JSON string, or in-memory list.

je_web_runner.api.quality.normalise_error(message: str) str

把錯誤訊息做積極正規化,方便後續分群比較。 Strip timestamps, hex addresses, file paths, line numbers, large numerics, and quoted substrings. Returns a lower-cased canonical form.

je_web_runner.api.quality.percentile(values: Sequence[float], pct: float) float

Return the inclusive percentile of values.

je_web_runner.api.quality.render_a11y_trend_html(points: List[A11yTrendPoint], title: str = 'A11y trend') str

Render a self-contained HTML page with table + SVG line chart.

je_web_runner.api.quality.render_run_trend_html(trend: Dict[str, Any], title: str = 'WebRunner trend') str

Render a self-contained HTML dashboard from compute_trend().