Release v1.62.0-beta.9 candidate

Issue: #108
User-Visible: yes
This commit is contained in:
Matysh
2026-08-12 21:49:29 +03:00
parent 9bb5f7c5a8
commit 8e2973fa7a
40 changed files with 779 additions and 393 deletions
+16
View File
@@ -84,6 +84,22 @@ export function prepareGoldenFixture(scenario) {
}
space.openings = [...(space.openings || []), ...structuredClone(scenario.extraOpenings)];
}
if (scenario.openingGeometry) {
const space = requireSpace();
const opening = (space.openings || []).find(
(item) => item.id === scenario.openingGeometry.id,
);
if (!opening || opening.type !== scenario.openingGeometry.type
|| Math.abs(Number(opening.angle) - scenario.openingGeometry.angle) > 0.001) {
throw new Error(
`golden openingGeometry references a missing/mismatched opening: `
+ `${scenario.openingGeometry.id}`,
);
}
// This scenario must not remain byte-identical to the generic geometry
// capture: isolate the intended diagonal symbol in the rendered fixture.
space.openings = [opening];
}
if (scenario.wallReplacements?.length) {
const space = requireSpace();
const samePoint = (a, b) => Array.isArray(a) && Array.isArray(b)
+2 -1
View File
@@ -19,7 +19,7 @@ export const GOLDEN_SCENARIOS = Object.freeze([
// complete 90 cm door preset while still proving rotation, inner-face
// offset and ruler placement on a thick wall.
mode: 'plan', openingPreview: { type: 'door', pointer: [0.48, 0.65] },
openingPreviewPixels: { minPixels: 40, minChannelDelta: 4 },
openingPreviewPixels: { minPixels: 150, minChannelDelta: 4 },
theme: 'dark', viewport: { width: 1180, height: 900 }, ...page },
{ id: 'geometry-devices-editor-dark', fixture: 'visual', space: 'golden-geometry', mode: 'devices',
theme: 'dark', viewport: { width: 1180, height: 900 }, ...page },
@@ -46,6 +46,7 @@ export const GOLDEN_SCENARIOS = Object.freeze([
editorTray: 'decor-tool', language: 'ru', theme: 'dark',
viewport: { width: 390, height: 760 }, ...page },
{ id: 'geometry-diagonal-45-opening-dark', fixture: 'visual', space: 'golden-geometry', mode: 'view',
openingGeometry: { id: 'geo-diagonal-window', type: 'window', angle: 45 },
theme: 'dark', viewport: { width: 1000, height: 900 }, ...stage },
{ id: 'openings-thick-wall-dark', fixture: 'visual', space: 'golden-lighting', mode: 'view',
fillMode: 'none', glowEnabled: false, theme: 'dark', viewport: { width: 1000, height: 900 }, ...stage },
+33
View File
@@ -385,6 +385,34 @@ try {
pageErrors.length = 0;
result.runtime = await prepareGoldenScenario(page, scenario);
if (pageErrors.length) throw new Error(`browser exception: ${pageErrors.join(' | ')}`);
if (scenario.openingGeometry) {
result.openingGeometry = await page.evaluate((expected) => {
const card = window.__goldenCard;
const opening = card?.renderRoot?.querySelector(
`.opening[data-id="${CSS.escape(expected.id)}"]`,
);
if (!opening) return null;
const transform = opening.getAttribute('transform') || '';
const angle = Number(transform.match(/rotate\(([-+0-9.eE]+)\)/)?.[1]);
const bounds = opening.getBoundingClientRect();
return {
type: opening.getAttribute('data-kind'), angle,
width: bounds.width, height: bounds.height,
visibleParts: opening.querySelectorAll('.op-leaf, .op-arc, .op-glass').length,
};
}, scenario.openingGeometry);
const expected = scenario.openingGeometry;
const actualOpening = result.openingGeometry;
if (!actualOpening || actualOpening.type !== expected.type
|| Math.abs(actualOpening.angle - expected.angle) > 0.001
|| actualOpening.width <= 0 || actualOpening.height <= 0
|| actualOpening.visibleParts <= 0) {
throw new Error(
`semantic golden opening geometry failed for ${expected.id}: `
+ JSON.stringify(actualOpening),
);
}
}
const clip = await goldenClip(page, scenario.capture);
const screenshotOptions = {
...(clip ? { clip } : {}),
@@ -418,6 +446,11 @@ try {
result.openingPreviewParts = control.parts;
result.openingPreviewChangedPixels = sample.changed;
result.openingPreviewMaxChannelDelta = sample.maxDelta;
if (control.parts < 2) {
throw new Error(
`semantic golden assertion failed: opening preview is incomplete (${control.parts} parts)`,
);
}
if (sample.changed < scenario.openingPreviewPixels.minPixels) {
throw new Error(
`semantic golden assertion failed: opening preview paints ${sample.changed} pixels, `
File diff suppressed because one or more lines are too long