Files
minstrel/web/src/lib/components/TabStrip.test.ts
T
bvandeusenandClaude Opus 5.5 0f9ddbca97
release / go (push) Successful in 1m53s
release / govulncheck (push) Successful in 49s
release / web (push) Successful in 1m50s
release / android (push) Successful in 6m44s
release / Build signed APK (releases and dev) (push) Successful in 6m30s
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / integration (push) Canceled after 21m41s
feat(web): every paged list loads as you scroll; Liked becomes tabs (#5416)
Preference 172: no "Load more" buttons. Eight remained, on Liked (three
sections), the three Search overflow pages, Genres and Years.

- ListContinuation: the one bottom-of-list block. It loads the next page
  ahead of the reader, announces "Loading more…" through aria-live, shows an
  optional end line, and on a failed page shows the error with Try again,
  dropping the sentinel so a dead endpoint isn't re-hit on every scroll.
  Used on all ten paged lists, including the four that already autoloaded.
- A failed next page no longer replaces the list. TanStack sets isError for
  it, so the page-level error branches now apply only to a failed first
  load. Genres and Years did the same with their own loader; a later
  page's failure now keeps the grid.
- Liked: Artists | Albums | Tracks tabs (operator's choice). Stacked, a
  long Artists list loading as you scroll would bury the other two. It
  opens on the first tab that has likes.
- TabStrip: the in-page tab strip, now shared by Liked, Playback errors
  and Requests.
- test-utils/intersectionObserver: a stand-in so tests can scroll to the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:55:33 -04:00

26 lines
1.2 KiB
TypeScript

import { describe, expect, test } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte';
import TabStrip from './TabStrip.svelte';
const items = [
{ id: 'artists', label: 'Artists', count: 3 },
{ id: 'albums', label: 'Albums' }
];
describe('TabStrip', () => {
test('a tablist with the selected tab marked, and counts where given', () => {
render(TabStrip, { props: { items, value: 'artists', ariaLabel: 'Liked' } });
expect(screen.getByRole('tablist', { name: 'Liked' })).toBeInTheDocument();
expect(screen.getByRole('tab', { name: /artists/i })).toHaveAttribute('aria-selected', 'true');
expect(screen.getByRole('tab', { name: /albums/i })).toHaveAttribute('aria-selected', 'false');
expect(screen.getAllByTestId('tab-count').map((c) => c.textContent?.trim())).toEqual(['3']);
});
test('clicking a tab selects it', async () => {
render(TabStrip, { props: { items, value: 'artists', ariaLabel: 'Liked' } });
await fireEvent.click(screen.getByRole('tab', { name: /albums/i }));
expect(screen.getByRole('tab', { name: /albums/i })).toHaveAttribute('aria-selected', 'true');
expect(screen.getByRole('tab', { name: /artists/i })).toHaveAttribute('aria-selected', 'false');
});
});