feat: 收口移动端侧栏与创作拆解页布局
This commit is contained in:
@@ -31,6 +31,9 @@ describe('管理后台组件边界', () => {
|
||||
expect(css).toMatch(/\.workspace-tabs > \.n-tabs-nav\s*\{[^}]*align-items:\s*stretch;/)
|
||||
expect(css).toMatch(/\.workspace-tabs \.n-tabs-nav__suffix\s*\{[^}]*align-items:\s*center;/)
|
||||
expect(css).toMatch(/\.tabs-toolbar-actions\s*\{[^}]*align-items:\s*center;[^}]*min-height:\s*40px;/)
|
||||
expect(css).toMatch(
|
||||
/\.tabs-toolbar-actions \.n-button\.icon-button\s*\{[^}]*width:\s*32px;[^}]*min-width:\s*32px;[^}]*height:\s*32px;[^}]*padding:\s*0/
|
||||
)
|
||||
expect(css).toContain('@container tabs-toolbar (max-width: 600px)')
|
||||
expect(css).not.toContain('.result-toolbar > .n-button')
|
||||
})
|
||||
@@ -82,7 +85,9 @@ describe('管理后台组件边界', () => {
|
||||
expect(css).toMatch(
|
||||
/\.breakdown-results-section > \.content-with-history\s*\{[^}]*flex:\s*1;[^}]*height:\s*auto;[^}]*min-height:\s*0;[^}]*grid-template-rows:\s*minmax\(0, 1fr\)/
|
||||
)
|
||||
expect(css).toContain('grid-template-rows: minmax(0, 1fr) min(25%, 130px)')
|
||||
expect(css).toMatch(
|
||||
/@media \(max-width: 800px\)[\s\S]*?\.breakdown-results-section \.content-with-history:not\(\.history-hidden\) \.history-panel\s*\{[^}]*inset:\s*0/
|
||||
)
|
||||
expect(css).toMatch(/\.panel-scroll\.n-scrollbar\s*\{[^}]*height:\s*100%;[^}]*min-height:\s*0/)
|
||||
})
|
||||
it('标题与内容使用各自滚动容器,不随正文一起滚动', () => {
|
||||
@@ -173,6 +178,9 @@ describe('管理后台组件边界', () => {
|
||||
expect(css).toMatch(/\.admin-sider\s*\{[^}]*display:\s*flex;[^}]*flex-direction:\s*column;[^}]*height:\s*100%/)
|
||||
expect(css).toMatch(/\.admin-nav-scroll\.n-scrollbar\s*\{[^}]*flex:\s*1;[^}]*min-height:\s*0/)
|
||||
expect(css).toMatch(/\.admin-sider-footer\s*\{[^}]*flex-shrink:\s*0/)
|
||||
expect(css).toMatch(/\.n-button\.admin-settings-button\.is-collapsed\s*\{[^}]*justify-content:\s*center/)
|
||||
expect(css).toMatch(/\.admin-brand\.is-collapsed\s*\{[^}]*justify-content:\s*center/)
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.admin-brand\s*\{[^}]*height:\s*48px/)
|
||||
expect(css).toContain('@media (max-width: 800px)')
|
||||
expect(css).toMatch(/transition:\s*width\s+0\.32s/)
|
||||
expect(css).toContain('calc(100% - var(--admin-sider-collapsed))')
|
||||
@@ -219,22 +227,41 @@ describe('管理后台组件边界', () => {
|
||||
await flushPromises()
|
||||
expect(wrapper.findAll('.admin-sider')).toHaveLength(1)
|
||||
expect(wrapper.get('.admin-sider').classes()).toContain('is-collapsed')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 64px')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 48px')
|
||||
expect(wrapper.find('.admin-sider-mask').exists()).toBe(false)
|
||||
expect(wrapper.find('.admin-nav-drawer').exists()).toBe(false)
|
||||
expect(wrapper.getComponent(NMenu).props()).toMatchObject({
|
||||
collapsedWidth: 48,
|
||||
indent: 14,
|
||||
rootIndent: 14
|
||||
})
|
||||
const collapsedBrand = wrapper.get('.admin-brand')
|
||||
expect(collapsedBrand.classes()).toContain('is-collapsed')
|
||||
expect(collapsedBrand.text()).toBe('')
|
||||
const collapsedSettings = wrapper.get('.admin-sider-footer [aria-label="后端连接"]')
|
||||
expect(collapsedSettings.text()).toBe('')
|
||||
expect(collapsedSettings.classes()).toContain('is-collapsed')
|
||||
await wrapper.get('[aria-label="展开侧栏"]').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.findAll('.admin-sider')).toHaveLength(1)
|
||||
expect(wrapper.get('.admin-sider').classes()).not.toContain('is-collapsed')
|
||||
expect(wrapper.get('.admin-sider').classes()).not.toContain('is-overlay')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 208px')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 168px')
|
||||
expect(wrapper.find('.admin-sider-mask').exists()).toBe(false)
|
||||
expect(wrapper.get('.admin-sider').findAll('.n-menu .n-menu-item')).toHaveLength(8)
|
||||
expect(wrapper.get('[aria-label="折叠侧栏"]').attributes('aria-expanded')).toBe('true')
|
||||
const expandedBrand = wrapper.get('.admin-brand')
|
||||
expect(expandedBrand.classes()).not.toContain('is-collapsed')
|
||||
expect(expandedBrand.text()).toContain('短剧工作台')
|
||||
const expandedSettings = wrapper.get('.admin-sider-footer [aria-label="后端连接"]')
|
||||
expect(expandedSettings.text()).toBe('后端连接')
|
||||
expect(expandedSettings.classes()).not.toContain('is-collapsed')
|
||||
await wrapper.get('[aria-label="折叠侧栏"]').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.get('.admin-sider').classes()).toContain('is-collapsed')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 64px')
|
||||
expect(wrapper.get('.admin-sider').attributes('style')).toContain('width: 48px')
|
||||
expect(wrapper.get('.admin-brand').text()).toBe('')
|
||||
expect(wrapper.get('.admin-sider-footer [aria-label="后端连接"]').text()).toBe('')
|
||||
})
|
||||
|
||||
it('长弹窗使用内部滚动,提交期间禁止遮罩和 Esc 关闭', async () => {
|
||||
|
||||
@@ -222,8 +222,8 @@ describe('拆解页内容滚动', () => {
|
||||
expect(wrapper!.findAll('.subject-record-list > article')).toHaveLength(30)
|
||||
})
|
||||
|
||||
it('主体搜索与统计靠左居中,窄内容区可换行,输入框不再使用外置图标容器', () => {
|
||||
// DOM 环境不计算布局,保护输入框宽度、主题统计色与窄屏换行的样式契约。
|
||||
it('主体搜索与统计靠左居中,窄屏搜索拉满同一行,输入框不再使用外置图标容器', () => {
|
||||
// DOM 环境不计算布局,保护输入框宽度、主题统计色与窄屏单行搜索的样式契约。
|
||||
const css = readAllStyles()
|
||||
expect(css).toMatch(
|
||||
/\.subject-list-toolbar\s*\{[^}]*display:\s*flex;[^}]*flex-wrap:\s*wrap;[^}]*align-items:\s*center;[^}]*justify-content:\s*flex-start;/
|
||||
@@ -232,9 +232,19 @@ describe('拆解页内容滚动', () => {
|
||||
/\.subject-list-search\.n-input\s*\{[^}]*flex:\s*0 1 260px;[^}]*min-width:\s*0;[^}]*max-width:\s*100%;/
|
||||
)
|
||||
expect(css).toMatch(/\.subject-list-count\s*\{[^}]*color:\s*var\(--app-muted\);/)
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.subject-list-search\.n-input\s*\{[^}]*flex:\s*1/)
|
||||
expect(css + readFileSync('src/styles/styles.css', 'utf8')).not.toContain('.search-field')
|
||||
})
|
||||
|
||||
it('窄屏收口拆解顶栏并隐藏重复标题,设置按钮保留图标', () => {
|
||||
const css = readAllStyles()
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.workspace-toolbar h2\s*\{[^}]*display:\s*none/)
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.workspace-tools-label\s*\{[^}]*display:\s*none/)
|
||||
expect(css).toMatch(
|
||||
/@media \(max-width: 800px\)[\s\S]*?\.workspace-tools-trigger\s*\{[^}]*height:\s*32px;[^}]*width:\s*32px/
|
||||
)
|
||||
})
|
||||
|
||||
it.each([
|
||||
['人物', 'character'],
|
||||
['场景', 'scene'],
|
||||
|
||||
@@ -71,7 +71,8 @@ describe('连续剧本阅读器', () => {
|
||||
expect(content).toContain('padding: 32px')
|
||||
expect(content).toContain('text-align: left')
|
||||
expect(content).not.toContain('auto')
|
||||
expect(css).toMatch(/@media \(max-width: 600px\)[\s\S]*?\.reader-content\s*\{\s*padding-inline:\s*18px/)
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.reader-content\s*\{\s*padding-inline:\s*18px/)
|
||||
expect(css).toMatch(/@media \(max-width: 800px\)[\s\S]*?\.episode-reader\s*\{[^}]*72px/)
|
||||
})
|
||||
|
||||
it('按编号连续渲染全部剧集、元数据和空正文,标题不截断,模型内容只按文本显示', () => {
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from '@/features/storyboard/testing/fixtures'
|
||||
import { getStoryboardSession } from '@/features/storyboard/model'
|
||||
import { getOperation } from '@/features/workflows/operations'
|
||||
import { readAllStyles } from '@/testing/styles'
|
||||
import SubjectImagesPage from '@/features/subject-images/SubjectImagesPage.vue'
|
||||
import { formFixture, imageFixture } from '@/features/subject-images/testing/fixtures'
|
||||
import { getImageSession } from '@/features/subject-images/model'
|
||||
@@ -1432,6 +1433,13 @@ describe('工作台页面交互', () => {
|
||||
expect(provided.refresh).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('窄屏隐藏进入拆解,选择器需压过工具栏文字按钮', () => {
|
||||
const css = readAllStyles()
|
||||
expect(css).toMatch(
|
||||
/@media \(max-width: 800px\)[\s\S]*?\.tabs-toolbar-actions \.script-next-link\s*\{[^}]*display:\s*none/
|
||||
)
|
||||
})
|
||||
|
||||
it('切换剧本标签保留阅读容器和位置,执行记录按需展开', async () => {
|
||||
wrapper = mount(CreateDramaPage, {
|
||||
attachTo: document.body,
|
||||
|
||||
Reference in New Issue
Block a user