/* shape-render.test.ts — 形状元素渲染回归(细条/装饰形状不被文字层污染) */ import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import ElementView from '../src/components/editor/ElementView.vue' import { store } from '../src/core/store' import type { SlideElement } from '../src/core/types' /** 目录页 t2:标题下方的细横条(rect 128×11.5px) */ const t2: SlideElement = { id: 't2', type: 'shape', x: 8, y: 23, w: 10, h: 1.6, content: '', style: { shapeType: 'rect', fill: 'accent', radius: 4, anim: 'fade-up' } } /** 步骤页 st4:步骤间的小三角 */ const st4: SlideElement = { id: 'st4', type: 'shape', x: 27.5, y: 40, w: 5, h: 0.8, content: '', style: { shapeType: 'triangle', fill: 'accent', anim: 'fade' } } describe('装饰形状渲染', () => { it('细横条 rect:编辑态渲染图形 div + 空 contenteditable 文字层,无占位文字', () => { const w = mount(ElementView, { props: { el: t2, bg: 'bg', edit: true }, attachTo: document.body }) const shape = w.find('.el-shape') expect(shape.exists()).toBe(true) expect(shape.attributes('style')).toContain('border-radius: 4px') const text = w.find('.el-shape-text') expect(text.exists()).toBe(true) // 编辑态保留可点击输入 expect(text.text()).toBe('') // 无占位文字 // 根节点暴露 data-shape 供 CSS 区分满幅/多边形安全区 expect(w.find('.el').attributes('data-shape')).toBe('rect') w.unmount() }) it('小三角 triangle:走 clip-path 分支,非正比框渲染', () => { const w = mount(ElementView, { props: { el: st4, bg: 'bg', edit: true }, attachTo: document.body }) const shape = w.find('.el-shape') expect(shape.attributes('style') || '').toContain('clip-path') w.unmount() }) it('非编辑态(模板预览):空 content 不渲染文字层', () => { const w = mount(ElementView, { props: { el: t2, bg: 'bg' }, attachTo: document.body }) expect(w.find('.el-shape-text').exists()).toBe(false) w.unmount() }) it('有文字的形状:非编辑态渲染 md 文字层且默认白字', () => { void store const el = { ...t2, h: 10, content: '**加粗**文字' } const w = mount(ElementView, { props: { el, bg: 'bg' }, attachTo: document.body }) const text = w.find('.el-shape-text') expect(text.exists()).toBe(true) expect(text.html()).toContain('加粗') expect(text.attributes('style') || '').toContain('rgb(255, 255, 255)') w.unmount() }) })