* feat(portals): rework the VOD sources popup and action row
The Sources popup now anchors above its button and always fits on screen:
the overlay caps it to the space beside the chip, only the source list
scrolls so the header, search, filter chips and footer stay visible, and
it flips below the button when the space above is too small. Filter chips
(All / Available / HD+ / language) compose with the playlist search, and
"Available" runs check-all itself when nothing has been checked yet.
Expanded copy rows no longer repeat the playlist domain: each copy shows
its parsed language chip, the provider's raw stream title, and only the
tags that differ from the parent copy.
Availability checks run at most four at a time and settled verdicts are
remembered per movie and source for ten minutes, so reopening a movie no
longer re-contacts every foreign portal.
Favorites and Download become icon-only buttons with real state: a filled
heart when favorited, and a download icon that turns into a progress ring
and then a checkmark that reveals the finished file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(portals): match the movie detail's icon-only favorite button
The Xtream movie detail's favorite control is now an icon-only button, so
the shared "add this detail to favorites" helpers no longer found it by
class. They are used against series and Stalker details too, which still
render the labeled variant, so they now select by accessible name — the
icon button carries the same label in aria-label.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(portals): keep provider playback for a downloaded movie
Once a movie is downloaded the primary button plays the local file, and
the sources popover only exists when another playlist carries the same
film. The icon-only rework left those as the only two paths, so a
downloaded movie in a single-playlist library had no way at all to stream
the provider's copy — the labeled action that used to do it was gone.
Restores it as an icon button beside the downloaded checkmark, under the
same condition the old one used.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Simplified expect statements for channel items and content cards in favorites and recent tests.
- Added new tests for opening Xtream favorite movies and series inline from favorites without switching playlists.
- Enhanced existing tests to ensure consistent behavior when navigating back from detail views.
- Introduced utility function expectInlineCollectionDetail to reduce code duplication in inline detail checks.
- Improved error handling for back button clicks in detail views.
Entire-Checkpoint: c6e522b4276c
Two separate root causes:
1. category-management.e2e.ts: openWorkspaceSection('Live TV') was not
awaited — pickSidebarCategory ran before the route settled on the live
section, so it read VOD categories from the stale sidebar (e.g. 'Action'
instead of a live category). The manage-categories dialog opens for the
live section, so searching for a VOD name found nothing.
Fix: add waitForURL(/\/workspace\/xtreams\/[^/]+\/live/) after both
openWorkspaceSection('Live TV') calls.
2. recent.e2e.ts / favorites.e2e.ts: waitForFirstGridListCardTitle read
the first card's title, but clickGridListCardByTitle then did a fresh
DOM search by that title. Between those two calls the grid could
re-sort/paginate, making the card unfindable.
Fix: new clickFirstGridListCard helper atomically reads the title and
clicks the same card reference, replacing the two-step pattern.
https://claude.ai/code/session_01VU6ZZTG7YrhKhKBQvBfmpp
- toggleManagedCategory: replace manual count-loop with Playwright filter so
the locator retries internally until Angular re-renders the filtered list
after the search field is populated (previously called .count() before the
@for loop had reacted to the updated searchTerm signal)
- favorites Xtream test: pick movie/series titles from the first displayed
grid card instead of vodFixture.items[0]. The grid sorts by date-desc and
paginates at 25 items; the first API item may land on page 2 making
clickGridListCardByTitle time out with "element not found". Reading the
title from the DOM after navigation ensures we always target a visible card.
- electron-test-fixtures: export waitForFirstGridListCardTitle helper
https://claude.ai/code/session_01VU6ZZTG7YrhKhKBQvBfmpp
- Implemented tests for tracking recently viewed channels in M3U playlists, ensuring they persist across app restarts.
- Added functionality to manage Xtream and Stalker history, including support for clearing recent items.
- Enhanced settings tests to verify persistence of user preferences across app restarts, including language, video player, and theme settings.
- Created comprehensive tests for managing sources, including filtering, sorting, editing, and deleting M3U, Xtream, and Stalker sources.
- Introduced mock fixtures for Xtream and Stalker categories to facilitate testing.