Files
AFFiNE-Mirror/blocksuite/tests-legacy/fragments/frame-panel.spec.ts
2024-12-20 11:08:21 +00:00

357 lines
11 KiB
TypeScript

import { expect, type Locator, type Page } from '@playwright/test';
import { dragBetweenCoords } from 'utils/actions/drag.js';
import {
assertEdgelessNonSelectedRect,
assertEdgelessSelectedRect,
assertZoomLevel,
} from 'utils/asserts.js';
import {
addBasicShapeElement,
addNote,
createNote,
createShapeElement,
dragBetweenViewCoords,
edgelessCommonSetup,
enterPresentationMode,
getZoomLevel,
setEdgelessTool,
Shape,
switchEditorMode,
toggleFramePanel,
} from '../utils/actions/edgeless.js';
import { waitNextFrame } from '../utils/actions/index.js';
import { test } from '../utils/playwright.js';
async function dragFrameCard(
page: Page,
fromCard: Locator,
toCard: Locator,
direction: 'up' | 'down' = 'down'
) {
const fromRect = await fromCard.boundingBox();
const toRect = await toCard.boundingBox();
// drag to the center of the toCard
const center = { x: toRect!.width / 2, y: toRect!.height / 2 };
const offset = direction === 'up' ? { x: 0, y: -20 } : { x: 0, y: 20 };
await page.mouse.move(fromRect!.x + center.x, fromRect!.y + center.y);
await page.mouse.down();
await page.mouse.move(
toRect!.x + center.x + offset.x,
toRect!.y + center.y + offset.y,
{ steps: 10 }
);
await page.mouse.up();
}
test.describe('frame panel', () => {
test('should display empty placeholder when no frames', async ({ page }) => {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
const frameCards = page.locator('affine-frame-card');
expect(await frameCards.count()).toBe(0);
const placeholder = page.locator('.no-frame-placeholder');
expect(await placeholder.isVisible()).toBeTruthy();
});
test('should display frame cards when there are frames', async ({ page }) => {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
await addBasicShapeElement(
page,
{ x: 300, y: 300 },
{ x: 350, y: 350 },
Shape.Square
);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 250, y: 250 }, { x: 360, y: 360 });
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 100, y: 440 }, { x: 600, y: 600 });
const frames = page.locator('affine-frame');
expect(await frames.count()).toBe(2);
const frameCards = page.locator('affine-frame-card');
expect(await frameCards.count()).toBe(2);
});
test('should render edgeless note correctly in frame preview', async ({
page,
}) => {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 100, y: 440 }, { x: 600, y: 600 });
await waitNextFrame(page, 100);
const frames = page.locator('affine-frame');
expect(await frames.count()).toBe(1);
const frameCards = page.locator('affine-frame-card');
expect(await frameCards.count()).toBe(1);
const edgelessNote = page.locator('affine-frame-card affine-edgeless-note');
expect(await edgelessNote.count()).toBe(1);
});
test('should update panel when frames change', async ({ page }) => {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
const frameCards = page.locator('affine-frame-card');
expect(await frameCards.count()).toBe(0);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 100, y: 440 }, { x: 600, y: 600 });
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 50, y: 300 }, { x: 120, y: 400 });
await waitNextFrame(page);
const frames = page.locator('affine-frame');
expect(await frames.count()).toBe(2);
expect(await frameCards.count()).toBe(2);
await page.mouse.click(50, 300);
await page.keyboard.press('Delete');
await waitNextFrame(page);
expect(await frames.count()).toBe(1);
expect(await frameCards.count()).toBe(1);
});
test.describe('frame panel behavior after mode switch', () => {
async function setupFrameTest(page: Page) {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await waitNextFrame(page, 100);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(
page,
{ x: 100, y: 440 },
{ x: 640, y: 600 },
{ steps: 10 }
);
await waitNextFrame(page, 100);
const edgelessNote = page.locator(
'affine-frame-card affine-edgeless-note'
);
expect(await edgelessNote.count()).toBe(1);
return edgelessNote;
}
test('should render edgeless note correctly after mode switch', async ({
page,
}) => {
const edgelessNote = await setupFrameTest(page);
const initialNoteRect = await edgelessNote.boundingBox();
expect(initialNoteRect).not.toBeNull();
const {
width: noteWidth,
height: noteHeight,
x: noteX,
y: noteY,
} = initialNoteRect!;
const checkNoteRect = async () => {
expect(await edgelessNote.count()).toBe(1);
const newNoteRect = await edgelessNote.boundingBox();
expect(newNoteRect).not.toBeNull();
expect(newNoteRect!.width).toBe(noteWidth);
expect(newNoteRect!.height).toBe(noteHeight);
expect(newNoteRect!.x).toBe(noteX);
expect(newNoteRect!.y).toBe(noteY);
};
await switchEditorMode(page);
await checkNoteRect();
await switchEditorMode(page);
await checkNoteRect();
});
test('should update frame preview when note is moved', async ({ page }) => {
const edgelessNote = await setupFrameTest(page);
const initialNoteRect = await edgelessNote.boundingBox();
expect(initialNoteRect).not.toBeNull();
await switchEditorMode(page);
await switchEditorMode(page);
async function moveNoteAndCheck(
start: { x: number; y: number },
end: { x: number; y: number },
comparison: 'greaterThan' | 'lessThan'
) {
await page.mouse.move(start.x, start.y);
await page.mouse.down();
await page.mouse.move(end.x, end.y);
await page.mouse.up();
await waitNextFrame(page);
const newNoteRect = await edgelessNote.boundingBox();
expect(newNoteRect).not.toBeNull();
if (comparison === 'greaterThan') {
expect(newNoteRect!.x).toBeGreaterThan(initialNoteRect!.x);
expect(newNoteRect!.y).toBeGreaterThan(initialNoteRect!.y);
} else {
expect(newNoteRect!.x).toBeLessThan(initialNoteRect!.x);
expect(newNoteRect!.y).toBeLessThan(initialNoteRect!.y);
}
}
// Move the note to the right
await moveNoteAndCheck(
{ x: 150, y: 500 },
{ x: 200, y: 550 },
'greaterThan'
);
// Move the note back to the left
await moveNoteAndCheck(
{ x: 200, y: 550 },
{ x: 100, y: 450 },
'lessThan'
);
// Move the note diagonally
await moveNoteAndCheck(
{ x: 100, y: 450 },
{ x: 250, y: 600 },
'greaterThan'
);
});
});
test.describe('select and de-select frame', () => {
async function setupFrameTest(page: Page) {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 100, y: 440 }, { x: 640, y: 600 });
await waitNextFrame(page);
const frames = page.locator('affine-frame');
const frameCards = page.locator('affine-frame-card');
expect(await frames.count()).toBe(1);
expect(await frameCards.count()).toBe(1);
return { frames, frameCards };
}
test('by click on frame card', async ({ page }) => {
const { frameCards } = await setupFrameTest(page);
// click on the first frame card
await frameCards.nth(0).click();
await assertEdgelessSelectedRect(page, [100, 440, 540, 160]);
await frameCards.nth(0).click();
await assertEdgelessNonSelectedRect(page);
});
test('by click on blank area', async ({ page }) => {
const { frameCards } = await setupFrameTest(page);
// click on the first frame card
await frameCards.nth(0).click();
await assertEdgelessSelectedRect(page, [100, 440, 540, 160]);
const framePanel = page.locator('.frame-panel-container');
const panelRect = await framePanel.boundingBox();
expect(panelRect).not.toBeNull();
const { x, y, width, height } = panelRect!;
await page.mouse.click(x + width / 2, y + height / 2);
await assertEdgelessNonSelectedRect(page);
});
});
test('should fit the viewport to the frame when double click frame card', async ({
page,
}) => {
await edgelessCommonSetup(page);
await toggleFramePanel(page);
await assertZoomLevel(page, 100);
await addNote(page, 'hello', 150, 500);
await page.mouse.click(0, 0);
await setEdgelessTool(page, 'frame');
await dragBetweenCoords(page, { x: 100, y: 440 }, { x: 600, y: 600 });
await waitNextFrame(page);
const frameCards = page.locator('affine-frame-card');
await frameCards.nth(0).dblclick();
const zoomLevel = await getZoomLevel(page);
expect(zoomLevel).toBeGreaterThan(100);
});
test('should reorder frames when drag and drop frame card', async ({
page,
}) => {
await edgelessCommonSetup(page);
await createShapeElement(page, [100, 100], [200, 200], Shape.Square);
await createNote(page, [300, 100], 'hello');
// Frame shape
await setEdgelessTool(page, 'frame');
await dragBetweenViewCoords(page, [80, 80], [220, 220]);
await waitNextFrame(page, 100);
// Frame note
await setEdgelessTool(page, 'frame');
await dragBetweenViewCoords(page, [240, 0], [800, 200]);
expect(await page.locator('affine-frame').count()).toBe(2);
await toggleFramePanel(page);
const frameCards = page.locator('affine-frame-card');
expect(await frameCards.count()).toBe(2);
// Drag the first frame card to the second
await dragFrameCard(page, frameCards.nth(0), frameCards.nth(1));
await enterPresentationMode(page);
await waitNextFrame(page, 100);
// Check if frame contains note now is the first
const edgelessNote = page.locator(
'affine-edgeless-root affine-edgeless-note'
);
await expect(edgelessNote).toBeVisible();
});
});