Fix pre-release smoke probes after merged contracts

Issue: #122
Issue: #131
Issue: #107
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-08-14 04:29:21 +03:00
parent 188a386cd8
commit 159094cfec
5 changed files with 26 additions and 5 deletions
+6 -1
View File
@@ -257,7 +257,12 @@ const layers = await page.evaluate(() => {
const c = window.__card;
const m = c._spaceModel();
const svgEl = c.renderRoot.querySelector('.stage svg');
const kids = [...svgEl.children];
// Stage 2 keeps the flat floor DOM byte-for-byte equivalent but places it
// in one transformable scene group shared with Iso. Ordering is therefore
// measured inside the group that actually owns paper/image/rooms.
const layerRoot = [...svgEl.children].find((node) =>
node.querySelector?.('.hp-paperg') && node.querySelector?.('.room')) || svgEl;
const kids = [...layerRoot.children];
const idx = (sel) => kids.findIndex((n) => n.matches(sel) || n.querySelector?.(sel));
const papers = [...svgEl.querySelectorAll('.hp-paper')];
return {
+7 -2
View File
@@ -197,7 +197,10 @@ const paper = await page.evaluate(async () => {
&& cs.fill !== 'none' && !/rgba\(.*,\s*0\)/.test(cs.fill);
}
// …and the picture is drawn ON that paper: image after paper, before walls
const kids = [...sr().querySelector('.stage svg').children];
const svgEl = sr().querySelector('.stage svg');
const layerRoot = [...svgEl.children].find((node) =>
node.querySelector?.('.hp-paperg') && node.querySelector?.('.room')) || svgEl;
const kids = [...layerRoot.children];
const idxOf = (sel) => kids.findIndex((n) => n.matches(sel) || n.querySelector?.(sel));
out.imageAbovePaper = idxOf('image') > idxOf('.hp-paper') && idxOf('image') >= 0;
out.imageBelowRooms = idxOf('image') < idxOf('.room, .room-outline');
@@ -266,7 +269,9 @@ const drawn = await page.evaluate(async () => {
});
// paper first, everything else on top of it (one .hp-paperg group wraps
// all paper shapes so the daynight drop shadow composites without seams)
const first = sr().querySelector('.stage.noplan svg').firstElementChild;
const noplanSvg = sr().querySelector('.stage.noplan svg');
const noplanLayers = [...noplanSvg.children].find((node) => node.querySelector?.('.hp-paperg')) || noplanSvg;
const first = [...noplanLayers.children].find((node) => node.tagName.toLowerCase() !== 'defs');
out.paperUnderneath = !!first && first.classList.contains('hp-paperg')
&& !!first.firstElementChild && first.firstElementChild.classList.contains('hp-paper');
// live resize preview: drag the L's right wall 0.625 -> 0.6875 — the paper
+7 -1
View File
@@ -197,7 +197,13 @@ Object.assign(out, await page.evaluate(async () => {
},
// модульный кэш конфига инвалидируется только через это событие — стаб
// сохраняет колбэк, чтобы следующий тест мог сбросить кэш
connection: { subscribeEvents: async (cb) => { window.__hpInvalidate = cb; return () => {}; } } };
connection: { subscribeEvents: async (cb, type) => {
// #107 added a third, virtual-light subscription. Keep the config event
// callback specifically; otherwise the next fixture calls the unrelated
// virtual-light listener and reuses this stale shared config snapshot.
if (type === 'houseplan_config_updated') window.__hpInvalidate = cb;
return () => {};
} } };
const host = document.createElement('div');
document.body.appendChild(host);
const card = document.createElement('houseplan-space-card');
+1 -1
View File
@@ -116,7 +116,7 @@ const res = await page.evaluate(async () => {
c._setProjection('iso');
await update();
out.isoUsesCanonicalBody = !!sr().querySelector('.iso-walls .iso-wall-top')
&& c._isoSource().build().flat(2).length > 0;
&& c._isoSource().build().walls.flat(2).length > 0;
c._setProjection('flat');
await update();
+5
View File
@@ -42,6 +42,11 @@ const result = await page.evaluate(async (visualFixture) => {
card._serverCfg = visualFixture.config;
card._layout = visualFixture.layout;
card._space = 'golden-lighting';
// This fixture starts after a same-route space choice. #131 deliberately
// refuses to treat the class initializer/current id as cold-start intent;
// mark this injected selection as already adopted navigation so the reload
// exercises continuity instead of cold-start precedence.
card._navApplied = true;
card._regSignature = '';
card.hass = {
...card.hass,