feat(admin,viewer,ui04): E06 management preview and v2 integration — real-component preview page, form mode fields, README

- viewer /embed-preview route: real EmbedStream with sample photography (picsum seeds), zero requests/WS (preview mode), postMessage config + simulated bursts through the real validation pipeline
- EmbedStream: preview prop (disables real WS subscription per §8.2 isolation) + exposed simulateBurst
- admin form: displayMode radio (new default), fixed 195x280 readonly, speed slider, reactions switch; v1 layout fields hidden in v2 (not silently effective)
- admin preview: v2 branch embeds the real preview iframe, white v2 handle, simulate-like tool button with sample-data note
- README-embed: v2 section (integration, hard sizing/docking, interactions/limits, artifact/version caching)
- tests: admin vitest 83 (+1 v2 placement), admin e2e 5 (v1 pinned carousel regression + full v2 chain incl. preview WYSIWYG heart and ov settings projection), viewer 244, v2 e2e 16

Note: part of the admin-side E06 changes (form/preview/utils/locales, mid-state of e2e spec) was swept into parallel commit eebf3b3 by a concurrent session's git add; this commit carries the final state of the remaining files and completes the set.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-22 18:20:50 +08:00
parent eebf3b3334
commit 3bba8d1dc5
7 changed files with 248 additions and 7 deletions
+11 -2
View File
@@ -224,12 +224,21 @@ test.describe.serial('embed slot management (P4b Task 5)', () => {
await expect(page.getByTestId('slot-form-interval')).toHaveCount(0)
await expect(page.getByTestId('slot-form-size')).toHaveCount(0)
// 真实组件预览(§8.2):iframe 挂载 + 模拟点赞按钮在工具区。
// 真实组件预览(§8.2):iframe 挂载 + 模拟点赞按钮在工具区;预览帧内为
// 真实 EmbedStream(.stream-viewport)且模拟点赞出心形(WYSIWYG 证据)。
await expect(page.getByTestId('embed-preview-v2-iframe')).toBeVisible()
await expect(page.getByTestId('embed-preview-sim-like')).toBeVisible()
const previewFrame = page
.frames()
.find((f) => f.url().includes('/embed-preview'))
expect(previewFrame).toBeDefined()
await expect(previewFrame!.locator('.stream-viewport')).toHaveCount(1)
await page.getByTestId('embed-preview-sim-like').click()
await expect(previewFrame!.locator('.heart').first()).toBeVisible({ timeout: 5_000 })
// 速度调整(24 px/s):滑轨点击定位((24-8)/(32-8)*180px ≈ 120)后断言值。
await page.getByTestId('slot-form-speed').click({ position: { x: 120, y: 10 } })
const runway = page.getByTestId('slot-form-speed').locator('.el-slider__runway')
await runway.click({ position: { x: 120, y: 4 } })
await expect(page.getByTestId('slot-form-speed-value')).toContainText('24')
await page.getByTestId('slot-form-submit').click()
await expect(page.getByTestId('slot-form-dialog')).toBeHidden()