');
return `
-
Loading Differential Testing
+
Loading ${escapeHtml(ovenName)}
${template}
`;
}
@@ -78,15 +78,18 @@ export function differentialProgressChartHistory(payload, { mode = "value" } = {
export function differentialExactPrefixFrameDeltaMetrics(payload, metrics) {
const ratios = metrics?.frameDeviationRatios;
+ const residuals = metrics?.frameSignedResiduals;
const latest = Array.isArray(payload?.progress) ? payload.progress.at(-1) : null;
const clearedFrame = Number(latest?.frame);
const frameCount = Number(latest?.frames);
- if (!Array.isArray(ratios) || !Number.isSafeInteger(clearedFrame) || !Number.isSafeInteger(frameCount)
- || frameCount !== ratios.length || clearedFrame < 0 || clearedFrame > frameCount
- || ratios.some((value) => !Number.isFinite(Number(value)) || Number(value) < 0)) return null;
+ if (!Array.isArray(ratios) || !Array.isArray(residuals) || !Number.isSafeInteger(clearedFrame) || !Number.isSafeInteger(frameCount)
+ || frameCount !== ratios.length || frameCount !== residuals.length || clearedFrame < 0 || clearedFrame > frameCount
+ || ratios.some((value) => !Number.isFinite(Number(value)) || Number(value) < 0)
+ || residuals.some((value) => !Number.isFinite(Number(value)))) return null;
return {
...metrics,
frameDeviationRatios: ratios.map((value, frame) => frame < clearedFrame ? 0 : Number(value)),
+ frameSignedResiduals: residuals.map((value, frame) => frame < clearedFrame ? 0 : Number(value)),
firstFailingFrame: clearedFrame < frameCount ? clearedFrame : -1,
};
}
@@ -157,6 +160,9 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
onFieldViewChange = () => {},
fieldPage = null,
frameDeltaMetrics = null,
+ detailCellId = "field-details",
+ detailRenderer = null,
+ initialProgressChart = "delta",
templateOnly = false,
} = {}) {
if (templateOnly) return templateHtml();
@@ -166,8 +172,8 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
const RED = "#ef4444";
const telemetryAvailability = differentialTelemetryAvailability(payload);
const state = {
- chart: "delta",
- progressChart: "delta",
+ chart: "current",
+ progressChart: initialProgressChart,
sort: fieldPage?.sort ?? (telemetryAvailability.status === "comparable" ? "changed" : "default"),
filter: fieldPage?.filter ?? "all",
search: fieldPage?.search ?? "",
@@ -383,12 +389,17 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
const marker = stateClass === "improved" ? "▲" : stateClass === "worsened" ? "▼" : "⦁";
const deltaText = deltaPercent === null ? "—" : percent(deltaPercent);
const resultText = frameDelta === null ? "—" : count(Math.abs(frameDelta));
- const result = marker !== "⦁"
- ? `
${marker}${resultText}`
- : resultText;
+ const result = frameDelta === null
+ ? "—"
+ : marker === "⦁"
+ ? resultText
+ : `
${marker}${resultText}`;
const frame = !Number.isSafeInteger(Number(entry.frame)) ? "—" : count(entry.frame);
+ const tick = entry.firstFailingTick == null || !Number.isSafeInteger(Number(entry.firstFailingTick))
+ ? "—"
+ : String(Number(entry.firstFailingTick));
const done = !Number.isSafeInteger(Number(entry.frame)) || !Number(entry.frames) ? "—" : `${Math.round(Math.max(0, Math.min(1, Number(entry.frame) / Number(entry.frames))) * 100)}%`;
- return `
${escapeHtml(formatLogRelativeMinutes(entry.timestamp, now))}${frame}${result}${deltaText}${done}`;
+ return `
${escapeHtml(formatLogRelativeMinutes(entry.timestamp, now))}${frame}×${tick}${result}${deltaText}${done}`;
}).join("");
const placeholders = Array.from(
{ length: Math.max(0, 8 - visibleEntries.length) },
@@ -564,7 +575,7 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
? "No changed fields in this telemetry."
: state.telemetryAvailability.reason
: "No fields match the current view.";
- return `
${escapeHtml(message)}
`;
+ return `
${escapeHtml(message)}
`;
}
return `
${fields.map((field, index) => {
const expanded = state.expanded.has(field.id);
@@ -755,9 +766,9 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
|
-
+
·
-
+
|
@@ -1499,6 +1510,12 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
border-radius: 1px;
color: var(--muted);
}
+ .hybrid-empty {
+ border: 0;
+ border-radius: 8px;
+ background: var(--card);
+ color: rgba(168,168,168,.76);
+ }
@@ -1579,7 +1596,7 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
existingHeaderStatus?.remove();
if (!state.oven || !state.payload) return;
const cells = new Map(state.oven.detail.cells.map((cell) => [cell.id, cell]));
- const title = cells.get("title"), burns = cells.get("burns"), fields = cells.get("fields"), frames = cells.get("frames"), progressCell = cells.get("progress"), logCell = cells.get("log"), details = cells.get("field-details");
+ const title = cells.get("title"), burns = cells.get("burns"), fields = cells.get("fields"), frames = cells.get("frames"), progressCell = cells.get("progress"), logCell = cells.get("log"), details = cells.get(detailCellId);
if (![title, burns, fields, frames, progressCell, logCell, details].every(Boolean)) { root.innerHTML = '
Differential Testing Oven layout is incomplete.
'; return; }
const titleText = String(title.title || state.oven.name || "Differential Testing");
if (state.payload.scenarioCatalog?.selectedScenarioId === null && state.payload.scenarioCatalog?.scenarios?.length === 0) {
@@ -1611,7 +1628,7 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
const scenarioKpi = kpiItem({
className: "driving-parity-kpi-scenario",
title: subtitleParts.join(" · "),
- visual: '
',
+ visual: '
',
heading: "Scenario",
headingClass: "differential-scenario-heading",
value: scenarioSelector(),
@@ -1629,8 +1646,8 @@ export function mountDifferentialTestingDashboard(root, oven, payload, {
.replace('
', '')
.replace('', `Fields List(${count(state.payload.summary?.fields?.total ?? state.payload.fields.length)})
`)
.replace('', '
')
- .replace('data-driving-parity-chart="current" aria-label="Value chart view" title="Value chart view" aria-pressed="false"', `data-driving-parity-chart="current" aria-label="Value chart view" title="Value chart view" aria-pressed="${state.chart === "current"}"`)
- .replace('data-driving-parity-chart="delta" aria-label="Delta chart view" title="Delta chart view" aria-pressed="true"', `data-driving-parity-chart="delta" aria-label="Delta chart view" title="Delta chart view" aria-pressed="${state.chart === "delta"}"`)
+ .replace('data-driving-parity-chart="current" aria-label="Value chart view" title="Value chart view" aria-pressed="true"', `data-driving-parity-chart="current" aria-label="Value chart view" title="Value chart view" aria-pressed="${state.chart === "current"}"`)
+ .replace('data-driving-parity-chart="delta" aria-label="Delta chart view" title="Delta chart view" aria-pressed="false"', `data-driving-parity-chart="delta" aria-label="Delta chart view" title="Delta chart view" aria-pressed="${state.chart === "delta"}"`)
.replace('
', `
`)
.replace('
', `
`)
.replace('