const { test, expect } = require('@playwright/test'); const { openClassic, showPlayingFixture } = require('./helpers/classic-fixture'); for (const layout of ['classic', 'glass-stage']) test(`${layout}: related failure stays visible and Retry refreshes`, async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await openClassic(page, { populated: true }); await showPlayingFixture(page); let calls = 0; await page.route('**/api/related?**', route => { calls++; if (calls > 1) expect(new URL(route.request().url()).searchParams.get('refresh')).toBe('1'); return route.fulfill({ status: calls === 1 ? 503 : 200, contentType: 'application/json', body: JSON.stringify(calls === 1 ? { ok: false, error: 'Raw YouTube failure' } : { ok: true, results: [{ id: 'bbbbbbbbbbb', title: 'A related song', channel: 'Artist' }] }) }); }); const railParent = await page.locator('#sectionRail').evaluate(el => el.parentElement.id || el.parentElement.className); await page.evaluate(async layout => { data.settings.layout = layout; applyAppearance(); view = { type: 'nowPlaying' }; render(); relatedCollapsed = false; await loadRelated(); }, layout); await expect(page.locator('#relatedPanel')).toBeVisible(); await expect(page.locator('#relatedList')).toContainText('Please try again'); await expect(page.locator('#relatedList')).not.toContainText('Raw YouTube failure'); await page.getByRole('button', { name: 'Retry related videos' }).click(); await expect(page.locator('.ri-title')).toHaveText('A related song'); expect(await page.locator('#sectionRail').evaluate(el => el.parentElement.id || el.parentElement.className)).toBe(railParent); });