feat(fase-17): /settings About section opens ChangelogModal

Adds a discreet "Ver historial" text-button under the existing version
chip in `/settings` › About. The button toggles a local `showChangelog`
$state that drives the ChangelogModal mounted at the bottom of the
template, after every other modal so it stacks correctly.

Playwright CL-01 verifies the trigger → modal → CHANGELOG header path,
CL-02 verifies Escape closes the modal. Both pass against the bundled
?raw import (no fetch, exercises the production load path).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 01:20:00 +02:00
parent d11cf6ccef
commit f549dc53a2
2 changed files with 64 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
/**
* CL-series — Fase 17.4.2 (changelog modal on /settings).
*
* CL-01: clicking "Ver historial" in the About section opens the modal
* and the [v0.0.0-beta] heading is visible.
* CL-02: Escape closes the modal.
*
* The CHANGELOG content is bundled at build time via ?raw, so these
* assertions exercise the production load path (no fetch, no SSR).
*/
import { test, expect } from '@playwright/test';
import { USERS } from '../fixtures/users.js';
import { loginAs } from '../fixtures/login.js';
test.describe('Changelog modal', () => {
test('CL-01: opens from /settings About section and shows beta heading', async ({ page }) => {
await loginAs(page, USERS.ana);
await page.goto('/settings');
const trigger = page.getByTestId('settings-about-view-changelog');
await expect(trigger).toBeVisible({ timeout: 10_000 });
await trigger.click();
const modal = page.getByTestId('changelog-modal');
await expect(modal).toBeVisible({ timeout: 5_000 });
// The CHANGELOG header is parsed into an <h1 class="...">Changelog</h1>
// inside the body — the beta release heading is an <h2> with the
// literal string "[v0.0.0-beta] — 2026-05-19 — MVP + MVP2 (Fases 016)".
const body = page.getByTestId('changelog-modal-body');
await expect(body.getByRole('heading', { level: 1, name: 'Changelog' })).toBeVisible();
await expect(body.getByText(/v0\.0\.0-beta/)).toBeVisible();
});
test('CL-02: Escape closes the modal', async ({ page }) => {
await loginAs(page, USERS.ana);
await page.goto('/settings');
await page.getByTestId('settings-about-view-changelog').click();
const modal = page.getByTestId('changelog-modal');
await expect(modal).toBeVisible({ timeout: 5_000 });
await page.keyboard.press('Escape');
await expect(modal).toHaveCount(0, { timeout: 5_000 });
});
});