mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 13:46:16 -08:00
fix(ui): keep detail back navigation available while scrolling (#1576)
This commit is contained in:
1 parent
e76447975b
commit
fff022afe4
28 files changed
+679
-138
No files matched your search
@@ -590,9 +590,12 @@ async function firstVisibleGridTitle(page: Page): Promise<string> {
|
||||
}
|
||||
|
||||
async function goBackFromDetail(page: Page): Promise<void> {
|
||||
// Return to the list: browse uses the sticky Back, watch uses the
|
||||
// now-playing bar's direct Back (the sticky watch action is Close player).
|
||||
const backButton = page
|
||||
.locator('app-content-hero .hero__back-button')
|
||||
.first();
|
||||
.locator('app-portal-detail-shell')
|
||||
.first()
|
||||
.getByRole('button', { name: 'Back', exact: true });
|
||||
|
||||
await expect(backButton).toBeVisible({ timeout: 20000 });
|
||||
try {
|
||||
|
||||
@@ -97,7 +97,10 @@ test.describe('Dashboard Activation', () => {
|
||||
await app.mainWindow
|
||||
.getByTestId('dashboard-favorite-vod-rail-manage-all')
|
||||
.click();
|
||||
await expectPathname(app.mainWindow, /\/workspace\/global-favorites$/);
|
||||
await expectPathname(
|
||||
app.mainWindow,
|
||||
/\/workspace\/global-favorites$/
|
||||
);
|
||||
await expectVisibleContentCardTitle(app.mainWindow, movieTitle);
|
||||
|
||||
await app.mainWindow.goBack();
|
||||
@@ -223,7 +226,10 @@ const xtreamCredentials = {
|
||||
password: defaultXtreamPassword,
|
||||
};
|
||||
|
||||
async function expectDashboardRail(page: Page, railTestId: string): Promise<void> {
|
||||
async function expectDashboardRail(
|
||||
page: Page,
|
||||
railTestId: string
|
||||
): Promise<void> {
|
||||
await expect(page.locator(`[data-test-id="${railTestId}"]`)).toBeVisible({
|
||||
timeout: 20000,
|
||||
});
|
||||
@@ -234,15 +240,21 @@ function dashboardRailCardByTitle(
|
||||
railTestId: string,
|
||||
title: string
|
||||
) {
|
||||
return page.locator(`[data-test-id="${railTestId}-card"]`).filter({
|
||||
hasText: title,
|
||||
}).first();
|
||||
return page
|
||||
.locator(`[data-test-id="${railTestId}-card"]`)
|
||||
.filter({
|
||||
hasText: title,
|
||||
})
|
||||
.first();
|
||||
}
|
||||
|
||||
async function goBackFromDetail(page: Page): Promise<void> {
|
||||
// Return to the list: browse uses the sticky Back, watch uses the
|
||||
// now-playing bar's direct Back (the sticky watch action is Close player).
|
||||
const backButton = page
|
||||
.locator('app-content-hero .hero__back-button')
|
||||
.first();
|
||||
.locator('app-portal-detail-shell')
|
||||
.first()
|
||||
.getByRole('button', { name: 'Back', exact: true });
|
||||
|
||||
await expect(backButton).toBeVisible({ timeout: 20000 });
|
||||
try {
|
||||
@@ -282,7 +294,7 @@ async function expectInlineCollectionDetail(
|
||||
await expect(page.locator('app-workspace-context-panel')).toHaveCount(0);
|
||||
await expect(page.locator('app-content-hero')).toContainText(params.title);
|
||||
await expect(
|
||||
page.locator('app-content-hero .hero__back-button').first()
|
||||
page.locator('app-portal-detail-shell .shell__back-button').first()
|
||||
).toBeVisible({ timeout: 20000 });
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,10 @@ test.describe('Electron Favorites', () => {
|
||||
});
|
||||
|
||||
await goBackFromDetail(app.mainWindow);
|
||||
await expectPathname(app.mainWindow, /\/workspace\/global-favorites$/);
|
||||
await expectPathname(
|
||||
app.mainWindow,
|
||||
/\/workspace\/global-favorites$/
|
||||
);
|
||||
await expectVisibleContentCardTitle(app.mainWindow, movieTitle);
|
||||
|
||||
await switchUnifiedCollectionContent(app.mainWindow, 'Series');
|
||||
@@ -366,7 +369,10 @@ test.describe('Electron Favorites', () => {
|
||||
});
|
||||
|
||||
await goBackFromDetail(app.mainWindow);
|
||||
await expectPathname(app.mainWindow, /\/workspace\/global-favorites$/);
|
||||
await expectPathname(
|
||||
app.mainWindow,
|
||||
/\/workspace\/global-favorites$/
|
||||
);
|
||||
await switchUnifiedCollectionContent(app.mainWindow, 'Series');
|
||||
await expectVisibleContentCardTitle(app.mainWindow, seriesTitle);
|
||||
} finally {
|
||||
@@ -545,7 +551,10 @@ test.describe('Electron Favorites', () => {
|
||||
await expectInlinePlayerWithoutDialog(app.mainWindow);
|
||||
|
||||
await goBackFromDetail(app.mainWindow);
|
||||
await expectPathname(app.mainWindow, /\/workspace\/global-favorites$/);
|
||||
await expectPathname(
|
||||
app.mainWindow,
|
||||
/\/workspace\/global-favorites$/
|
||||
);
|
||||
await expectVisibleContentCardTitle(app.mainWindow, movieTitle);
|
||||
|
||||
await switchUnifiedCollectionContent(app.mainWindow, 'Series');
|
||||
@@ -562,7 +571,10 @@ test.describe('Electron Favorites', () => {
|
||||
await expectInlinePlayerWithoutDialog(app.mainWindow);
|
||||
|
||||
await goBackFromDetail(app.mainWindow);
|
||||
await expectPathname(app.mainWindow, /\/workspace\/global-favorites$/);
|
||||
await expectPathname(
|
||||
app.mainWindow,
|
||||
/\/workspace\/global-favorites$/
|
||||
);
|
||||
await switchUnifiedCollectionContent(app.mainWindow, 'Series');
|
||||
await expectVisibleContentCardTitle(app.mainWindow, seriesTitle);
|
||||
} finally {
|
||||
@@ -594,9 +606,12 @@ async function addCurrentDetailToFavorites(page: Page): Promise<void> {
|
||||
}
|
||||
|
||||
async function goBackFromDetail(page: Page): Promise<void> {
|
||||
// Return to the list: browse uses the sticky Back, watch uses the
|
||||
// now-playing bar's direct Back (the sticky watch action is Close player).
|
||||
const backButton = page
|
||||
.locator('app-content-hero .hero__back-button')
|
||||
.first();
|
||||
.locator('app-portal-detail-shell')
|
||||
.first()
|
||||
.getByRole('button', { name: 'Back', exact: true });
|
||||
|
||||
await expect(backButton).toBeVisible({ timeout: 20000 });
|
||||
try {
|
||||
@@ -623,7 +638,7 @@ async function expectInlineCollectionDetail(
|
||||
await expect(page.locator('app-workspace-context-panel')).toHaveCount(0);
|
||||
await expect(page.locator('app-content-hero')).toContainText(params.title);
|
||||
await expect(
|
||||
page.locator('app-content-hero .hero__back-button').first()
|
||||
page.locator('app-portal-detail-shell .shell__back-button').first()
|
||||
).toBeVisible({ timeout: 20000 });
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,9 @@ test.describe('Electron Recently Viewed', () => {
|
||||
'Stable Recent Channel'
|
||||
).first();
|
||||
const livePlayer = app.mainWindow
|
||||
.locator('app-unified-live-tab .content-container .video-player')
|
||||
.locator(
|
||||
'app-unified-live-tab .content-container .video-player'
|
||||
)
|
||||
.first();
|
||||
|
||||
await item.click();
|
||||
@@ -129,7 +131,10 @@ test.describe('Electron Recently Viewed', () => {
|
||||
.poll(() => visibleLiveTitles(app.mainWindow))
|
||||
.toEqual(['Recent Channel Two', 'Recent Channel One']);
|
||||
|
||||
await toggleFavoriteForChannel(app.mainWindow, 'Recent Channel Two');
|
||||
await toggleFavoriteForChannel(
|
||||
app.mainWindow,
|
||||
'Recent Channel Two'
|
||||
);
|
||||
await expect
|
||||
.poll(() => visibleLiveTitles(app.mainWindow))
|
||||
.toEqual(['Recent Channel Two', 'Recent Channel One']);
|
||||
@@ -648,9 +653,12 @@ async function expectUnifiedLiveDetailOpen(
|
||||
}
|
||||
|
||||
async function goBackFromDetail(page: Page): Promise<void> {
|
||||
// Return to the list: browse uses the sticky Back, watch uses the
|
||||
// now-playing bar's direct Back (the sticky watch action is Close player).
|
||||
const backButton = page
|
||||
.locator('app-content-hero .hero__back-button')
|
||||
.first();
|
||||
.locator('app-portal-detail-shell')
|
||||
.first()
|
||||
.getByRole('button', { name: 'Back', exact: true });
|
||||
|
||||
await expect(backButton).toBeVisible({ timeout: 20000 });
|
||||
try {
|
||||
@@ -677,7 +685,7 @@ async function expectInlineCollectionDetail(
|
||||
await expect(page.locator('app-workspace-context-panel')).toHaveCount(0);
|
||||
await expect(page.locator('app-content-hero')).toContainText(params.title);
|
||||
await expect(
|
||||
page.locator('app-content-hero .hero__back-button').first()
|
||||
page.locator('app-portal-detail-shell .shell__back-button').first()
|
||||
).toBeVisible({ timeout: 20000 });
|
||||
}
|
||||
|
||||
|
||||
@@ -1540,9 +1540,12 @@ async function addCurrentDetailToFavorites(page: Page): Promise<void> {
|
||||
}
|
||||
|
||||
async function goBackFromDetail(page: Page): Promise<void> {
|
||||
// Return to the list: browse uses the sticky Back, watch uses the
|
||||
// now-playing bar's direct Back (the sticky watch action is Close player).
|
||||
const backButton = page
|
||||
.locator('app-content-hero .hero__back-button')
|
||||
.first();
|
||||
.locator('app-portal-detail-shell')
|
||||
.first()
|
||||
.getByRole('button', { name: 'Back', exact: true });
|
||||
|
||||
await expect(backButton).toBeVisible({ timeout: 20000 });
|
||||
await backButton.click();
|
||||
|
||||
@@ -135,6 +135,46 @@ test.describe('Xtream VOD Details', () => {
|
||||
});
|
||||
|
||||
for (const theme of ['light', 'dark']) {
|
||||
test(`detail action tooltips preserve one-press Escape (${theme})`, async ({
|
||||
dataDir,
|
||||
request,
|
||||
}) => {
|
||||
await resetMockServers(request, ['xtream']);
|
||||
const app = await launchElectronApp(dataDir);
|
||||
try {
|
||||
const page = app.mainWindow;
|
||||
await addXtreamPortal(page);
|
||||
await waitForXtreamWorkspaceReady(page);
|
||||
await page
|
||||
.getByRole('link', { name: 'Movies', exact: true })
|
||||
.click();
|
||||
await page.evaluate(
|
||||
(dark) => document.body.classList.toggle('dark-theme', dark),
|
||||
theme === 'dark'
|
||||
);
|
||||
for (const action of [
|
||||
'vod-favorite-toggle',
|
||||
'vod-download-start',
|
||||
]) {
|
||||
await page.locator('app-grid-list mat-card').first().click();
|
||||
const shell = page.locator('app-portal-detail-shell');
|
||||
await expect(
|
||||
shell.getByRole('heading', { level: 1 })
|
||||
).toBeVisible();
|
||||
const button = shell.locator(`[data-testid="${action}"]`);
|
||||
await button.focus();
|
||||
await button.hover();
|
||||
await expect(
|
||||
page.locator('.mat-mdc-tooltip-show')
|
||||
).toBeVisible();
|
||||
await page.keyboard.press('Escape');
|
||||
await expect(shell).toHaveCount(0);
|
||||
}
|
||||
} finally {
|
||||
await closeElectronApp(app);
|
||||
}
|
||||
});
|
||||
|
||||
test(`supports keyboard and mouse scrolling in portal details (${theme})`, async ({
|
||||
dataDir,
|
||||
request,
|
||||
@@ -188,7 +228,9 @@ for (const theme of ['light', 'dark']) {
|
||||
.poll(() => shell.evaluate((el) => el.scrollTop))
|
||||
.toBeGreaterThan(0);
|
||||
await page.keyboard.press('Tab');
|
||||
await expect(shell.locator('.hero__back-button')).toBeFocused();
|
||||
await expect(
|
||||
shell.locator('.shell__back-button')
|
||||
).toBeFocused();
|
||||
await page.keyboard.press('Enter');
|
||||
await expect(shell).toHaveCount(0);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user