openpencil/tests/helpers/tauri/editor-snapshot.ts
Danila Poyarkov f4f3736034 test(native): open a document before editor fixtures
The Home tab exposes an editor store without a mounted canvas or text editor. Open New design during fixture setup and await actual editor readiness before populating nodes or starting text input. Reuse already-open documents and keep WebDriver input assertions unchanged.

Full check passes. Native WebKit text input, fixture reuse and Settings checks pass (4 tests); Windows-only layer dragging skips on macOS. Upstream Tauri service bridge/teardown warnings remain; this does not claim IME or native clipboard coverage.
2026-09-15 14:43:31 +03:00

110 lines
4.1 KiB
TypeScript

export type NativeLayerFixture = {
first: string
second: string
third: string
}
// Home has an editor store too, but no mounted canvas or text-input session.
async function ensureNativeEditorReady(): Promise<void> {
await browser.waitUntil(
async () => browser.execute(() => Boolean(window.openPencil?.getStore?.())),
{ timeout: 30_000, timeoutMsg: 'OpenPencil store did not initialize' }
)
await browser.execute(() => {
const store = window.openPencil?.getStore?.()
if (document.querySelector('canvas') && store?.textEditor) return
const newDesign = [...document.querySelectorAll('button')].find(
(button) => button.textContent?.trim() === 'New design'
)
// Setup only: input assertions still use WebDriver after the document is ready.
newDesign?.click()
})
await browser.waitUntil(
async () =>
browser.execute(() => {
const store = window.openPencil?.getStore?.()
return Boolean(document.querySelector('canvas') && store?.textEditor)
}),
{ timeout: 30_000, timeoutMsg: 'Native canvas and text editor did not initialize' }
)
}
export async function createNativeLayerFixture(): Promise<NativeLayerFixture> {
await ensureNativeEditorReady()
return browser.execute(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil editor is not ready')
const pageId = store.state.currentPageId
for (const node of store.graph.getChildren(pageId)) store.graph.deleteNode(node.id)
const first = store.graph.createNode('RECTANGLE', pageId, { name: 'Native Layer A' })
const second = store.graph.createNode('RECTANGLE', pageId, { name: 'Native Layer B' })
const third = store.graph.createNode('RECTANGLE', pageId, { name: 'Native Layer C' })
store.requestRender()
return { first: first.id, second: second.id, third: third.id }
})
}
export async function readNativeLayerOrder(parentId?: string): Promise<string[]> {
return browser.execute((id) => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil editor is not ready')
return store.graph.getNode(id ?? store.state.currentPageId)?.childIds ?? []
}, parentId)
}
export type NativeEditorSnapshot = {
editingTextId: string | null
selectedIds: string[]
renderVersion: number
sceneVersion: number
editingText: string | null
editingNodeExists: boolean
textNodeCount: number
}
export async function readNativeEditorSnapshot(): Promise<NativeEditorSnapshot> {
return browser.execute(() => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil editor is not ready')
const editingTextId = store.state.editingTextId
const node = editingTextId ? store.graph.getNode(editingTextId) : null
let textNodeCount = 0
for (const pageNode of store.graph.getChildren(store.state.currentPageId)) {
if (pageNode.type === 'TEXT') textNodeCount++
}
return {
editingTextId,
selectedIds: [...store.state.selectedIds],
renderVersion: store.state.renderVersion,
sceneVersion: store.state.sceneVersion,
editingText: node?.type === 'TEXT' ? (node.text ?? '') : null,
editingNodeExists: editingTextId !== null && node !== undefined,
textNodeCount
}
})
}
export async function createNativeTextFixture(text = ''): Promise<string> {
await ensureNativeEditorReady()
return browser.execute((initialText) => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil editor is not ready')
for (const node of store.graph.getChildren(store.state.currentPageId)) {
store.graph.deleteNode(node.id)
}
const id = store.createShape('TEXT', 120, 120, 320, 60)
store.graph.updateNode(id, {
text: initialText,
fontSize: 32,
fontFamily: 'Inter',
textAutoResize: 'WIDTH_AND_HEIGHT',
fills: [{ type: 'SOLID', color: { r: 0, g: 0, b: 0, a: 1 }, visible: true, opacity: 1 }]
})
store.select([id])
store.startTextEditing(id)
store.textEditor?.selectAll()
store.requestRender()
return id
}, text)
}