|
| 1 | +import { describe, expect, it } from 'vitest' |
| 2 | +import { page } from 'vitest/browser' |
| 3 | +import { render } from 'vitest-browser-svelte' |
| 4 | +import type { PipelineThumb } from '$lib/services/pipelineManager' |
| 5 | +import List from './List.svelte' |
| 6 | + |
| 7 | +// List only reads `name` (for the label/filter) and `status` (for the status |
| 8 | +// dot) off each thumb, so a minimal stub is enough to exercise the search. |
| 9 | +const thumb = (name: string): PipelineThumb => |
| 10 | + ({ name, status: 'Stopped' }) as unknown as PipelineThumb |
| 11 | + |
| 12 | +const pipelines = [thumb('orders'), thumb('payments'), thumb('fraud-detection')] |
| 13 | + |
| 14 | +// Each rendered pipeline is an <a>; the only other interactive elements are the |
| 15 | +// search box and the close button, so counting links counts visible pipelines. |
| 16 | +const visibleNames = () => page.getByRole('link').elements().map((el) => el.textContent?.trim()) |
| 17 | + |
| 18 | +describe('pipeline list search', () => { |
| 19 | + it('lists every pipeline before any search term is entered', async () => { |
| 20 | + render(List, { pipelineName: '', pipelines }) |
| 21 | + |
| 22 | + await expect.element(page.getByText('orders')).toBeInTheDocument() |
| 23 | + await expect.element(page.getByText('payments')).toBeInTheDocument() |
| 24 | + await expect.element(page.getByText('fraud-detection')).toBeInTheDocument() |
| 25 | + expect(visibleNames()).toHaveLength(3) |
| 26 | + }) |
| 27 | + |
| 28 | + it('filters to pipelines whose name contains the search term', async () => { |
| 29 | + render(List, { pipelineName: '', pipelines }) |
| 30 | + |
| 31 | + await page.getByPlaceholder('Search pipelines...').fill('pay') |
| 32 | + |
| 33 | + await expect.element(page.getByText('payments')).toBeInTheDocument() |
| 34 | + await expect.element(page.getByText('orders')).not.toBeInTheDocument() |
| 35 | + await expect.element(page.getByText('fraud-detection')).not.toBeInTheDocument() |
| 36 | + expect(visibleNames()).toEqual(['payments']) |
| 37 | + }) |
| 38 | + |
| 39 | + it('matches case-insensitively', async () => { |
| 40 | + render(List, { pipelineName: '', pipelines }) |
| 41 | + |
| 42 | + await page.getByPlaceholder('Search pipelines...').fill('PAY') |
| 43 | + |
| 44 | + expect(visibleNames()).toEqual(['payments']) |
| 45 | + }) |
| 46 | + |
| 47 | + it('matches a substring anywhere in the name, not only a prefix', async () => { |
| 48 | + render(List, { pipelineName: '', pipelines }) |
| 49 | + |
| 50 | + await page.getByPlaceholder('Search pipelines...').fill('detect') |
| 51 | + |
| 52 | + expect(visibleNames()).toEqual(['fraud-detection']) |
| 53 | + }) |
| 54 | + |
| 55 | + it('shows no pipelines when the term matches nothing', async () => { |
| 56 | + render(List, { pipelineName: '', pipelines }) |
| 57 | + |
| 58 | + await page.getByPlaceholder('Search pipelines...').fill('no-such-pipeline') |
| 59 | + |
| 60 | + expect(visibleNames()).toHaveLength(0) |
| 61 | + }) |
| 62 | + |
| 63 | + it('restores the full list when the search term is cleared', async () => { |
| 64 | + render(List, { pipelineName: '', pipelines }) |
| 65 | + const search = page.getByPlaceholder('Search pipelines...') |
| 66 | + |
| 67 | + await search.fill('pay') |
| 68 | + expect(visibleNames()).toEqual(['payments']) |
| 69 | + |
| 70 | + await search.fill('') |
| 71 | + expect(visibleNames()).toHaveLength(3) |
| 72 | + }) |
| 73 | +}) |
0 commit comments