openpencil/tests/e2e/recovery.spec.ts

79 lines
3.2 KiB
TypeScript
Raw Normal View History

2026-09-10 19:57:45 +00:00
import { type Page } from '@playwright/test'
import { expect, test } from '#tests/e2e/fixtures'
import { CanvasHelper } from '#tests/helpers/canvas'
2026-09-10 19:57:45 +00:00
function recoverySnapshotCount(page: Page): Promise<number> {
return page.evaluate(async () => {
const request = indexedDB.open('open-pencil-recovery')
const database = await new Promise<IDBDatabase>((resolve, reject) => {
request.onsuccess = () => resolve(request.result)
request.onerror = () => reject(request.error)
})
const transaction = database.transaction('meta')
const countRequest = transaction.objectStore('meta').count()
return new Promise<number>((resolve, reject) => {
countRequest.onsuccess = () => resolve(countRequest.result)
countRequest.onerror = () => reject(countRequest.error)
})
})
}
test('keeps an unsaved document recoverable after its tab closes', async ({ browser, baseURL }) => {
const context = await browser.newContext({ baseURL })
const page = await context.newPage()
await page.goto('/')
const canvas = new CanvasHelper(page)
await canvas.waitForInit()
await page.evaluate(async () => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
const id = store.createShape('RECTANGLE', 120, 120, 240, 140)
await store.persistRecoveryNow()
store.updateNode(id, { name: 'Retained recovery rectangle' })
})
await page.keyboard.press('ControlOrMeta+t')
await expect(page.getByRole('button', { name: 'New tab' })).toBeVisible()
await page.getByTestId('tabbar-tab').first().getByTestId('tabbar-close').click()
await expect(page.getByRole('button', { name: 'New tab' })).toBeHidden()
2026-09-10 19:57:45 +00:00
await expect.poll(() => recoverySnapshotCount(page)).toBe(1)
await page.reload()
await expect(page.getByRole('alertdialog', { name: 'Recover unsaved work' })).toBeVisible()
await page.getByRole('button', { name: 'Restore' }).click()
await expect(page.getByText('Retained recovery rectangle')).toBeVisible()
await context.close()
})
2026-09-10 19:57:45 +00:00
test('discards a closed tab snapshot in auto-recover mode', async ({ browser, baseURL }) => {
const context = await browser.newContext({ baseURL })
const page = await context.newPage()
await page.goto('/?recover=auto')
const canvas = new CanvasHelper(page)
await canvas.waitForInit()
await page.evaluate(async () => {
const store = window.openPencil?.getStore?.()
if (!store) throw new Error('OpenPencil store not initialized')
const id = store.createShape('RECTANGLE', 120, 120, 240, 140)
await store.persistRecoveryNow()
store.updateNode(id, { name: 'Closed tab rectangle' })
})
await page.keyboard.press('ControlOrMeta+t')
await page.getByTestId('tabbar-tab').first().getByTestId('tabbar-close').click()
// Auto-recover mode must drop the snapshot instead of retaining it, otherwise
// the silently-restored document resurrects the closed tab on every reload.
await expect.poll(() => recoverySnapshotCount(page)).toBe(0)
await page.reload()
await expect(page.getByRole('alertdialog', { name: 'Recover unsaved work' })).toBeHidden()
await expect(page.getByText('Closed tab rectangle')).toHaveCount(0)
await context.close()
})