Files
houseplan-card/demo/smoke_subarea.mjs
T
2026-08-31 10:16:46 +03:00

96 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { launch, checkAll, finish } from './serve.mjs';
const { page, browser } = await launch();
const res = await page.evaluate(async () => {
const out = {};
const c = window.__card;
// комната без зоны на f1
c._serverCfg = { ...c._serverCfg, spaces: c._serverCfg.spaces.map((s) => s.id !== 'f1' ? s : ({
...s, rooms: [...s.rooms, { id: 'rc', name: 'Cupboard', area: null, poly: [[0.05,0.62],[0.2,0.62],[0.2,0.9],[0.05,0.9]] }],
})).map((s) => s.id !== 'garden' ? s : ({
...s, rooms: [...s.rooms,
{ id: 'garden-shed-a', name: 'Shed A', area: null, poly: [[0.60,0.55],[0.80,0.55],[0.80,0.75],[0.60,0.75]] },
{ id: 'garden-shed-b', name: 'Shed B', area: null, poly: [[0.25,0.55],[0.45,0.55],[0.45,0.75],[0.25,0.75]] },
],
})) };
c._regSignature = ''; c._maybeRebuildDevices(); await c.updateComplete;
// список комнат в диалоге содержит подзону
c._setMode('devices');
c._openMarkerDialog(); await c.updateComplete;
const rooms = c._allRoomsFlat();
out.subareaListed = rooms.some((r) => r.value === 'f1#@rc');
// создать виртуальный маркер в подзону
c._markerDialog = { ...c._markerDialog, name: 'Vacuum dock', binding: 'virtual', room: 'f1#@rc' };
await c._saveMarker(); await c.updateComplete;
const m = c._serverCfg.markers.find((x) => x.name === 'Vacuum dock');
out.markerRoomId = m?.room_id;
out.markerAreaNull = m ? m.area === null : null;
// позиция — в центре подзоны (норм. центр rc: x=0.125, y=0.76)
const pos = c._layout[m.id];
out.posInRoom = pos && Math.abs(pos.x - 0.125) < 0.03 && Math.abs(pos.y - 0.76) < 0.03;
// девайс отрисован
const dev = c._devices.find((d) => d.id === m.id);
out.deviceBuilt = !!dev && dev.space === 'f1';
// reopen диалога восстанавливает выбор
c._openMarkerDialog(dev);
out.reopenRoom = c._markerDialog?.room;
c._markerDialog = null;
// Реальное HA-устройство с registry Area вручную переносится в комнату без
// Area другого пространства. Registry metadata не должна вернуть его в f1.
const source = c._devices.find((d) => d.id === 'd_light1');
c._openMarkerDialog(source); await c.updateComplete;
const roomSelect = c.renderRoot.querySelector('#marker-room');
roomSelect.value = 'garden#@garden-shed-a';
roomSelect.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
await c.updateComplete;
out.realRoomChangeMarkedTouched = c._markerDialog?.roomTouched === true;
await c._saveMarker(); await c.updateComplete;
const haMarker = c._serverCfg.markers.find((x) => x.binding === 'device:d_light1');
const moved = c._devices.find((d) => d.id === haMarker?.id);
const crossPos = c._layout[haMarker?.id];
out.haMarkerSaved = !!haMarker
&& haMarker.space === 'garden' && haMarker.area === null && haMarker.room_id === 'garden-shed-a';
out.haRuntimePlacement = !!moved
&& moved.space === 'garden' && moved.area === '' && moved.marker?.room_id === 'garden-shed-a';
out.crossSpaceCentered = !!crossPos && crossPos.s === 'garden'
&& Math.abs(crossPos.x - 0.70) < 0.03 && Math.abs(crossPos.y - 0.65) < 0.03;
c._openMarkerDialog(moved); await c.updateComplete;
out.haReopenRoom = c._markerDialog?.room === 'garden#@garden-shed-a';
c._markerDialog = null;
// Защитный негативный кейс: transient runtime-пара с room_id из другого
// пространства не роняет диалог и не переписывает сохранённый marker.
const persistedBeforeInvalidOpen = JSON.stringify(haMarker);
c._openMarkerDialog({ ...moved, space: 'f1' }); await c.updateComplete;
const invalidSelect = c.shadowRoot?.querySelector('#marker-room');
out.invalidPairPlaceholder = invalidSelect?.value === '';
out.invalidPairReadOnly = JSON.stringify(
c._serverCfg.markers.find((x) => x.binding === 'device:d_light1'),
) === persistedBeforeInvalidOpen;
c._markerDialog = null; await c.updateComplete;
// Смена комнаты внутри того же пространства сохраняет уже закреплённую
// позицию, хотя room_id меняется.
c._openMarkerDialog(moved); await c.updateComplete;
const secondRoomSelect = c.renderRoot.querySelector('#marker-room');
secondRoomSelect.value = 'garden#@garden-shed-b';
secondRoomSelect.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
await c.updateComplete;
await c._saveMarker(); await c.updateComplete;
const sameSpaceMarker = c._serverCfg.markers.find((x) => x.binding === 'device:d_light1');
const sameSpacePos = c._layout[sameSpaceMarker?.id];
const sameSpaceDevice = c._devices.find((d) => d.id === sameSpaceMarker?.id);
out.sameSpaceRoomSaved = sameSpaceMarker?.room_id === 'garden-shed-b'
&& sameSpaceDevice?.space === 'garden' && sameSpaceDevice?.area === '';
out.sameSpacePositionKept = !!sameSpacePos
&& sameSpacePos.s === crossPos.s && sameSpacePos.x === crossPos.x && sameSpacePos.y === crossPos.y;
return out;
});
// значения зафиксированы прогоном на v1.43.1 и сверены с кодом (audit T1)
checkAll(res, {
"markerRoomId": "rc",
"reopenRoom": "f1#@rc",
});
await finish(browser, res);