test(e2e): replace unchecked lookups, widen the assertion timeout, restore the skipped test (#241)

Tasks 2 to 4 of the plan. Nine `collection.find(...)` dereferences become findOrFail, so a missing row fails as a named assertion naming what was wanted and how many rows were searched, rather than "Cannot read properties of undefined" pointing at test plumbing. Where the old code followed the lookup with expect(x).toBeTruthy(), that assertion is dropped: findOrFail already guarantees it, and with a better message.

The expect timeout goes from Playwright's default 5s to 10s. It costs nothing on a green run — it bounds how long a failing assertion waits, not how long a passing one takes — and #239 died reporting exactly Timeout: 5000ms on a runner that also builds, migrates and runs three other suites.

The admin-save happy path comes back from the #245 skip. It is the only end-to-end check that adding an item reaches the database rather than merely firing a toast, and it passed both full parallel runs and in isolation.

filters.spec.ts:216 is deliberately untouched: its .find() searches CSS class names on a string array, not test data, and has no missing-row failure mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-31 20:04:43 -05:00
co-authored by Claude Opus 5
parent 93a451dbf0
commit 895c08d1a7
7 changed files with 69 additions and 33 deletions
+21 -5
View File
@@ -1,4 +1,4 @@
import { test, expect, uniqueSuffix } from './fixtures';
import { test, expect, uniqueSuffix, findOrFail } from './fixtures';
// Each test leaves the templates as it found them, because they are stored in
// admin_settings and would otherwise change the copy a later test reads.
@@ -51,7 +51,11 @@ test.describe('Editing the customer emails', () => {
// Persisted, not merely accepted by the form.
const stored = await (await page.request.get('/api/admin/email-templates')).json();
const reset = stored.find((t: { key: string }) => t.key === 'passwordReset');
const reset = findOrFail(
stored,
(t: { key: string }) => t.key === 'passwordReset',
'the passwordReset template'
);
expect(reset.subject).toBe(subject);
});
@@ -69,7 +73,11 @@ test.describe('Editing the customer emails', () => {
// And nothing was stored.
const stored = await (await page.request.get('/api/admin/email-templates')).json();
const reset = stored.find((t: { key: string }) => t.key === 'passwordReset');
const reset = findOrFail(
stored,
(t: { key: string }) => t.key === 'passwordReset',
'the passwordReset template'
);
expect(reset.body).toBeNull();
});
@@ -88,7 +96,11 @@ test.describe('Editing the customer emails', () => {
await expect(page.getByText('Password reset restored to the default')).toBeVisible();
const stored = await (await page.request.get('/api/admin/email-templates')).json();
const reset = stored.find((t: { key: string }) => t.key === 'passwordReset');
const reset = findOrFail(
stored,
(t: { key: string }) => t.key === 'passwordReset',
'the passwordReset template'
);
expect(reset.subject).toBeNull();
expect(reset.body).toBeNull();
});
@@ -113,7 +125,11 @@ test.describe('Previewing the customer emails', () => {
await expect(adminEmails.preview('Password reset').getByText(wording)).toBeVisible();
const stored = await (await page.request.get('/api/admin/email-templates')).json();
expect(stored.find((t: { key: string }) => t.key === 'passwordReset').body).toBeNull();
expect(findOrFail(
stored,
(t: { key: string }) => t.key === 'passwordReset',
'the passwordReset template'
).body).toBeNull();
});
test('substitutes sample values rather than showing raw placeholders', async ({ page, admin, adminEmails }) => {