test(e2e): adapt to v0.22 dialog + theme picker redesigns

The redesign rollup in this branch replaced the Add Playlist dialog's
2-level type × subtype tabs with a single flat 5-card radiogroup, and
replaced the Settings theme list with a compact segmented control whose
options are just "Light"/"Dark"/"System" (no "theme" suffix). E2E tests
that pinned to the old roles/labels failed in CI:

  - basic / xtream / stalker / self-hosted: getByRole('tab', ...) on
    "Add via file upload" / "Xtream" / "Stalker" — there are no tabs in
    the new dialog. Switched to getByRole('radio', { name: /M3U file/i })
    and friends, matched against the new radio labels.
  - settings: getByRole('radio', { name: 'System theme' }) — the new
    picker uses just "System". Scoped to the [data-test-id="select-theme"]
    radiogroup so it doesn't collide with the identically-labelled
    cover-size options below.

The Electron `clickDialogSegmentedOption` helper grew a radio-role lookup
as its primary path and keeps the old tab/button/legacy-selector
fallbacks so a future redesign won't break every fixture again. The
"M3U" parent category becomes a no-op (the new picker has no standalone
M3U tile — callers always specialise to M3U URL/file/text immediately
after, which is what we want anyway).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 4.7 committed 2026-05-19 22:07:26 +02:00
1 parent 8091dec074
commit a8253c5801
6 files changed
+86 -52

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ test('basic test', async ({ page }) => {
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.locator('mat-dialog-container');
await expect(dialog).toBeVisible();
await dialog.getByRole('tab', { name: 'Add via file upload' }).click();
// v0.22 redesign: tabs were replaced with a flat 5-card radio picker.
await dialog.getByRole('radio', { name: /M3U file/i }).click();
await page.setInputFiles('input[type="file"]', fixturePath);
const addButton = dialog.getByRole('button', {
name: 'Add playlist',
+6 -2
View File
@@ -36,7 +36,10 @@ async function addXtreamPortal(page: Page): Promise<void> {
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.locator('mat-dialog-container');
await expect(dialog).toBeVisible();
await dialog.getByRole('tab', { name: 'Xtream', exact: true }).click();
// v0.22 redesign: tabs were replaced with a flat 5-card radio picker.
await dialog
.getByRole('radio', { name: /Xtream credentials/i })
.click();
await dialog.locator('#title').fill('Self-hosted Xtream');
await dialog.locator('#serverUrl').fill(XTREAM_MOCK_SERVER);
@@ -52,7 +55,8 @@ async function addStalkerPortal(page: Page): Promise<void> {
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.locator('mat-dialog-container');
await expect(dialog).toBeVisible();
await dialog.getByRole('tab', { name: 'Stalker', exact: true }).click();
// v0.22 redesign: tabs were replaced with a flat 5-card radio picker.
await dialog.getByRole('radio', { name: /Stalker portal/i }).click();
await setInputValue(dialog.locator('input#title'), 'Self-hosted Stalker');
await setInputValue(dialog.locator('input#portalUrl'), STALKER_PORTAL_URL);
+12 -3
View File
@@ -49,17 +49,26 @@ test.describe('Settings', () => {
test('Change app theme', async ({ page }) => {
await openSettings(page);
// v0.22 compact theme picker exposes the segmented control as a
// radiogroup with options labelled just "Light"/"Dark"/"System".
// Scope to the theme radiogroup so we don't collide with the
// identically-labelled cover-size options below.
const themeGroup = page.locator(
'[data-test-id="select-theme"][role="radiogroup"]'
);
await expect(
page.getByRole('radio', { name: 'System theme' })
themeGroup.getByRole('radio', { name: 'System', exact: true })
).toHaveAttribute('aria-checked', 'true');
await page.getByRole('radio', { name: 'Dark theme' }).click();
await themeGroup
.getByRole('radio', { name: 'Dark', exact: true })
.click();
await saveSettings(page);
await page.reload();
await openSettings(page);
await expect(
page.getByRole('radio', { name: 'Dark theme' })
themeGroup.getByRole('radio', { name: 'Dark', exact: true })
).toHaveAttribute('aria-checked', 'true');
});
+2 -1
View File
@@ -126,7 +126,8 @@ async function addStalkerPortal(
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.locator('mat-dialog-container');
await expect(dialog).toBeVisible();
await dialog.getByRole('tab', { name: 'Stalker', exact: true }).click();
// v0.22 redesign: tabs were replaced with a flat 5-card radio picker.
await dialog.getByRole('radio', { name: /Stalker portal/i }).click();
await setInputValue(dialog.locator('input#title'), name);
await setInputValue(dialog.locator('input#portalUrl'), PORTAL_URL);
+4 -1
View File
@@ -78,7 +78,10 @@ async function addXtreamPortal(
await page.getByRole('button', { name: 'Add playlist' }).click();
const dialog = page.locator('mat-dialog-container');
await expect(dialog).toBeVisible();
await dialog.getByRole('tab', { name: 'Xtream', exact: true }).click();
// v0.22 redesign: tabs were replaced with a flat 5-card radio picker.
await dialog
.getByRole('radio', { name: /Xtream credentials/i })
.click();
await dialog.locator('#title').fill(name);
await dialog.locator('#serverUrl').fill(MOCK_SERVER);