Advance AXIS-style Three.js simulation UI
This commit is contained in:
@@ -120,6 +120,53 @@ function normalizeObservedOutput(value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
function normalizeAxisScreenshotArtifacts(value) {
|
||||
return arrayOrEmpty(value)
|
||||
.map((artifact) => objectOrEmpty(artifact))
|
||||
.filter(({ apiName }) => apiName === "real-browser-simulation-axis-screenshot-artifact")
|
||||
.map((artifact) => ({
|
||||
apiName: artifact.apiName,
|
||||
artifactVersion: artifact.artifactVersion ?? 1,
|
||||
viewportName: artifact.viewportName ?? "unknown",
|
||||
windowSize: artifact.windowSize ?? "unknown",
|
||||
query: artifact.query ?? "",
|
||||
screenshotBytes: Number.isFinite(artifact.screenshotBytes) ? artifact.screenshotBytes : 0,
|
||||
validatedBy: artifact.validatedBy ?? "unknown",
|
||||
fullDiagnosticsApiName: artifact.fullDiagnosticsApiName ?? null,
|
||||
fullDiagnosticsPath: artifact.fullDiagnosticsPath ?? null,
|
||||
previewRenderer: artifact.previewRenderer ?? null,
|
||||
previewViewMode: artifact.previewViewMode ?? null,
|
||||
threeReady: artifact.threeReady === true,
|
||||
threePathPoints: Number.isFinite(artifact.threePathPoints) ? artifact.threePathPoints : 0,
|
||||
screenshotPath: artifact.screenshotPath ?? null,
|
||||
diagnosticsPath: artifact.diagnosticsPath ?? null,
|
||||
}));
|
||||
}
|
||||
|
||||
function createAxisScreenshotArtifactSummary(axisScreenshotArtifacts = []) {
|
||||
const artifacts = normalizeAxisScreenshotArtifacts(axisScreenshotArtifacts);
|
||||
const expectedViewports = ["desktop-preview", "desktop-dro", "mobile-preview", "mobile-mdi"];
|
||||
const viewportNames = artifacts.map(({ viewportName }) => viewportName);
|
||||
const missingViewports = expectedViewports.filter((name) => !viewportNames.includes(name));
|
||||
const undersizedViewports = artifacts
|
||||
.filter(({ screenshotBytes }) => screenshotBytes < 10000)
|
||||
.map(({ viewportName }) => viewportName);
|
||||
const ready = artifacts.length === 0 || (missingViewports.length === 0 && undersizedViewports.length === 0);
|
||||
return {
|
||||
apiName: "project-release-axis-screenshot-artifact-summary",
|
||||
summaryVersion: 1,
|
||||
phase: ready ? "ready" : "blocked",
|
||||
ready,
|
||||
expectedViewports,
|
||||
artifactCount: artifacts.length,
|
||||
viewportNames,
|
||||
missingViewports,
|
||||
undersizedViewports,
|
||||
totalScreenshotBytes: artifacts.reduce((sum, { screenshotBytes }) => sum + screenshotBytes, 0),
|
||||
artifacts,
|
||||
};
|
||||
}
|
||||
|
||||
export function createProjectReleaseGateManifest() {
|
||||
return {
|
||||
apiName: "project-release-gate-manifest",
|
||||
@@ -1206,6 +1253,7 @@ export function createProjectReleaseReadinessReport({
|
||||
simConfigInventory = DEFAULT_SIM_CONFIG_INVENTORY_BASELINE,
|
||||
blockedRuntimeFamilies = BLOCKED_RUNTIME_FAMILIES,
|
||||
promotedRuntimeFamilies = [],
|
||||
axisScreenshotArtifacts = [],
|
||||
} = {}) {
|
||||
const gateManifest = createProjectReleaseGateManifest();
|
||||
const gateExecutionManifest = createProjectReleaseGateExecutionManifest({
|
||||
@@ -1236,11 +1284,14 @@ export function createProjectReleaseReadinessReport({
|
||||
const promotedBlockedFamilies = promotedFamilies.filter((family) => blockedFamilies.includes(family));
|
||||
const inventoryReady = inventory.unexpectedFail === 0;
|
||||
const blockedRuntimeReady = promotedBlockedFamilies.length === 0;
|
||||
const ready = releaseGatePassed && inventoryReady && blockedRuntimeReady;
|
||||
const axisScreenshotArtifactSummary = createAxisScreenshotArtifactSummary(axisScreenshotArtifacts);
|
||||
const axisScreenshotArtifactsReady = axisScreenshotArtifactSummary.ready;
|
||||
const ready = releaseGatePassed && inventoryReady && blockedRuntimeReady && axisScreenshotArtifactsReady;
|
||||
const missing = [
|
||||
...(releaseGatePassed ? [] : ["project-release-gate"]),
|
||||
...(inventoryReady ? [] : ["sim-config-inventory"]),
|
||||
...(blockedRuntimeReady ? [] : ["blocked-runtime-families"]),
|
||||
...(axisScreenshotArtifactsReady ? [] : ["axis-screenshot-artifacts"]),
|
||||
];
|
||||
|
||||
return {
|
||||
@@ -1258,6 +1309,7 @@ export function createProjectReleaseReadinessReport({
|
||||
blockedRuntimeFamilies: blockedFamilies,
|
||||
promotedRuntimeFamilies: promotedFamilies,
|
||||
promotedBlockedFamilies,
|
||||
axisScreenshotArtifactSummary,
|
||||
gateManifest,
|
||||
gateExecutionManifest,
|
||||
gateExecutionSummaryViewModel,
|
||||
@@ -1280,6 +1332,13 @@ export function createProjectReleaseReadinessReport({
|
||||
label: "Blocked runtime families",
|
||||
value: blockedRuntimeReady ? blockedFamilies.join(", ") : `promoted: ${promotedBlockedFamilies.join(", ")}`,
|
||||
},
|
||||
{
|
||||
id: "axis-screenshot-artifacts",
|
||||
label: "AXIS screenshot artifacts",
|
||||
value: axisScreenshotArtifactSummary.artifactCount > 0
|
||||
? `${axisScreenshotArtifactSummary.artifactCount}/${axisScreenshotArtifactSummary.expectedViewports.length} captured`
|
||||
: "not captured",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -1290,6 +1349,7 @@ export function createProjectReleaseReadinessSummaryViewModel(
|
||||
const missing = Array.isArray(report?.missing) ? report.missing : [];
|
||||
const gateResultMatrix = objectOrEmpty(report?.gateResultMatrix);
|
||||
const simConfigInventory = objectOrEmpty(report?.simConfigInventory);
|
||||
const axisScreenshotArtifactSummary = objectOrEmpty(report?.axisScreenshotArtifactSummary);
|
||||
const blockedRuntimeFamilies = arrayOrEmpty(report?.blockedRuntimeFamilies);
|
||||
const promotedBlockedFamilies = arrayOrEmpty(report?.promotedBlockedFamilies);
|
||||
const ready = report?.ready === true;
|
||||
@@ -1327,6 +1387,13 @@ export function createProjectReleaseReadinessSummaryViewModel(
|
||||
? `promoted: ${promotedBlockedFamilies.join(", ")}`
|
||||
: (blockedRuntimeFamilies.join(", ") || "none"),
|
||||
},
|
||||
{
|
||||
id: "axis-screenshot-artifacts",
|
||||
label: "AXIS screenshot artifacts",
|
||||
value: Number(axisScreenshotArtifactSummary.artifactCount ?? 0) > 0
|
||||
? `${axisScreenshotArtifactSummary.artifactCount}/${arrayOrEmpty(axisScreenshotArtifactSummary.expectedViewports).length} captured`
|
||||
: "not captured",
|
||||
},
|
||||
{
|
||||
id: "missing",
|
||||
label: "Missing readiness",
|
||||
@@ -1840,6 +1907,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
const gateExecutionSummaryViewModel = objectOrEmpty(artifactObject.gateExecutionSummaryViewModel);
|
||||
const gateResultMatrix = objectOrEmpty(artifactObject.gateResultMatrix);
|
||||
const gateActionPlan = objectOrEmpty(artifactObject.gateActionPlan);
|
||||
const axisScreenshotArtifactSummary = objectOrEmpty(artifactObject.axisScreenshotArtifactSummary);
|
||||
const gates = arrayOrEmpty(artifactObject.gates);
|
||||
const manifestGateIds = arrayOrEmpty(gateManifest.gateIds);
|
||||
const executionRows = arrayOrEmpty(gateExecutionManifest.rows);
|
||||
@@ -1879,6 +1947,30 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
&& gateActionPlan.pendingCount === 0
|
||||
&& gateActionPlan.nextCommand === null
|
||||
&& actionPlanCommands.length === 0;
|
||||
const axisScreenshotArtifacts = arrayOrEmpty(axisScreenshotArtifactSummary.artifacts);
|
||||
const axisScreenshotSummaryReady = !axisScreenshotArtifactSummary.apiName
|
||||
|| axisScreenshotArtifacts.length === 0
|
||||
|| (
|
||||
axisScreenshotArtifactSummary.apiName === "project-release-axis-screenshot-artifact-summary"
|
||||
&& axisScreenshotArtifactSummary.summaryVersion === 1
|
||||
&& axisScreenshotArtifactSummary.ready === true
|
||||
&& axisScreenshotArtifacts.length === 4
|
||||
&& arrayOrEmpty(axisScreenshotArtifactSummary.missingViewports).length === 0
|
||||
&& arrayOrEmpty(axisScreenshotArtifactSummary.undersizedViewports).length === 0
|
||||
&& axisScreenshotArtifacts.every((artifact) =>
|
||||
artifact.apiName === "real-browser-simulation-axis-screenshot-artifact"
|
||||
&& artifact.screenshotBytes >= 10000
|
||||
&& artifact.validatedBy === "browser_real_simulation_page_smoke"
|
||||
&& (
|
||||
artifact.fullDiagnosticsPath === null
|
||||
|| (
|
||||
artifact.fullDiagnosticsApiName === "real-browser-simulation-diagnostics-artifact"
|
||||
&& artifact.previewRenderer === "threejs"
|
||||
&& artifact.threePathPoints > 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
const missing = [
|
||||
...(artifactObject.apiName === PROJECT_RELEASE_READINESS_ARTIFACT_API ? [] : ["apiName"]),
|
||||
...(artifactObject.reportVersion === PROJECT_RELEASE_READINESS_ARTIFACT_VERSION ? [] : ["reportVersion"]),
|
||||
@@ -1901,6 +1993,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
...(executionSummaryReady ? [] : ["gateExecutionSummaryViewModel"]),
|
||||
...(matrixReady ? [] : ["gateResultMatrix"]),
|
||||
...(actionPlanReady ? [] : ["gateActionPlan"]),
|
||||
...(axisScreenshotSummaryReady ? [] : ["axisScreenshotArtifactSummary"]),
|
||||
...(gateCountReady ? [] : ["gates.length"]),
|
||||
...(gatesPassed ? [] : ["gates.passed"]),
|
||||
...(rows.find(({ id, value }) => id === "project-release-gate" && value === "passed")
|
||||
@@ -1924,6 +2017,8 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
gateExecutionSummaryReady: executionSummaryReady,
|
||||
gateResultMatrixReady: matrixReady,
|
||||
gateActionPlanReady: actionPlanReady,
|
||||
axisScreenshotArtifactSummaryReady: axisScreenshotSummaryReady,
|
||||
axisScreenshotArtifactCount: axisScreenshotArtifacts.length,
|
||||
blockedRuntimeFamilies: arrayOrEmpty(artifactObject.blockedRuntimeFamilies),
|
||||
rows: [
|
||||
{
|
||||
@@ -1961,6 +2056,13 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
label: "Gate action plan",
|
||||
value: actionPlanReady ? "ready" : "missing",
|
||||
},
|
||||
{
|
||||
id: "axis-screenshot-artifacts",
|
||||
label: "AXIS screenshot artifacts",
|
||||
value: axisScreenshotArtifacts.length > 0
|
||||
? `${axisScreenshotArtifacts.length} captured`
|
||||
: "not captured",
|
||||
},
|
||||
{
|
||||
id: "validation",
|
||||
label: "Artifact validation",
|
||||
|
||||
Reference in New Issue
Block a user