Compare commits
2 Commits
site
...
alpha-v202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be5a8bb300 | ||
|
|
ce040c75fd |
@@ -6,14 +6,20 @@ import { TolariaSideMenu } from './tolariaBlockNoteSideMenu'
|
||||
let capturedDragHandleMenu: ComponentType | null = null
|
||||
|
||||
vi.mock('@blocknote/react', () => ({
|
||||
AddBlockButton: () => <button type="button">Add block</button>,
|
||||
DragHandleMenu: ({ children }: PropsWithChildren) => (
|
||||
<div data-testid="drag-handle-menu">{children}</div>
|
||||
),
|
||||
RemoveBlockItem: ({ children }: PropsWithChildren) => <div>{children}</div>,
|
||||
SideMenu: ({ dragHandleMenu }: { dragHandleMenu?: ComponentType }) => {
|
||||
DragHandleButton: ({ dragHandleMenu }: { dragHandleMenu?: ComponentType }) => {
|
||||
capturedDragHandleMenu = dragHandleMenu ?? null
|
||||
return <div data-testid="side-menu" />
|
||||
return (
|
||||
<button type="button" draggable>
|
||||
Open block menu
|
||||
</button>
|
||||
)
|
||||
},
|
||||
RemoveBlockItem: ({ children }: PropsWithChildren) => <div>{children}</div>,
|
||||
SideMenu: ({ children }: PropsWithChildren) => <div data-testid="side-menu">{children}</div>,
|
||||
TableColumnHeaderItem: ({ children }: PropsWithChildren) => <div>{children}</div>,
|
||||
TableRowHeaderItem: ({ children }: PropsWithChildren) => <div>{children}</div>,
|
||||
useDictionary: () => ({
|
||||
@@ -32,6 +38,10 @@ describe('TolariaSideMenu', () => {
|
||||
|
||||
expect(screen.getByTestId('side-menu')).toBeInTheDocument()
|
||||
expect(capturedDragHandleMenu).not.toBeNull()
|
||||
expect(screen.getAllByRole('button').map((button) => button.textContent)).toEqual([
|
||||
'Open block menu',
|
||||
'Add block',
|
||||
])
|
||||
|
||||
const DragHandleMenuComponent = capturedDragHandleMenu!
|
||||
render(<DragHandleMenuComponent />)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import {
|
||||
AddBlockButton,
|
||||
DragHandleMenu,
|
||||
DragHandleButton,
|
||||
RemoveBlockItem,
|
||||
SideMenu,
|
||||
TableColumnHeaderItem,
|
||||
@@ -21,5 +23,10 @@ function TolariaDragHandleMenu() {
|
||||
}
|
||||
|
||||
export function TolariaSideMenu(props: SideMenuProps) {
|
||||
return <SideMenu {...props} dragHandleMenu={TolariaDragHandleMenu} />
|
||||
return (
|
||||
<SideMenu {...props}>
|
||||
<DragHandleButton dragHandleMenu={TolariaDragHandleMenu} />
|
||||
<AddBlockButton />
|
||||
</SideMenu>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@ async function blockOuterForText(page: Page, text: string): Promise<Locator> {
|
||||
return textNode.locator('xpath=ancestor::*[contains(concat(" ", normalize-space(@class), " "), " bn-block-outer ")][1]')
|
||||
}
|
||||
|
||||
async function visibleDragHandle(page: Page, block: Locator): Promise<Locator> {
|
||||
async function visibleLeftBlockHandle(page: Page, block: Locator): Promise<Locator> {
|
||||
await block.hover()
|
||||
const handle = page.locator('.bn-side-menu [draggable="true"]').first()
|
||||
const handle = page.locator('.bn-side-menu button').first()
|
||||
await expect(handle).toBeVisible({ timeout: 5_000 })
|
||||
await expect(handle).toHaveAttribute('draggable', 'true')
|
||||
return handle
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ test('dragging the left block handle reorders editor blocks', async ({ page }) =
|
||||
|
||||
await expect.poll(async () => editor.textContent()).toMatch(/Alpha Project[\s\S]*This is a test project[\s\S]*Notes/)
|
||||
|
||||
const handle = await visibleDragHandle(page, notesHeading)
|
||||
const handle = await visibleLeftBlockHandle(page, notesHeading)
|
||||
await dragHandleToBlock(page, handle, paragraph)
|
||||
|
||||
await expect.poll(async () => editor.textContent()).toMatch(/Alpha Project[\s\S]*Notes[\s\S]*This is a test project/)
|
||||
|
||||
80
tests/smoke/table-hover-crash.spec.ts
Normal file
80
tests/smoke/table-hover-crash.spec.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { test, expect, type Page } from '@playwright/test'
|
||||
import { createFixtureVaultCopy, openFixtureVaultTauri, removeFixtureVaultCopy } from '../helpers/fixtureVault'
|
||||
import { seedBlockNoteTable, triggerMenuCommand } from './testBridge'
|
||||
|
||||
let tempVaultDir: string
|
||||
|
||||
function trackUnexpectedErrors(page: Page): string[] {
|
||||
const errors: string[] = []
|
||||
|
||||
page.on('pageerror', (error) => {
|
||||
errors.push(error.message)
|
||||
})
|
||||
|
||||
page.on('console', (message) => {
|
||||
if (message.type() !== 'error') return
|
||||
const text = message.text()
|
||||
if (text.includes('ws://localhost:9711')) return
|
||||
errors.push(text)
|
||||
})
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
async function createUntitledNote(page: Page): Promise<void> {
|
||||
await triggerMenuCommand(page, 'file-new-note')
|
||||
await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5_000 })
|
||||
}
|
||||
|
||||
async function moveAcrossElement(page: Page, selector: string): Promise<void> {
|
||||
const target = page.locator(selector).first()
|
||||
await expect(target).toBeVisible({ timeout: 5_000 })
|
||||
const box = await target.boundingBox()
|
||||
expect(box).not.toBeNull()
|
||||
if (!box) return
|
||||
|
||||
const points = [
|
||||
{ x: box.x + 2, y: box.y + 2 },
|
||||
{ x: box.x + box.width / 2, y: box.y + box.height / 2 },
|
||||
{ x: box.x + Math.max(2, box.width - 2), y: box.y + Math.max(2, box.height - 2) },
|
||||
]
|
||||
|
||||
for (const point of points) {
|
||||
await page.mouse.move(point.x, point.y, { steps: 4 })
|
||||
}
|
||||
}
|
||||
|
||||
test.describe('table hover crash regression', () => {
|
||||
test.beforeEach(({ page }, testInfo) => {
|
||||
void page
|
||||
testInfo.setTimeout(60_000)
|
||||
tempVaultDir = createFixtureVaultCopy()
|
||||
})
|
||||
|
||||
test.afterEach(() => {
|
||||
removeFixtureVaultCopy(tempVaultDir)
|
||||
})
|
||||
|
||||
test('moving through table wrappers, cells, and nearby text keeps the editor stable', async ({ page }) => {
|
||||
const errors = trackUnexpectedErrors(page)
|
||||
|
||||
await openFixtureVaultTauri(page, tempVaultDir)
|
||||
await createUntitledNote(page)
|
||||
await seedBlockNoteTable(page, [180, 120, 120])
|
||||
|
||||
await expect(page.locator('div.tableWrapper')).toBeVisible({ timeout: 5_000 })
|
||||
await moveAcrossElement(page, 'div.tableWrapper')
|
||||
await page.locator('table th').first().hover()
|
||||
await page.locator('table td').first().hover()
|
||||
|
||||
const trailingParagraph = page.locator('.bn-editor [data-content-type="paragraph"]').last()
|
||||
await trailingParagraph.hover()
|
||||
await trailingParagraph.click()
|
||||
await page.keyboard.type('stable after table hover')
|
||||
|
||||
const editor = page.getByRole('textbox').last()
|
||||
await expect(editor).toContainText('stable after table hover')
|
||||
await expect(page.locator('table')).toHaveCount(1)
|
||||
expect(errors).toEqual([])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user