test(geschichten): cover multi-person AND filter end-to-end
Adds a Playwright flow that picks two persons through the typeahead, asserts both ?personId= params end up in the URL with two chips on screen, then removes the first chip and verifies only the second person id remains. Also extends .prettierignore so a stale root-owned test-results directory left over from running tests inside Docker doesn't break the pre-commit lint hook.
This commit is contained in:
@@ -23,5 +23,6 @@ bun.lockb
|
|||||||
|
|
||||||
# Test artifacts
|
# Test artifacts
|
||||||
/test-results/
|
/test-results/
|
||||||
|
/test-results.locked/
|
||||||
/e2e/.auth/
|
/e2e/.auth/
|
||||||
/coverage/
|
/coverage/
|
||||||
|
|||||||
@@ -62,6 +62,51 @@ test.describe('Geschichten — writer + reader journey', () => {
|
|||||||
await expect(page.locator('article')).toBeVisible();
|
await expect(page.locator('article')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('multi-person filter: chips, URL params, and AND removal work end-to-end', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
await page.goto('/geschichten');
|
||||||
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|
||||||
|
// We need two persons to filter by. Open the picker and pick one whose name
|
||||||
|
// the dev seed reliably contains. Then open the picker again and pick a
|
||||||
|
// second one. Picking is via the typeahead — we type, wait for the listbox,
|
||||||
|
// click the first option.
|
||||||
|
async function pickPerson(query: string) {
|
||||||
|
await page.getByRole('button', { name: /Person wählen/ }).click();
|
||||||
|
const input = page.getByRole('combobox', { name: /Person wählen/ });
|
||||||
|
await input.fill(query);
|
||||||
|
// Wait for at least one option in the listbox, then click it
|
||||||
|
const firstOption = page.getByRole('option').first();
|
||||||
|
await expect(firstOption).toBeVisible();
|
||||||
|
await firstOption.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
await pickPerson('a');
|
||||||
|
await page.waitForURL(/personId=/);
|
||||||
|
const firstUrl = new URL(page.url());
|
||||||
|
const firstIds = firstUrl.searchParams.getAll('personId');
|
||||||
|
expect(firstIds).toHaveLength(1);
|
||||||
|
|
||||||
|
await pickPerson('b');
|
||||||
|
await page.waitForURL((url) => url.searchParams.getAll('personId').length === 2);
|
||||||
|
const secondUrl = new URL(page.url());
|
||||||
|
const secondIds = secondUrl.searchParams.getAll('personId');
|
||||||
|
expect(secondIds).toHaveLength(2);
|
||||||
|
expect(secondIds[0]).toBe(firstIds[0]); // first one persists
|
||||||
|
expect(secondIds[1]).not.toBe(firstIds[0]); // second is different
|
||||||
|
|
||||||
|
// Two chips visible — find them by their remove-aria-label pattern
|
||||||
|
const chipButtons = page.getByRole('button', { name: /aus Filter entfernen/ });
|
||||||
|
await expect(chipButtons).toHaveCount(2);
|
||||||
|
|
||||||
|
// Remove the first chip — URL drops to one param
|
||||||
|
await chipButtons.first().click();
|
||||||
|
await page.waitForURL((url) => url.searchParams.getAll('personId').length === 1);
|
||||||
|
const finalIds = new URL(page.url()).searchParams.getAll('personId');
|
||||||
|
expect(finalIds).toEqual([secondIds[1]]);
|
||||||
|
});
|
||||||
|
|
||||||
test('AxeBuilder finds no critical violations on the index', async ({ page }) => {
|
test('AxeBuilder finds no critical violations on the index', async ({ page }) => {
|
||||||
await page.goto('/geschichten');
|
await page.goto('/geschichten');
|
||||||
await page.waitForSelector('[data-hydrated]');
|
await page.waitForSelector('[data-hydrated]');
|
||||||
|
|||||||
Reference in New Issue
Block a user