272 lines
7.9 KiB
TypeScript
272 lines
7.9 KiB
TypeScript
import { expect, test, useEditorSetup } from '#tests/e2e/fixtures'
|
|
|
|
const editor = useEditorSetup()
|
|
|
|
function getPages() {
|
|
return editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
return store.graph.getPages().map((p) => ({ id: p.id, name: p.name }))
|
|
})
|
|
}
|
|
|
|
function getCurrentPageId() {
|
|
return editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
return store.state.currentPageId
|
|
})
|
|
}
|
|
|
|
function getPageChildCount() {
|
|
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).length
|
|
})
|
|
}
|
|
|
|
function pagesPanel() {
|
|
return editor.page.getByTestId('pages-panel')
|
|
}
|
|
|
|
function pageItems() {
|
|
return editor.page.getByTestId('pages-item')
|
|
}
|
|
|
|
function pageRows() {
|
|
return editor.page.getByTestId('pages-row')
|
|
}
|
|
|
|
function addPageButton() {
|
|
return editor.page.getByTestId('pages-add')
|
|
}
|
|
|
|
test('initial state has one page', async () => {
|
|
const pages = await getPages()
|
|
expect(pages).toHaveLength(1)
|
|
expect(pages[0].name).toBe('Page 1')
|
|
})
|
|
|
|
test('pages panel shows current page', async () => {
|
|
await expect(pagesPanel()).toBeVisible()
|
|
await expect(pageItems().first()).toContainText('Page 1')
|
|
})
|
|
|
|
test('add page creates a second page', async () => {
|
|
await addPageButton().click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
const pages = await getPages()
|
|
expect(pages).toHaveLength(2)
|
|
|
|
expect(await pageItems().count()).toBe(2)
|
|
})
|
|
|
|
test('new page is auto-selected', async () => {
|
|
const pages = await getPages()
|
|
const currentId = await getCurrentPageId()
|
|
expect(currentId).toBe(pages[1].id)
|
|
})
|
|
|
|
test('new page is empty', async () => {
|
|
expect(await getPageChildCount()).toBe(0)
|
|
})
|
|
|
|
test('drawing on new page adds nodes only to it', async () => {
|
|
await editor.canvas.drawRect(100, 100, 80, 60)
|
|
await editor.canvas.waitForRender()
|
|
|
|
expect(await getPageChildCount()).toBe(1)
|
|
})
|
|
|
|
test('switching to first page shows its content', async () => {
|
|
await pageItems().first().click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
const pages = await getPages()
|
|
const currentId = await getCurrentPageId()
|
|
expect(currentId).toBe(pages[0].id)
|
|
})
|
|
|
|
test('first page has no shapes (we never drew on it)', async () => {
|
|
expect(await getPageChildCount()).toBe(0)
|
|
})
|
|
|
|
test('switching back to second page shows its shape', async () => {
|
|
await pageItems().nth(1).click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
expect(await getPageChildCount()).toBe(1)
|
|
})
|
|
|
|
test('add a third page', async () => {
|
|
await addPageButton().click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
const pages = await getPages()
|
|
expect(pages).toHaveLength(3)
|
|
expect(await pageItems().count()).toBe(3)
|
|
})
|
|
|
|
test('delete current page switches to adjacent', async () => {
|
|
const pagesBefore = await getPages()
|
|
const deletingId = await getCurrentPageId()
|
|
|
|
await editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
store.deletePage(store.state.currentPageId)
|
|
})
|
|
await editor.canvas.waitForRender()
|
|
|
|
const pagesAfter = await getPages()
|
|
expect(pagesAfter).toHaveLength(pagesBefore.length - 1)
|
|
expect(pagesAfter.find((p) => p.id === deletingId)).toBeUndefined()
|
|
|
|
const currentId = await getCurrentPageId()
|
|
expect(pagesAfter.some((p) => p.id === currentId)).toBe(true)
|
|
})
|
|
|
|
test('rename page via store', async () => {
|
|
const currentId = await getCurrentPageId()
|
|
|
|
await editor.page.evaluate(
|
|
([id, name]) => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
store.renamePage(id, name)
|
|
},
|
|
[currentId, 'Renamed Page'] as [string, string]
|
|
)
|
|
await editor.canvas.waitForRender()
|
|
|
|
const updated = await getPages()
|
|
const renamed = updated.find((p) => p.id === currentId)
|
|
expect(renamed?.name).toBe('Renamed Page')
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|
|
|
|
test('double-click page to rename', async () => {
|
|
const item = pageItems().first()
|
|
await item.dblclick()
|
|
|
|
const input = editor.page.getByTestId('pages-item-input')
|
|
await expect(input).toBeVisible()
|
|
await input.fill('My Page')
|
|
await input.press('Enter')
|
|
|
|
await editor.canvas.waitForRender()
|
|
const pages = await getPages()
|
|
expect(pages.some((p) => p.name === 'My Page')).toBe(true)
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|
|
|
|
test('clicking outside page rename input commits', async () => {
|
|
const item = pageItems().first()
|
|
await item.dblclick()
|
|
|
|
const input = editor.page.getByTestId('pages-item-input')
|
|
await expect(input).toBeVisible()
|
|
await input.fill('Outside Click Page')
|
|
|
|
// Click on the page header label to trigger blur (outside the input but still in the panel)
|
|
await editor.page.getByTestId('pages-header').click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
await expect(input).not.toBeVisible()
|
|
const pages = await getPages()
|
|
expect(pages.some((p) => p.name === 'Outside Click Page')).toBe(true)
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|
|
|
|
test('cannot delete the last page', async () => {
|
|
// Delete until 1 remains
|
|
let pages = await getPages()
|
|
while (pages.length > 1) {
|
|
await editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
store.deletePage(store.state.currentPageId)
|
|
})
|
|
await editor.canvas.waitForRender()
|
|
pages = await getPages()
|
|
}
|
|
|
|
expect(pages).toHaveLength(1)
|
|
|
|
// Try deleting the last one — should be a no-op
|
|
await editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
store.deletePage(store.state.currentPageId)
|
|
})
|
|
await editor.canvas.waitForRender()
|
|
|
|
const after = await getPages()
|
|
expect(after).toHaveLength(1)
|
|
|
|
await pageRows().first().click({ button: 'right' })
|
|
await expect(editor.page.getByTestId('pages-context-delete')).toHaveAttribute('data-disabled', '')
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|
|
|
|
test('page context menu deletes a page', async () => {
|
|
await addPageButton().click()
|
|
await addPageButton().click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
const before = await getPages()
|
|
const deletedId = before[1].id
|
|
|
|
await pageRows().nth(1).click({ button: 'right' })
|
|
await editor.page.getByTestId('pages-context-delete').click()
|
|
await editor.canvas.waitForRender()
|
|
|
|
const after = await getPages()
|
|
expect(after).toHaveLength(before.length - 1)
|
|
expect(after.some((page) => page.id === deletedId)).toBe(false)
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|
|
|
|
test('dragging a page row reorders pages', async () => {
|
|
const currentPageId = await editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
while (store.graph.getPages().length < 3) store.addPage()
|
|
for (const [index, page] of store.graph.getPages().entries()) {
|
|
store.renamePage(page.id, `Order ${index + 1}`)
|
|
}
|
|
const page = store.graph.getPages()[1]
|
|
if (!page) throw new Error('Expected at least two pages')
|
|
store.switchPage(page.id)
|
|
return page.id
|
|
})
|
|
await editor.canvas.waitForRender()
|
|
|
|
await pageRows()
|
|
.first()
|
|
.dragTo(pageRows().nth(2), {
|
|
targetPosition: { x: 12, y: 18 }
|
|
})
|
|
await editor.canvas.waitForRender()
|
|
|
|
const pages = await getPages()
|
|
const names = pages.map((page) => page.name)
|
|
const currentAfterReorder = await editor.page.evaluate(() => {
|
|
const store = window.openPencil?.getStore?.()
|
|
if (!store) throw new Error('OpenPencil store not initialized')
|
|
return store.state.currentPageId
|
|
})
|
|
|
|
expect(names).toEqual(['Order 2', 'Order 3', 'Order 1'])
|
|
expect(currentAfterReorder).toBe(currentPageId)
|
|
|
|
editor.canvas.assertNoErrors()
|
|
})
|