135 lines
4.4 KiB
TypeScript
135 lines
4.4 KiB
TypeScript
import { test, expect, type Page } from '@playwright/test'
|
|
import * as path from 'path'
|
|
import * as fs from 'fs'
|
|
import {
|
|
createFixtureVaultCopy,
|
|
openFixtureVault,
|
|
removeFixtureVaultCopy,
|
|
} from '../tests/helpers/fixtureVault'
|
|
|
|
// Minimal valid PNG: 1x1 red pixel
|
|
const TEST_PNG_BASE64 =
|
|
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
|
|
|
|
function createTestPng(filepath: string) {
|
|
fs.mkdirSync(path.dirname(filepath), { recursive: true })
|
|
fs.writeFileSync(filepath, Buffer.from(TEST_PNG_BASE64, 'base64'))
|
|
}
|
|
|
|
let tempVaultDir: string
|
|
|
|
async function openImageTestNote(page: Page) {
|
|
await page.locator('[data-testid="note-list-container"]').getByText('Alpha Project', { exact: true }).click()
|
|
|
|
const editor = page.locator('.bn-editor')
|
|
await expect(editor).toBeVisible({ timeout: 10000 })
|
|
return editor
|
|
}
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
testInfo.setTimeout(60_000)
|
|
tempVaultDir = createFixtureVaultCopy()
|
|
await openFixtureVault(page, tempVaultDir)
|
|
})
|
|
|
|
test.afterEach(async () => {
|
|
removeFixtureVaultCopy(tempVaultDir)
|
|
})
|
|
|
|
test('image upload via file picker displays image with data URL', async ({ page }) => {
|
|
const editor = await openImageTestNote(page)
|
|
await editor.click()
|
|
await page.waitForTimeout(200)
|
|
|
|
// Insert image block via slash command
|
|
await page.keyboard.press('Enter')
|
|
await page.waitForTimeout(100)
|
|
await page.keyboard.type('/image', { delay: 80 })
|
|
await page.waitForTimeout(500)
|
|
|
|
// Select Image from slash menu (press Enter to pick first match)
|
|
await page.keyboard.press('Enter')
|
|
await page.waitForTimeout(500)
|
|
|
|
// Verify Upload tab is available (uploadFile is configured)
|
|
const fileInput = page.locator('input[type="file"]')
|
|
expect(await fileInput.count()).toBeGreaterThan(0)
|
|
|
|
// Upload a test image
|
|
const testImagePath = path.join(process.cwd(), 'test-results', 'test-image.png')
|
|
createTestPng(testImagePath)
|
|
|
|
await fileInput.first().setInputFiles(testImagePath)
|
|
await page.waitForTimeout(2000)
|
|
|
|
// Verify: image element exists in the editor
|
|
const images = page.locator('.bn-editor img')
|
|
const imageCount = await images.count()
|
|
expect(imageCount).toBeGreaterThan(0)
|
|
|
|
// Verify: image uses data URL (stable, survives reload in dev mode)
|
|
const src = await images.first().getAttribute('src')
|
|
expect(src).toMatch(/^data:/)
|
|
|
|
// Verify: no "Loading..." elements remain
|
|
const loadingEls = page.locator('.bn-file-loading-preview')
|
|
expect(await loadingEls.count()).toBe(0)
|
|
|
|
await page.screenshot({ path: 'test-results/image-upload-after.png', fullPage: true })
|
|
|
|
if (fs.existsSync(testImagePath)) fs.unlinkSync(testImagePath)
|
|
})
|
|
|
|
test('image paste into editor inserts image block', async ({ page }) => {
|
|
const editor = await openImageTestNote(page)
|
|
await editor.click()
|
|
|
|
await page.evaluate((base64) => {
|
|
const editorElement = document.querySelector('.bn-editor')
|
|
if (!editorElement) throw new Error('Editor not found')
|
|
|
|
const binary = atob(base64)
|
|
const bytes = new Uint8Array(binary.length)
|
|
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
|
|
|
|
const file = new File([bytes], 'pasted-image.png', { type: 'image/png' })
|
|
const clipboardData = new DataTransfer()
|
|
clipboardData.items.add(file)
|
|
editorElement.dispatchEvent(new ClipboardEvent('paste', {
|
|
clipboardData,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
}))
|
|
}, TEST_PNG_BASE64)
|
|
|
|
const images = page.locator('.bn-editor img')
|
|
await expect(images.first()).toBeVisible({ timeout: 5000 })
|
|
|
|
const src = await images.first().getAttribute('src')
|
|
expect(src).toMatch(/^data:/)
|
|
})
|
|
|
|
test('editor has uploadFile configured (no error on image block insert)', async ({ page }) => {
|
|
const editor = await openImageTestNote(page)
|
|
|
|
// Capture console errors
|
|
const errors: string[] = []
|
|
page.on('pageerror', (err) => errors.push(err.message))
|
|
|
|
// Insert an image block via slash command
|
|
await editor.click()
|
|
await page.keyboard.press('Enter')
|
|
await page.keyboard.type('/image', { delay: 30 })
|
|
await page.waitForTimeout(500)
|
|
|
|
// Press Enter to select Image
|
|
await page.keyboard.press('Enter')
|
|
await page.waitForTimeout(500)
|
|
|
|
await page.screenshot({ path: 'test-results/image-block-inserted.png', fullPage: true })
|
|
|
|
// No errors related to upload should have occurred
|
|
const uploadErrors = errors.filter(e => e.includes('upload'))
|
|
expect(uploadErrors).toHaveLength(0)
|
|
})
|