From d09a355ab32c7985de5a102e735c05b0a8335150 Mon Sep 17 00:00:00 2001 From: quality Date: Sun, 4 Oct 2026 12:37:00 -0400 Subject: [PATCH] test: cover the industry and CNCF-project facet selects end to end /architectures ships three facet controls and only the organization one has ever been driven by a browser. The industry and project selects' onChange handlers (src/components/ArchitectureFilters/index.js lines 142 and 163) and filterArchitectures' two matching guards (lines 33 and 36) were reached by the unit suite's fake DOM alone, which cannot vouch for a select being wired to the setter its label claims. Adds the same select-narrow-clear cycle the organization facet already gets, for both remaining facets. No data overlay is needed: the catalog's alphabetically-first industry and project each match exactly one of its eight entries, so option index 1 takes both arms of each guard. Closes #1057 Signed-off-by: quality --- tests/e2e/interactions.spec.js | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/e2e/interactions.spec.js b/tests/e2e/interactions.spec.js index 79d2cd46..c8fcb30c 100644 --- a/tests/e2e/interactions.spec.js +++ b/tests/e2e/interactions.spec.js @@ -352,4 +352,54 @@ test.describe('reference architecture filters', () => { .toBe(total); await expect(search).toHaveValue(''); }); + + // The organization test above is the only facet a browser has ever driven, + // so filterArchitectures' industry and project guards and the two selects' + // onChange handlers are reached by the unit suite's fake DOM alone. Those + // are three separate select elements wired to three separate state setters, + // and nothing about one working implies the others do: a mismatched `id`, + // an option list built from the wrong field, or a handler bound to the + // wrong setter leaves the shipped toolbar inert on that facet while the + // organization test stays green. + for (const label of ['Filter by industry', 'Filter by CNCF project']) { + test(`${label.toLowerCase()} narrows the catalog and clears back`, async ({ + page, + }) => { + await page.goto('/architectures'); + const search = page.getByLabel( + 'Search architectures by organization or title', + ); + await waitForHydration(search); + + const results = page.getByText(/Showing \d+ of \d+ architectures/); + const total = totalCount(await results.textContent()); + expect(total).toBeGreaterThan(0); + + const select = page.getByLabel(label); + await expect(select).toHaveValue(''); + // Index 0 is the "All ..." placeholder, so the first real facet value + // is index 1. The option list is derived from the catalog, so a value + // here is also a value at least one architecture carries. + const value = await select.locator('option').nth(1).getAttribute('value'); + expect(value).toBeTruthy(); + await select.selectOption(value); + + // At least one architecture carries the value, and the catalog is wider + // than any single facet value, so the guard has to return false for some + // entries and true for others: a count strictly between 1 and the total. + await expect + .poll(async () => shownCount(await results.textContent())) + .toBeGreaterThan(0); + expect(shownCount(await results.textContent())).toBeLessThan(total); + + const clear = page.getByRole('button', { name: 'Clear filters' }); + await expect(clear).toBeVisible(); + await clear.click(); + + await expect + .poll(async () => shownCount(await results.textContent())) + .toBe(total); + await expect(select).toHaveValue(''); + }); + } });