* refactor(ui): extract shared action and navigation primitives * refactor(ui): compose settings and libraries with shared tabs * feat(ui): preserve native activation and toolbar keyboard navigation * refactor(home): share document entries and accessible input controls * fix(layers): share virtualized row geometry and selection styling * refactor(layout): compose spacing and readable dimension controls * refactor(properties): compose advanced strokes and inline effects * refactor(ui): reuse actions in page and property controls * refactor(settings): adopt shared actions without changing workflows * refactor(ui): share collaboration and provider actions * refactor(ui): finish shell and paint action composition * test(ui): restore extracted control and settings coverage * test(ui): complete workflow extraction coverage * fix(ui): address review and trim redundant snapshots * fix(layout): preserve single-step Undo for guides and wrap
73 lines
2.6 KiB
TypeScript
73 lines
2.6 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
|
|
import { CanvasHelper } from '#tests/helpers/canvas'
|
|
|
|
for (const theme of ['light', 'dark']) {
|
|
test(`stroke settings editing and dismissal in ${theme}`, async ({ page }) => {
|
|
await page.goto('/?test')
|
|
await new CanvasHelper(page).waitForInit()
|
|
const ids = await page.evaluate(async (mode) => {
|
|
const path = '/src/app/shell/theme.ts'
|
|
const module = await import(path)
|
|
module.useAppTheme().setTheme(mode)
|
|
const editor = window.openPencil?.getStore?.()
|
|
if (!editor) throw new Error('Editor unavailable')
|
|
const id = editor.createShape('RECTANGLE', 100, 100, 180, 120)
|
|
const line = editor.createShape('LINE', 100, 300, 180, 0)
|
|
for (const target of [id, line])
|
|
editor.updateNode(target, {
|
|
strokes: [
|
|
{
|
|
color: { r: 0, g: 0, b: 0, a: 1 },
|
|
weight: 2,
|
|
opacity: 1,
|
|
visible: true,
|
|
align: 'CENTER'
|
|
}
|
|
]
|
|
})
|
|
editor.select([id])
|
|
return { id, line }
|
|
}, theme)
|
|
const section = page.getByRole('region', { name: 'Stroke', exact: true })
|
|
await expect(section).toHaveScreenshot(`stroke-main-${theme}.png`)
|
|
const trigger = section.getByRole('button', { name: 'Stroke settings' })
|
|
await trigger.click()
|
|
const dialog = page.getByRole('dialog', { name: 'Stroke settings' })
|
|
await dialog.getByRole('switch', { name: 'Dashed stroke' }).click()
|
|
const dash = dialog.getByRole('spinbutton', { name: 'Dash', exact: true })
|
|
await dash.focus()
|
|
await dash.fill('10')
|
|
await dash.press('Enter')
|
|
await expect
|
|
.poll(() =>
|
|
page.evaluate(
|
|
(id) => window.openPencil?.getStore?.().graph.getNode(id)?.strokes[0].dashPattern?.[0],
|
|
ids.id
|
|
)
|
|
)
|
|
.toBe(10)
|
|
await expect(dialog).toHaveScreenshot(`stroke-dashed-${theme}.png`)
|
|
await page.keyboard.press('Escape')
|
|
await expect(dialog).toHaveCount(0)
|
|
await expect(trigger).toBeFocused()
|
|
await trigger.click()
|
|
await page.evaluate((id) => window.openPencil?.getStore?.().select([id]), ids.line)
|
|
await dialog.getByRole('button', { name: 'Round cap', exact: true }).click()
|
|
await expect
|
|
.poll(() =>
|
|
page.evaluate(
|
|
(id) => window.openPencil?.getStore?.().graph.getNode(id)?.strokeCap,
|
|
ids.line
|
|
)
|
|
)
|
|
.toBe('ROUND')
|
|
await expect
|
|
.poll(() =>
|
|
page.evaluate((id) => window.openPencil?.getStore?.().graph.getNode(id)?.strokeCap, ids.id)
|
|
)
|
|
.toBe('NONE')
|
|
await expect(dialog).toHaveScreenshot(`stroke-line-${theme}.png`)
|
|
})
|
|
}
|