openpencil/tests/e2e/text/editing.spec.ts
2026-07-20 21:22:30 +03:00

166 lines
5.4 KiB
TypeScript

import { expect, test, useEditorSetup } from '#tests/e2e/fixtures'
import { expectDefined } from '#tests/helpers/assert'
import { getSelectedNode } from '#tests/helpers/store'
const editor = useEditorSetup()
function getPageChildren() {
return editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
return store.graph.getChildren(store.state.currentPageId).map((n) => ({
type: n.type,
name: n.name,
text: n.text
}))
})
}
test('pressing T activates text tool', async () => {
await editor.page.keyboard.press('t')
const tool = await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
return store.state.activeTool
})
expect(tool).toBe('TEXT')
})
test('clicking with text tool creates a text node', async () => {
await editor.canvas.click(200, 200)
await editor.canvas.waitForRender()
// Wait a tick for text editing mode to activate
await editor.page.waitForTimeout(200)
const children = await getPageChildren()
const textNode = children.find((c) => c.type === 'TEXT')
expect(textNode).toBeTruthy()
})
test('point text is selected and auto-sizes after creation', async () => {
const node = await getSelectedNode(editor.page)
expect(node?.type).toBe('TEXT')
expect(node?.textAutoResize).toBe('WIDTH_AND_HEIGHT')
})
test('typography section appears for text node', async () => {
// Exit text editing mode
await editor.page.keyboard.press('Escape')
await editor.canvas.waitForRender()
// Re-select the text node
await editor.canvas.click(200, 200)
await editor.canvas.waitForRender()
const typoSection = editor.page.getByRole('region', { name: 'Typography' })
await expect(typoSection).toBeVisible()
})
test('text node has default font properties', async () => {
const node = await getSelectedNode(editor.page)
expect(node?.fontSize).toBeGreaterThan(0)
expect(node?.fontFamily).toBeTruthy()
})
test('dragging with the text tool creates a fixed-width text box', async () => {
await editor.page.keyboard.press('Escape')
await editor.page.keyboard.press('t')
await editor.canvas.drag(300, 120, 520, 240)
await editor.canvas.waitForRender()
const node = expectDefined(await getSelectedNode(editor.page), 'selected text box')
expect(node.type).toBe('TEXT')
expect(node.width).toBeCloseTo(220)
expect(node.height).toBeCloseTo(120)
expect(node.textAutoResize).toBe('NONE')
const editingTextId = await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
return store.state.editingTextId
})
expect(editingTextId).toBe(node.id)
})
test('creating text via store works', async () => {
await editor.page.keyboard.press('Escape')
await editor.canvas.waitForRender()
await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
const id = store.createShape('TEXT', 100, 300, 200, 30)
store.graph.updateNode(id, { text: 'Hello World', fontSize: 24, fontFamily: 'Inter' })
store.select([id])
})
await editor.canvas.waitForRender()
const node = await getSelectedNode(editor.page)
expect(node?.text).toBe('Hello World')
expect(node?.fontSize).toBe(24)
})
test('undo removes text node', async () => {
const beforeCount = (await getPageChildren()).length
await editor.canvas.undo()
await editor.canvas.waitForRender()
const afterCount = (await getPageChildren()).length
expect(afterCount).toBe(beforeCount - 1)
})
test('frame tool creates FRAME node', async () => {
await editor.page.keyboard.press('f')
await editor.canvas.drag(400, 100, 600, 250)
await editor.canvas.waitForRender()
const node = expectDefined(await getSelectedNode(editor.page), 'selected frame')
expect(node.type).toBe('FRAME')
expect(node.width).toBeGreaterThan(0)
expect(node.height).toBeGreaterThan(0)
editor.canvas.assertNoErrors()
})
test('Enter key opens text editing and selects all without erasing', async () => {
await editor.page.keyboard.press('Escape')
await editor.canvas.waitForRender()
const textId = await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
const id = store.createShape('TEXT', 300, 300, 200, 30)
store.graph.updateNode(id, { text: 'Keep this text' })
store.select([id])
store.requestRender()
return id
})
await editor.canvas.waitForRender()
const before = await getSelectedNode(editor.page)
expect(before?.text).toBe('Keep this text')
expect(before?.type).toBe('TEXT')
await editor.page.keyboard.press('Enter')
await editor.page.waitForTimeout(200)
const editing = await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
return store.state.editingTextId
})
expect(editing).toBe(textId)
const after = await editor.page.evaluate(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
const id = store.state.editingTextId
if (!id) return null
return store.graph.getNode(id)?.text ?? null
})
expect(after).toBe('Keep this text')
})