const { test, expect } = require('@playwright/test'); const { readFileSync } = require('node:fs'); const { openClassic, showPlayingFixture } = require('./helpers/classic-fixture'); const phoneCss = readFileSync('frontend/styles.css', 'utf8').replaceAll('(display-mode: standalone)', '(min-width: 0px)').replaceAll('env(safe-area-inset-bottom)', '34px'); // Glass Stage section rail floats centred above the mini player and stays put while the page scrolls. test('glass rail floats above the mini player and ignores scroll', async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.route('**/styles.css', r => r.fulfill({ contentType: 'text/css', body: phoneCss })); await openClassic(page, { populated: true, standalone: true, settings: { autoPreload: false } }); await showPlayingFixture(page); await page.evaluate(() => { data.settings.layout = 'glass-stage'; applyAppearance(); document.getElementById('miniBar').classList.remove('hidden'); updateBottomChrome(); SectionRail.refresh(); }); await page.waitForTimeout(300); const at = () => page.evaluate(() => { const r = document.getElementById('sectionRail').getBoundingClientRect(), m = document.getElementById('miniBar').getBoundingClientRect(); return { top: r.top, bottom: r.bottom, center: (r.left + r.right) / 2, miniTop: m.top, parent: document.getElementById('sectionRail').parentElement.id, pos: getComputedStyle(document.getElementById('sectionRail')).position }; }); const a = await at(); expect(a.pos).toBe('fixed'); expect(a.parent).not.toBe('listPane'); expect(Math.abs(a.center - 195)).toBeLessThan(2); expect(a.bottom).toBeLessThanOrEqual(a.miniTop); await page.screenshot({ path: process.env.SHOT_DIR ? `${process.env.SHOT_DIR}/rail-a.png` : undefined }); await page.evaluate(() => { for (const el of [document.scrollingElement, ...document.querySelectorAll('.body,#listPane,.player-pane')]) el && (el.scrollTop += 600); }); await page.waitForTimeout(200); const b = await at(); expect(Math.abs(b.top - a.top)).toBeLessThan(1); await page.screenshot({ path: process.env.SHOT_DIR ? `${process.env.SHOT_DIR}/rail-b.png` : undefined }); });