* fix(editor): commit vector drags on pointer release - Commit vertex and Bézier handle edits immediately on release\n- Rebase active vector-edit state after graph commits\n- Use vector-specific input paths and cover Pen-created Bézier drags * test: reduce visual snapshot scope - Replace behavior screenshots with scene assertions\n- Capture renderer fixtures from bounded canvas regions\n- Remove obsolete full-viewport snapshots * fix(vector): harden edit cancellation and endpoint remapping - Restore temporary vector geometry on cancelled pointer drags\n- Commit Bézier handle releases consistently and guard stale handle state\n- Preserve valid endpoint indices when connecting vector vertices * fix(vector): cancel bend drags and satisfy formatting * fix(vector): guard stale handle references * fix(vector): guard stale overlay handle indices * fix(vector): validate overlay handle keys * refactor(vector): use typed handle selection ids * test(vector): align typed handle selection coverage
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import { expect, test, useEditorSetupWithClear } from '#tests/e2e/fixtures'
|
|
|
|
const editor = useEditorSetupWithClear('/?test&no-chrome&no-rulers')
|
|
|
|
async function pageChildren() {
|
|
return editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
const page = store.graph.getNode(store.state.currentPageId)
|
|
if (!page) throw new Error('Current page not found')
|
|
return page.childIds
|
|
.map((id: string) => {
|
|
const node = store.graph.getNode(id)
|
|
return node
|
|
? {
|
|
id: node.id,
|
|
type: node.type,
|
|
x: node.x,
|
|
y: node.y,
|
|
width: node.width,
|
|
height: node.height
|
|
}
|
|
: null
|
|
})
|
|
.filter((node): node is NonNullable<typeof node> => node !== null)
|
|
})
|
|
}
|
|
|
|
test('empty canvas', async () => {
|
|
expect(await pageChildren()).toEqual([])
|
|
})
|
|
|
|
test('draw rectangle', async () => {
|
|
await editor.canvas.drawRect(100, 100, 200, 150)
|
|
const [rectangle] = await pageChildren()
|
|
expect(rectangle).toMatchObject({ type: 'RECTANGLE', x: 100, y: 100, width: 200, height: 150 })
|
|
})
|
|
|
|
test('draw ellipse', async () => {
|
|
await editor.canvas.drawEllipse(100, 100, 200, 150)
|
|
const [ellipse] = await pageChildren()
|
|
expect(ellipse).toMatchObject({ type: 'ELLIPSE', x: 100, y: 100, width: 200, height: 150 })
|
|
})
|
|
|
|
test('draw rectangle then move it', async () => {
|
|
await editor.canvas.drawRect(100, 100, 200, 150)
|
|
await editor.canvas.selectTool('select')
|
|
await editor.canvas.drag(200, 175, 400, 300)
|
|
await editor.canvas.waitForRender()
|
|
const [moved] = await pageChildren()
|
|
expect(moved).toMatchObject({ type: 'RECTANGLE', x: 300, y: 225, width: 200, height: 150 })
|
|
})
|
|
|
|
test('draw and delete', async () => {
|
|
await editor.canvas.drawRect(100, 100, 200, 150)
|
|
await editor.canvas.deleteSelection()
|
|
expect(await pageChildren()).toEqual([])
|
|
})
|
|
|
|
test('draw and undo', async () => {
|
|
await editor.canvas.drawRect(100, 100, 200, 150)
|
|
await editor.canvas.undo()
|
|
expect(await pageChildren()).toEqual([])
|
|
})
|