fix(e2e): fix category-management filter scoping and recent grid pagination

- category-management: replace filter({ has: dialog.locator(...) }) with
  filter({ hasText }) on the .category-item row. Playwright cannot scope an
  absolute locator (created via dialog.locator()) to each candidate element
  when used inside filter({ has: }), so the query always returned empty.
  Using hasText on the whole row correctly retries until Angular's @for loop
  re-renders filteredCategories() after the search field is populated.

- recent.e2e.ts Xtream test: same pagination fix as favorites — derive
  movieTitle and seriesTitle from waitForFirstGridListCardTitle() instead of
  pickDistinctTitles(fixture.items)[0], which may be on page 2 of the
  date-sorted grid and never visible.

https://claude.ai/code/session_01VU6ZZTG7YrhKhKBQvBfmpp
This commit is contained in:
Claude committed 2026-04-01 05:08:30 +00:00
1 parent 78a2dd3766
commit ffa5b59a5c
2 files changed
+10 -9

No files matched your search

@@ -158,15 +158,13 @@ async function toggleManagedCategory(
name: string;
}
): Promise<void> {
// Use Playwright's built-in filter so it retries until Angular re-renders
// the filtered list after the search field is populated.
// Use hasText on the whole row so Playwright's retry loop waits for Angular
// to re-render filteredCategories() after the search field is populated.
// Avoid nesting dialog.locator() inside filter({ has: }) — Playwright
// cannot scope an absolute locator to each candidate element.
const categoryRow = dialog
.locator('.category-item')
.filter({
has: dialog.locator('.category-name', {
hasText: targetCategory.name,
}),
})
.filter({ hasText: targetCategory.name })
.first();
await expect(categoryRow).toBeVisible({ timeout: 5000 });
+5 -2
View File
@@ -23,6 +23,7 @@ import {
switchUnifiedCollectionContent,
switchUnifiedCollectionScope,
test,
waitForFirstGridListCardTitle,
waitForM3uCatalog,
waitForStalkerCatalog,
waitForXtreamWorkspaceReady,
@@ -115,8 +116,6 @@ test.describe('Electron Recently Viewed', () => {
xtreamCredentials
);
const [liveTitle] = pickDistinctTitles(liveFixture.items, getXtreamTitle);
const [movieTitle] = pickDistinctTitles(vodFixture.items, getXtreamTitle);
const [seriesTitle] = pickDistinctTitles(seriesFixture.items, getXtreamTitle);
const portalTitle = 'Xtream Recent Source';
const app = await launchElectronApp(dataDir);
@@ -141,6 +140,9 @@ test.describe('Electron Recently Viewed', () => {
app.mainWindow,
vodFixture.categoryName
);
// Pick from the displayed grid: fixture order ≠ display order (date-desc
// sort + pagination), so the first fixture item may not be on page 1.
const movieTitle = await waitForFirstGridListCardTitle(app.mainWindow);
await clickGridListCardByTitle(app.mainWindow, movieTitle);
await playCurrentDetail(app.mainWindow);
await goBackFromDetail(app.mainWindow);
@@ -150,6 +152,7 @@ test.describe('Electron Recently Viewed', () => {
app.mainWindow,
seriesFixture.categoryName
);
const seriesTitle = await waitForFirstGridListCardTitle(app.mainWindow);
await clickGridListCardByTitle(app.mainWindow, seriesTitle);
await playFirstSeriesEpisode(app.mainWindow);