Every catalog-listed control on the admin surfaces carries an accessible deviation marking in mode marked: text + icon under the control (never colour alone), part of the control's accessible description (aria-describedby), i18n de+en. The check runs against the CURRENT control value, so a violating choice is marked before saving. Covered controls: registration mode, new-page classification, upload policy, SVG policy, the four master switches (api/mcp/feeds/plugins), the legal texts (violating while empty), and the Nextcloud backup toggle on the system panel. The profile card (#243) gains the warning summary and the hardening-guide reference. e2e: new vs-nfd-marking pack (marked half in CI — the e2e api now runs VS_NFD_MODE=marked, which also puts the marked state into the a11y admin scan; off half in local default runs; both halves verified live). hidden/enforced follow in #245/#246. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
61 lines
2.6 KiB
TypeScript
61 lines
2.6 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
import { contextForUser } from './helpers';
|
|
|
|
/**
|
|
* VS-NfD marking pack (issue #244): in mode `marked`, catalog-listed
|
|
* controls carry an accessible deviation marking that follows the CURRENT
|
|
* (unsaved) value; in mode `off` nothing is marked anywhere. The api's
|
|
* mode is deploy-level, so each half runs only against the matching stack:
|
|
* CI runs the marked half (VS_NFD_MODE=marked on the e2e api), local full
|
|
* runs against a default stack cover the off half.
|
|
*/
|
|
const BASE_URL = process.env.E2E_BASE_URL ?? 'http://localhost:5173';
|
|
const MODE = process.env.E2E_VS_NFD_MODE ?? 'off';
|
|
|
|
test('mode marked: card, checkbox marking, and point-of-choice marking', async ({ browser }) => {
|
|
test.skip(MODE !== 'marked', 'needs an api started with VS_NFD_MODE=marked');
|
|
const context = await contextForUser(browser, BASE_URL, 'fixture-admin');
|
|
const page = await context.newPage();
|
|
await page.goto('/admin');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// The profile card shows mode and violation count (issue #243).
|
|
await expect(page.locator('.vs-nfd-summary')).toBeVisible();
|
|
|
|
// feeds.enabled defaults to true = violating: its toggle row is marked,
|
|
// and the marking is part of the control's accessible description.
|
|
const feedsInput = page.locator('input[aria-describedby="vs-nfd-mark-feeds.enabled"]');
|
|
await expect(feedsInput).toBeVisible();
|
|
await expect(page.locator('#vs-nfd-mark-feeds\\.enabled')).toBeVisible();
|
|
|
|
// Point of choice: the registration-mode marking follows the UNSAVED
|
|
// select value — compliant choice clears it, violating choice brings it
|
|
// back, no save in between.
|
|
const regField = page.locator('label.field', {
|
|
has: page.locator('select[name="auth.registrationMode"]'),
|
|
});
|
|
const regSelect = regField.locator('select');
|
|
await regSelect.selectOption('open');
|
|
await expect(regField.locator('.vs-nfd-mark')).toBeVisible();
|
|
await regSelect.selectOption('closed');
|
|
await expect(regField.locator('.vs-nfd-mark')).toHaveCount(0);
|
|
await regSelect.selectOption('open');
|
|
await expect(regField.locator('.vs-nfd-mark')).toBeVisible();
|
|
|
|
await context.close();
|
|
});
|
|
|
|
test('mode off: no card, no markings', async ({ browser }) => {
|
|
test.skip(MODE !== 'off', 'covers the default stack only');
|
|
const context = await contextForUser(browser, BASE_URL, 'fixture-admin');
|
|
const page = await context.newPage();
|
|
await page.goto('/admin');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
await expect(page.locator('.vs-nfd-summary')).toHaveCount(0);
|
|
await expect(page.locator('.vs-nfd-mark')).toHaveCount(0);
|
|
|
|
await context.close();
|
|
});
|