fix(epg): scroll the programme guide to now on open and on Now/N (#1781)

This commit is contained in:
4gray authored and GitHub committed 2026-10-01 21:40:06 +02:00
1 parent 572034f3be
commit 1653ffe9fb
10 files changed
+423 -52

No files matched your search

@@ -1,3 +1,4 @@
import { Page } from '@playwright/test';
import {
buildM3uContent,
channelItemByTitle,
@@ -40,6 +41,39 @@ function xmltvWithCurrentProgramme(
`;
}
/** True when the now-line is painted inside the visible programme lane. */
function nowLineInLane(page: Page): Promise<boolean> {
return page.evaluate(() => {
const lane = document
.querySelector('.epg-guide__now-clip')
?.getBoundingClientRect();
const line = document
.querySelector('.epg-guide__now-line')
?.getBoundingClientRect();
return (
!!lane &&
!!line &&
line.left >= lane.left &&
line.right <= lane.right
);
});
}
/** Scroll the lane to whichever end of the day is farther from now. */
async function scrollAwayFromNow(page: Page): Promise<void> {
await page.evaluate(() => {
const viewport = document.querySelector(
'.epg-guide__viewport'
) as HTMLElement;
const badge = document.querySelector(
'.epg-guide__now-badge'
) as HTMLElement;
const nowLeft = parseFloat(badge.style.left);
const end = viewport.scrollWidth - viewport.clientWidth;
viewport.scrollTo({ left: nowLeft > end / 2 ? 0 : end });
});
}
test('@epg @electron opens the programme guide with the playlist channels, switches channels and keeps the player mounted', async ({
dataDir,
}) => {
@@ -133,6 +167,27 @@ test('@epg @electron opens the programme guide with the playlist channels, switc
timeout: 20000,
});
// The guide opens on "now", and the Now button and N jump back to it
// on both axes at once (#1733: the lane stayed at midnight).
await expect.poll(() => nowLineInLane(app.mainWindow)).toBe(true);
await scrollAwayFromNow(app.mainWindow);
await expect.poll(() => nowLineInLane(app.mainWindow)).toBe(false);
await guide.locator('.guide-toolbar__now').click();
await expect.poll(() => nowLineInLane(app.mainWindow)).toBe(true);
await scrollAwayFromNow(app.mainWindow);
await expect.poll(() => nowLineInLane(app.mainWindow)).toBe(false);
// Keys are left alone while a toolbar button holds the focus.
await app.mainWindow.evaluate(() =>
(document.activeElement as HTMLElement | null)?.blur()
);
await app.mainWindow.keyboard.press('n');
await expect.poll(() => nowLineInLane(app.mainWindow)).toBe(true);
// The keyboard focus follows the jump to the playing row.
await expect(
rows.nth(0).locator('[data-epg-guide-grid][tabindex="0"]')
).toBeFocused();
// "Only with EPG" hides the silent channel once coverage is known.
const toggle = guide.locator('.guide-toolbar__toggle input');
await expect(toggle).toBeEnabled({ timeout: 20000 });