All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 6m58s
CI / Build container images (pull_request) Successful in 1m26s
CI / Auth e2e pack (pull_request) Successful in 9m7s
CI / Import/export fidelity gate (pull_request) Successful in 1m2s
CD / Build and push images (push) Successful in 13s
CD / Deploy to Test (push) Successful in 14s
CI / Lint, typecheck, test (push) Successful in 7m31s
CI / Build container images (push) Has been skipped
CD / Smoke tests against Test (push) Successful in 1m24s
CD / Promote to Int (push) Successful in 13s
CI / Auth e2e pack (push) Successful in 9m25s
CI / Import/export fidelity gate (push) Successful in 55s
useDocumentTitle pinned APP_NAME = 'Dorfteich', so every route title — tab, bookmarks, the window title a screen reader announces (WCAG 2.4.2) — named the product instead of the operator's instance. The trailing name now comes from the public branding query, exactly like the TopBar brand (#306); until the query resolves (or when it cannot, e.g. maintenance mode) the shipped default keeps the title stable, so an untouched instance reads exactly as before. The static index.html title stays the pre-JS placeholder — server-rendering it is #179's territory, deliberately out of scope (recorded in the issue). The admin-settings e2e now also asserts the title carries the new name right after saving, without a reload. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017aviRTgWCcAHUh1SBoxf6P
56 lines
2.4 KiB
TypeScript
56 lines
2.4 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
import { contextForUser } from './helpers';
|
|
|
|
const BASE_URL = process.env.E2E_BASE_URL ?? 'http://localhost:5173';
|
|
|
|
/**
|
|
* The general admin settings card saves THROUGH THE FORM (issue #322).
|
|
*
|
|
* This must drive the UI, not the api: the bug it fences was invisible to
|
|
* every api-level test — react-hook-form nested the dotted field names on
|
|
* input, the strict PATCH schema rejected the body, and the form looked
|
|
* fine while never saving. Verified end to end: success message, the value
|
|
* survives a full reload, the api returns it, and the TopBar picks it up
|
|
* without a reload (branding query invalidation).
|
|
*/
|
|
test('instance name changed in the general settings form persists', async ({ browser }) => {
|
|
const admin = await contextForUser(browser, BASE_URL, 'fixture-admin');
|
|
const before = (
|
|
(await (await admin.request.get('/api/v1/admin/settings')).json()) as Record<string, unknown>
|
|
)['instance.name'] as string;
|
|
const newName = `Renamed ${Date.now()}`;
|
|
|
|
const nameLabel = /^(Instance name|Name der Instanz)$/;
|
|
const page = await admin.newPage();
|
|
try {
|
|
await page.goto('/admin');
|
|
const generalCard = page
|
|
.locator('section.settings-section')
|
|
.filter({ has: page.getByLabel(nameLabel) });
|
|
await page.getByLabel(nameLabel).fill(newName);
|
|
await generalCard.getByRole('button', { name: /^(Save|Speichern)$/ }).click();
|
|
// Scoped to the card: the page has several forms with status regions.
|
|
await expect(generalCard.getByRole('status')).toHaveText(/^(Saved\.|Gespeichert\.)$/);
|
|
|
|
// The TopBar and the document title show the new name without a reload —
|
|
// the save invalidates the branding query both read from (issue #323).
|
|
await expect(page.locator('.topbar__brand')).toHaveText(newName);
|
|
await expect(page).toHaveTitle(new RegExp(`${newName}$`));
|
|
|
|
// The proof the form really persisted: the value survives a reload and
|
|
// the api returns it.
|
|
await page.reload();
|
|
await expect(page.getByLabel(nameLabel)).toHaveValue(newName);
|
|
const stored = (
|
|
(await (await admin.request.get('/api/v1/admin/settings')).json()) as Record<string, unknown>
|
|
)['instance.name'];
|
|
expect(stored).toBe(newName);
|
|
} finally {
|
|
await admin.request.patch('/api/v1/admin/settings', {
|
|
data: { 'instance.name': before },
|
|
});
|
|
await admin.close();
|
|
}
|
|
});
|