feat(v2): boot /v2/dashboard through OrganizerLayoutV2 + AppShellV2

Replaces the Task 3 stub in pages-v2/dashboard.vue with the boot-proof
page (data-testid v2-dashboard, correct definePage meta). Adds the
Playwright CT smoke (appshell-boot.spec.ts) that mounts AppShellV2 in
Chromium and asserts both the shell root and slot content are visible;
uses page scope for the root-element assertion (CT component locator
only matches descendants, not the root itself). Full Plan-1 gate green:
typecheck 0 new errors, eslint clean, 5 vitest files / 21 tests + 2
component tests, vite build succeeded, typed-router has v2-dashboard.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 11:57:41 +02:00
parent 31f5a7c4f0
commit 6a45d86b6f
2 changed files with 30 additions and 3 deletions

View File

@@ -1,9 +1,17 @@
<script setup lang="ts">
// First v2 page — boot proof (RFC-WS-GUI-REDESIGN Plan 1). `public`
// keeps it reachable without auth wiring during the foundation slice;
// it is removed when the real dashboard lands in a later plan.
definePage({ meta: { layout: 'OrganizerLayoutV2', public: true } })
</script>
<template>
<div data-testid="v2-dashboard-placeholder">
v2 dashboard
</div>
<section data-testid="v2-dashboard">
<h1 class="text-xl font-semibold text-surface-900 dark:text-surface-0">
v2 foundation OK
</h1>
<p class="mt-2 text-surface-600 dark:text-surface-300">
AppShellV2 skeleton renders this route at /v2/dashboard.
</p>
</section>
</template>

View File

@@ -0,0 +1,19 @@
import { expect, test } from '@playwright/experimental-ct-vue'
import AppShellV2 from '@/layouts/components/AppShellV2.vue'
// Pinia is set up globally by playwright/index.ts's beforeMount hook
// (createPinia per test). We do NOT use @pinia/testing's
// createTestingPinia here: it requires Vitest's `vi.fn`, which is
// absent in Playwright's Node runtime. See playwright/index.ts §Pinia.
test('AppShellV2 mounts and renders content in the CT runner', async ({ mount, page }) => {
await mount(AppShellV2, {
slots: { default: '<section data-testid="v2-dashboard">v2 foundation OK</section>' },
})
// `data-testid="appshell-v2"` is on the component's own root element,
// so we query the page rather than the component locator (which only
// matches descendants of the root, not the root itself in CT).
await expect(page.getByTestId('appshell-v2')).toBeVisible()
await expect(page.getByTestId('v2-dashboard')).toContainText('v2 foundation OK')
})