Files
ytplayer/tests/now-playing-return.spec.js
2026-10-03 18:29:48 +08:00

76 lines
4.2 KiB
JavaScript

const { test, expect } = require('@playwright/test');
const { openClassic, showPlayingFixture } = require('./helpers/classic-fixture');
for (const layout of ['classic', 'glass-stage']) {
for (const width of [390, 1440]) {
for (const route of ['mini player', 'close', 'player jump', 'browser back', 'track reveal'].filter(route => width === 390 || route !== 'player jump')) {
test(`${layout} ${width}: ${route} restores the playing list`, async ({ page }) => {
await page.setViewportSize({ width, height: 844 });
await openClassic(page, { populated: true, settings: { autoPreload: false } });
await showPlayingFixture(page);
await page.evaluate(layout => {
document.documentElement.dataset.layout = layout;
for (const type of ['search', 'history', 'saved', 'downloads', 'channel', 'settings', 'search']) {
view = { type };
if (type === 'search') setHomeOverPlayer(true);
render();
}
showMiniBar();
}, layout);
// Chromium is not an installed phone PWA. Expose its mini-player
// chrome while exercising the actual click listeners (no forced click).
await page.addStyleTag({ content: '#miniBar { display:flex !important; }' });
if (route === 'close') await page.locator('#miniCloseBtn').click();
else if (route === 'track reveal') {
// User-picked tracks/deep links share this reveal hook after loading;
// avoid testing network/media decoding with synthetic fixture ids.
await page.evaluate(() => scrollPlayerIntoViewPortrait());
} else {
await page.locator('#miniTitle').click();
if (route === 'player jump') {
await page.evaluate(() => { view = { type: 'history' }; render(); });
await page.locator('#sectionRail [data-sec="player"]').click();
} else if (route === 'browser back') {
await page.evaluate(() => { view = { type: 'history' }; render(); });
await page.goBack();
await expect(page.locator('#listTitle')).toHaveText('Studio sessions');
await page.goBack();
await expect(page.locator('#playerPane')).toHaveClass(/home-over/);
await page.goForward();
}
}
await expect(page.locator('#upnext')).toBeVisible();
await expect(page.locator('#upnextList .upnext-item')).toHaveCount(11);
await expect(page.locator('#listPane')).toBeVisible();
await expect(page.locator('#listTitle')).toHaveText('Studio sessions');
await expect(page.locator('#cards .card')).toHaveCount(12);
expect(await page.evaluate(() => ({ source: queueSource, index: queueIndex, size: queue.length, id: current.meta.id })))
.toEqual({ source: 'playlist:studio', index: 0, size: 12, id: 'preview0000' });
});
}
}
test(`${layout}: missing source playlist falls back to the live queue`, async ({ page }) => {
await page.setViewportSize({ width: 390, height: 844 });
await openClassic(page, { populated: true, settings: { autoPreload: false } });
await showPlayingFixture(page);
await page.evaluate(layout => {
document.documentElement.dataset.layout = layout;
data.playlists = [];
data.queue = [];
view = { type: 'downloads' }; render();
scrollPlayerIntoViewPortrait();
}, layout);
await expect(page.locator('#listTitle')).toHaveText('Now playing');
await expect(page.locator('#cards .card')).toHaveCount(12);
await expect(page.locator('#upnextList .upnext-item')).toHaveCount(11);
const historyLength = await page.evaluate(() => history.length);
// Re-entry must repair stale DOM even when home-over is already false.
await page.evaluate(() => { document.getElementById('upnextList').innerHTML = ''; scrollPlayerIntoViewPortrait(); });
await expect(page.locator('#upnextList .upnext-item')).toHaveCount(11);
expect(await page.evaluate(() => history.length)).toBe(historyLength);
await page.evaluate(() => { queueIndex = queue.length - 1; scrollPlayerIntoViewPortrait(); });
await expect(page.locator('#upnext')).toBeHidden();
await expect(page.locator('#cards .card')).toHaveCount(12);
});
}