import { closeElectronApp, expect, getStableWindow, openModelsPage, test } from './fixtures/electron'; test.describe('hover-only scrollbar visibility', () => { test('hides scrollbars until a scroll container is hovered', async ({ launchElectronApp }) => { const app = await launchElectronApp({ skipSetup: true }); try { const page = await getStableWindow(app); await expect(page.getByTestId('ai-module-selection-page')).toBeVisible(); await page.getByTestId('ai-module-option-programming').click(); await openModelsPage(page); const scrollContainer = page.locator('[data-testid="models-page"] .overflow-y-auto').first(); await expect(scrollContainer).toBeVisible(); await page.getByTestId('models-page-title').hover(); const beforeHover = await scrollContainer.evaluate((element) => { const style = window.getComputedStyle(element); const thumbStyle = window.getComputedStyle(element, '::-webkit-scrollbar-thumb'); return { scrollbarWidth: style.scrollbarWidth, thumbBackground: thumbStyle.backgroundColor, }; }); await expect(scrollContainer).toHaveCSS('scrollbar-width', 'thin'); // Chromium may report the scrollbar pseudo element's hover color even // while the pointer is over a sibling. The platform-independent // contract is the thin, non-layout scrollbar and the explicit hover // state below. expect(beforeHover.scrollbarWidth).toBe('thin'); await scrollContainer.hover(); const afterHover = await scrollContainer.evaluate((element) => { const style = window.getComputedStyle(element); const thumbStyle = window.getComputedStyle(element, '::-webkit-scrollbar-thumb'); return { scrollbarWidth: style.scrollbarWidth, thumbBackground: thumbStyle.backgroundColor, }; }); expect(afterHover.scrollbarWidth).toBe('thin'); expect(await scrollContainer.evaluate((element) => element.matches(':hover'))).toBe(true); } finally { await closeElectronApp(app); } }); });