Point the motion check at a block that keeps its entrance
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s

The Kant-IT home page now animates blocks instead of whole sections, so the
check waits for the closing call to action rather than the contact section.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Fable 5.1 committed 2026-09-14 17:23:43 +02:00
1 parent 2299184401
commit b634f486e5
2 files changed
+21 -15

No files matched your search

+15 -15
View File
@@ -53,30 +53,30 @@ try {
const hovered = await hoverTarget.evaluate(node => ({ transform: getComputedStyle(node).transform, matches: node.matches(':hover'), classes: node.className }));
console.log('Pilot hover:', width, JSON.stringify(hovered));
assert.equal(hovered.transform, 'matrix(1, 0, 0, 1, 0, -4)', 'Saved lift effect changes the rendered transform');
const target = page.locator('#kontakt');
assert.equal(await page.evaluate(() => motionCalls.some(call => call.id === 'kontakt')), false, 'Below-fold section must wait for scrolling');
const target = page.locator('#abschluss-cta');
assert.equal(await page.evaluate(() => motionCalls.some(call => call.id === 'abschluss-cta')), false, 'Below-fold section must wait for scrolling');
assert.equal(await target.evaluate(node => node.style.opacity), '0', 'Below-fold block waits out of sight, as in Flatsome');
await target.scrollIntoViewIfNeeded();
await page.waitForFunction(() => motionCalls.some(call => call.id === 'kontakt'));
await page.waitForFunction(() => motionCalls.some(call => call.id === 'abschluss-cta'));
const calls = await page.evaluate(() => motionCalls);
assert.equal(calls.find(call => call.id === 'kontakt').frames[0].transform, 'translateY(40px)');
assert.equal(calls.find(call => call.id === 'kontakt').frames[0].opacity, 0, 'Entrance fades in from invisible, as in Flatsome');
assert.equal(calls.find(call => call.id === 'abschluss-cta').frames[0].transform, 'translateY(40px)');
assert.equal(calls.find(call => call.id === 'abschluss-cta').frames[0].opacity, 0, 'Entrance fades in from invisible, as in Flatsome');
await page.waitForTimeout(800);
await page.evaluate(() => scrollTo(0, 0)); await target.scrollIntoViewIfNeeded(); await page.waitForTimeout(100);
assert.equal(await page.evaluate(() => motionCalls.filter(call => call.id === 'kontakt').length), 1, 'Entrance runs once');
assert.equal(await page.evaluate(() => motionCalls.filter(call => call.id === 'abschluss-cta').length), 1, 'Entrance runs once');
await page.screenshot({ path: `${report}/pilot-${width}.png` });
// Exercise both existing choices on the real pilot element without editing saved content.
for (const direction of ['left', 'right']) {
await page.evaluate(async direction => {
const node = document.getElementById('kontakt');
const node = document.getElementById('abschluss-cta');
node.classList.remove('fx-entrance-rise', 'fx-entrance-left', 'fx-entrance-right');
node.classList.add(`fx-entrance-${direction}`);
const { initMotion } = await import(document.querySelector('script[src*="motion.js"]').src);
window.stopMotionCheck?.(); window.motionCalls = [];
window.stopMotionCheck = initMotion();
}, direction);
await page.waitForFunction(() => motionCalls.some(call => call.id === 'kontakt'));
await page.waitForFunction(() => motionCalls.some(call => call.id === 'abschluss-cta'));
const actual = await target.evaluate(node => {
const animation = node.getAnimations()[0]; animation.pause(); animation.currentTime = 150;
return { transform: getComputedStyle(node).transform, frames: animation.effect.getKeyframes() };
@@ -91,7 +91,7 @@ try {
// Umut's Chrome reports "reduce" without anyone having chosen it; the site must still move.
await page.emulateMedia({ reducedMotion: 'reduce' });
await page.reload(); await target.scrollIntoViewIfNeeded();
await page.waitForFunction(() => motionCalls.some(call => call.id === 'kontakt'), null, { timeout: 3000 });
await page.waitForFunction(() => motionCalls.some(call => call.id === 'abschluss-cta'), null, { timeout: 3000 });
await page.waitForTimeout(900);
assert.equal(await target.evaluate(node => getComputedStyle(node).opacity), '1', 'Block ends fully visible');
await hoverTarget.scrollIntoViewIfNeeded(); await hoverTarget.hover(); await page.waitForTimeout(350);
@@ -116,7 +116,7 @@ try {
}).observe(document, { childList: true });
});
const respectPage = await respect.newPage(); respectPage.on('pageerror', error => errors.push(error.message));
const respectTarget = respectPage.locator('#kontakt'), respectHover = respectPage.locator('#leistung-app');
const respectTarget = respectPage.locator('#abschluss-cta'), respectHover = respectPage.locator('#leistung-app');
await respectPage.goto(origin); await respectTarget.scrollIntoViewIfNeeded(); await respectPage.waitForTimeout(800);
assert.equal(await respectPage.evaluate(() => motionCalls.length), 0, 'Reduced motion suppresses animations when respected');
assert.equal(await respectTarget.evaluate(node => getComputedStyle(node).opacity), '1');
@@ -124,29 +124,29 @@ try {
assert.equal(await respectHover.evaluate(node => getComputedStyle(node).transform), 'none', 'Reduced motion suppresses hover movement when respected');
await respectTarget.scrollIntoViewIfNeeded();
await respectPage.emulateMedia({ reducedMotion: 'no-preference' });
await respectPage.waitForFunction(() => motionCalls.some(call => call.id === 'kontakt'), null, { timeout: 3000 });
await respectPage.waitForFunction(() => motionCalls.some(call => call.id === 'abschluss-cta'), null, { timeout: 3000 });
await respectPage.waitForTimeout(900);
await respectPage.emulateMedia({ reducedMotion: 'reduce' });
await respectPage.emulateMedia({ reducedMotion: 'no-preference' });
await respectPage.waitForTimeout(100);
assert.equal(await respectPage.evaluate(() => motionCalls.filter(call => call.id === 'kontakt').length), 1, 'Preference changes do not replay an already seen element');
assert.equal(await respectPage.evaluate(() => motionCalls.filter(call => call.id === 'abschluss-cta').length), 1, 'Preference changes do not replay an already seen element');
await respectHover.scrollIntoViewIfNeeded(); await respectHover.hover(); await respectPage.waitForTimeout(350);
assert.equal(await respectHover.evaluate(node => getComputedStyle(node).transform), 'matrix(1, 0, 0, 1, 0, -4)', 'Hover resumes after allowing motion');
// Also cover a page that starts normally, then suppresses motion before reaching its content.
await respectPage.reload(); await respectPage.waitForTimeout(800);
await respectPage.emulateMedia({ reducedMotion: 'reduce' });
await respectTarget.scrollIntoViewIfNeeded(); await respectPage.waitForTimeout(100);
assert.equal(await respectPage.evaluate(() => motionCalls.filter(call => call.id === 'kontakt').length), 0);
assert.equal(await respectPage.evaluate(() => motionCalls.filter(call => call.id === 'abschluss-cta').length), 0);
assert.equal(await respectTarget.evaluate(node => getComputedStyle(node).opacity), '1', 'A waiting block is shown again when motion is reduced');
await respectPage.emulateMedia({ reducedMotion: 'no-preference' });
await respectPage.waitForFunction(() => motionCalls.some(call => call.id === 'kontakt'), null, { timeout: 3000 });
await respectPage.waitForFunction(() => motionCalls.some(call => call.id === 'abschluss-cta'), null, { timeout: 3000 });
results.push({ width, inventory, calls, checks: ['scroll trigger', 'once only', 'hidden until visible', 'left/right computed movement', 'saved hover lift', 'default plays under reduce preference', 'motion-respect honours reduce', 'resume without reloading after initial and subsequent reduced motion', 'hover resumes after preference change'] });
await respect.close();
}
const noJs = await browser.newContext({ javaScriptEnabled: false });
const page = await noJs.newPage(); await page.goto(origin);
assert.ok(await page.locator('main').innerText());
assert.equal(await page.locator('#kontakt').evaluate(node => getComputedStyle(node).opacity), '1');
assert.equal(await page.locator('#abschluss-cta').evaluate(node => getComputedStyle(node).opacity), '1');
await noJs.close();
const editorContext = await browser.newContext({ reducedMotion: 'reduce', viewport: { width: 1600, height: 1000 } });
const editor = await editorContext.newPage(); editor.on('pageerror', error => errors.push(error.message));