mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 03:38:47 +00:00
test: judge marker reuse by node identity, not by a transition
The marker half of the space-switch witness asked whether a box-shadow transition was running on the shell. That worked only because such a transition existed; #524 removed it — the shadow is sized in container units and animating it cost a real user 9.4 frames per second — and the check became trivially true. The mutant that removes the keys from the marker list has been surviving ever since, and nobody noticed until the next gate ran it. The witness now keeps references to the marker nodes and requires that none of them stays in the DOM under a different data-id after the switch. Node identity is what the keys are for, and it does not depend on any stylesheet. The door half is untouched: there the transition is part of the product contract, not a side effect. Issue: #528 User-Visible: no
This commit is contained in:
@@ -97,6 +97,14 @@ const res = await page.evaluate(async () => {
|
||||
await settle();
|
||||
const leafBefore = root().querySelector('.op-leaf');
|
||||
out.doorIsDrawnInTheFirstSpace = !!leafBefore;
|
||||
// #528: маркеры судятся по идентичности узлов, а не по бегущему переходу.
|
||||
// Прежняя проверка смотрела на переход `box-shadow` у оболочки — он исчез
|
||||
// вместе с правкой #524, и мутант «маркеры без ключей» начал выживать:
|
||||
// признак стал тривиально истинным. Идентичность узла не зависит ни от
|
||||
// одного перехода и переживёт любую правку стилей.
|
||||
const markersBefore = [...root().querySelectorAll('[data-hp="device"]')]
|
||||
.map((node) => ({ node, id: node.dataset.id }));
|
||||
out.markersDrawnInTheFirstSpace = markersBefore.length >= 3;
|
||||
out.quietBeforeTheSwitch = runningAnimations().filter((entry) => !EXPECTED(entry)).length === 0;
|
||||
// поворот створки живёт инлайновым стилем, не атрибутом
|
||||
const leafTransform = (leaf) => leaf?.style?.transform || leaf?.getAttribute('transform') || null;
|
||||
@@ -113,6 +121,13 @@ const res = await page.evaluate(async () => {
|
||||
.filter((entry) => /op-leaf|op-arc/.test(entry.cls)).length === 0;
|
||||
out.noMarkerTransitionOnSwitch = afterSwitch
|
||||
.filter((entry) => /device-shell-frame/.test(entry.cls)).length === 0;
|
||||
// Узел, живший до переключения, не имеет права остаться в DOM под чужим
|
||||
// `data-id`: это и есть позиционное переиспользование, ради которого в
|
||||
// `repeat` стоят ключи (#525 AC2, #528).
|
||||
const reused = markersBefore.filter((entry) => entry.node.isConnected
|
||||
&& entry.node.dataset.id !== entry.id);
|
||||
out.noMarkerNodeReusedForAnotherDevice = reused.length === 0;
|
||||
out.reusedMarkerNodes = reused.map((entry) => `${entry.id} → ${entry.node.dataset.id}`);
|
||||
const unexpected = afterSwitch.filter((entry) => !EXPECTED(entry));
|
||||
out.onlyTheSwitchItselfAnimates = unexpected.length === 0;
|
||||
out.unexpectedAnimations = unexpected.map((entry) => `${entry.cls}:${entry.property}`);
|
||||
@@ -135,5 +150,5 @@ const res = await page.evaluate(async () => {
|
||||
.filter((entry) => /op-leaf/.test(entry.cls)).length >= 1;
|
||||
return out;
|
||||
});
|
||||
checkAll(res, { unexpectedAnimations: [] });
|
||||
checkAll(res, { unexpectedAnimations: [], reusedMarkerNodes: [] });
|
||||
await finish(browser, res);
|
||||
|
||||
Reference in New Issue
Block a user