mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-24 18:02:47 +08:00
Closes: [BS-1475](https://linear.app/affine-design/issue/BS-1475/颜色主题更新) [BS-1803](https://linear.app/affine-design/issue/BS-1803/fill-color色板影响的yuan素) [BS-1804](https://linear.app/affine-design/issue/BS-1804/border-color色板影响的yuan素) [BS-1815](https://linear.app/affine-design/issue/BS-1815/连线文字配色略瞎) ### What's Changed * refactor `EdgelessLineWidthPanel` component, the previous width is fixed and cannot be used in the new design * refactor `EdgelessColorPanel` and `EdgelessColorButton` components, make them simple and reusable * delete redundant `EdgelessOneRowColorPanel` component * unity and update color palette, if the previously set color is not in the latest color palette, the custom color button will be selected
770 lines
19 KiB
TypeScript
770 lines
19 KiB
TypeScript
import { sleep } from '@blocksuite/global/utils';
|
|
import { expect, type Page } from '@playwright/test';
|
|
import { switchEditorMode } from 'utils/actions/edgeless.js';
|
|
|
|
import { dragBlockToPoint, popImageMoreMenu } from './utils/actions/drag.js';
|
|
import {
|
|
pressArrowDown,
|
|
pressArrowUp,
|
|
pressBackspace,
|
|
pressEnter,
|
|
pressEscape,
|
|
pressShiftTab,
|
|
pressTab,
|
|
redoByKeyboard,
|
|
SHORT_KEY,
|
|
type,
|
|
undoByKeyboard,
|
|
} from './utils/actions/keyboard.js';
|
|
import {
|
|
captureHistory,
|
|
enterPlaygroundRoom,
|
|
focusRichText,
|
|
initEmptyEdgelessState,
|
|
initEmptyParagraphState,
|
|
resetHistory,
|
|
waitNextFrame,
|
|
} from './utils/actions/misc.js';
|
|
import {
|
|
assertBlockChildrenIds,
|
|
assertBlockCount,
|
|
assertBlockFlavour,
|
|
assertBlockSelections,
|
|
assertKeyboardWorkInInput,
|
|
assertParentBlockFlavour,
|
|
assertRichImage,
|
|
assertRichTextInlineRange,
|
|
assertStoreMatchJSX,
|
|
} from './utils/asserts.js';
|
|
import { test } from './utils/playwright.js';
|
|
|
|
const FILE_NAME = 'test-card-1.png';
|
|
const FILE_PATH = `../playground/public/${FILE_NAME}`;
|
|
const FILE_ID = 'ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA=';
|
|
const FILE_SIZE = 45801;
|
|
|
|
function getAttachment(page: Page) {
|
|
const attachment = page.locator('affine-attachment');
|
|
const loading = attachment.locator('.affine-attachment-card.loading');
|
|
const toolbar = page.locator('.affine-attachment-toolbar');
|
|
const switchViewButton = toolbar.getByRole('button', { name: 'Switch view' });
|
|
const renameBtn = toolbar.getByRole('button', { name: 'Rename' });
|
|
const renameInput = page.locator('.affine-attachment-rename-container input');
|
|
|
|
const insertAttachment = async () => {
|
|
await page.evaluate(() => {
|
|
// Force fallback to input[type=file] in tests
|
|
// See https://github.com/microsoft/playwright/issues/8850
|
|
window.showOpenFilePicker = undefined;
|
|
});
|
|
|
|
const slashMenu = page.locator(`.slash-menu`);
|
|
await waitNextFrame(page);
|
|
await type(page, '/');
|
|
await resetHistory(page);
|
|
await expect(slashMenu).toBeVisible();
|
|
await type(page, 'file', 100);
|
|
await expect(slashMenu).toBeVisible();
|
|
|
|
const fileChooser = page.waitForEvent('filechooser');
|
|
await pressEnter(page);
|
|
await sleep(100);
|
|
await (await fileChooser).setFiles(FILE_PATH);
|
|
|
|
// Try to break the undo redo test
|
|
await captureHistory(page);
|
|
|
|
await expect(attachment).toBeVisible();
|
|
};
|
|
|
|
const getName = () =>
|
|
attachment.locator('.affine-attachment-content-title-text').innerText();
|
|
|
|
return {
|
|
// locators
|
|
attachment,
|
|
toolbar,
|
|
switchViewButton,
|
|
renameBtn,
|
|
renameInput,
|
|
|
|
// actions
|
|
insertAttachment,
|
|
/**
|
|
* Wait for the attachment upload to finish
|
|
*/
|
|
waitLoading: () => loading.waitFor({ state: 'hidden' }),
|
|
getName,
|
|
getSize: () =>
|
|
attachment.locator('.affine-attachment-content-info').innerText(),
|
|
|
|
turnToEmbed: async () => {
|
|
await expect(switchViewButton).toBeVisible();
|
|
await switchViewButton.click();
|
|
await page.getByRole('button', { name: 'Embed view' }).click();
|
|
await assertRichImage(page, 1);
|
|
},
|
|
rename: async (newName: string) => {
|
|
await attachment.hover();
|
|
await expect(toolbar).toBeVisible();
|
|
await renameBtn.click();
|
|
await page.keyboard.press(`${SHORT_KEY}+a`, { delay: 50 });
|
|
await pressBackspace(page);
|
|
await type(page, newName);
|
|
await pressEnter(page);
|
|
expect(await getName()).toContain(newName);
|
|
},
|
|
|
|
// external
|
|
turnImageToCard: async () => {
|
|
const { turnIntoCardButton } = await popImageMoreMenu(page);
|
|
await turnIntoCardButton.click();
|
|
await expect(attachment).toBeVisible();
|
|
},
|
|
};
|
|
}
|
|
|
|
test('can insert attachment from slash menu', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
const { noteId } = await initEmptyParagraphState(page);
|
|
|
|
const { insertAttachment, waitLoading, getName, getSize } =
|
|
getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
expect(await getName()).toBe(FILE_NAME);
|
|
expect(await getSize()).toBe('45.8 kB');
|
|
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
});
|
|
|
|
test('should undo/redo works for attachment', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
const { noteId } = await initEmptyParagraphState(page);
|
|
|
|
const { insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
` <affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
|
|
await undoByKeyboard(page);
|
|
await waitNextFrame(page);
|
|
// The loading/error state should not be restored after undo
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="/"
|
|
prop:type="text"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
|
|
await redoByKeyboard(page);
|
|
await waitNextFrame(page);
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
});
|
|
|
|
test('should rename attachment works', async ({ page }) => {
|
|
test.info().annotations.push({
|
|
type: 'issue',
|
|
description: 'https://github.com/toeverything/blocksuite/issues/4534',
|
|
});
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyParagraphState(page);
|
|
const {
|
|
attachment,
|
|
renameBtn,
|
|
renameInput,
|
|
insertAttachment,
|
|
waitLoading,
|
|
getName,
|
|
rename,
|
|
} = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
expect(await getName()).toBe(FILE_NAME);
|
|
|
|
await attachment.hover();
|
|
await expect(renameBtn).toBeVisible();
|
|
await renameBtn.click();
|
|
await assertKeyboardWorkInInput(page, renameInput);
|
|
await pressEscape(page);
|
|
await expect(renameInput).not.toBeVisible();
|
|
|
|
await rename('new-name');
|
|
expect(await getName()).toBe('new-name.png');
|
|
await rename('');
|
|
expect(await getName()).toBe('.png');
|
|
await rename('abc');
|
|
expect(await getName()).toBe('abc');
|
|
});
|
|
|
|
test('should turn attachment to image works', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
const { noteId } = await initEmptyParagraphState(page);
|
|
const { insertAttachment, waitLoading, turnToEmbed, turnImageToCard } =
|
|
getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await turnToEmbed();
|
|
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:image
|
|
prop:caption=""
|
|
prop:height={0}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:width={0}
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
await turnImageToCard();
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:caption=""
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
});
|
|
|
|
test('should attachment can be deleted', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
const { noteId } = await initEmptyParagraphState(page);
|
|
const { attachment, insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await attachment.click();
|
|
await pressBackspace(page);
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
`
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:type="text"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
});
|
|
|
|
test.fixme(`support dragging attachment block directly`, async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
const { noteId } = await initEmptyParagraphState(page);
|
|
|
|
const { insertAttachment, waitLoading, getName, getSize } =
|
|
getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
expect(await getName()).toBe(FILE_NAME);
|
|
expect(await getSize()).toBe('45.8 kB');
|
|
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
` <affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
</affine:note>`,
|
|
noteId
|
|
);
|
|
|
|
const attachmentBlock = page.locator('affine-attachment');
|
|
const rect = await attachmentBlock.boundingBox();
|
|
if (!rect) {
|
|
throw new Error('image not found');
|
|
}
|
|
|
|
// add new paragraph blocks
|
|
await page.mouse.click(rect.x + 20, rect.y + rect.height + 20);
|
|
await focusRichText(page);
|
|
await type(page, '111');
|
|
await page.waitForTimeout(200);
|
|
await pressEnter(page);
|
|
|
|
await type(page, '222');
|
|
await page.waitForTimeout(200);
|
|
await pressEnter(page);
|
|
|
|
await type(page, '333');
|
|
await page.waitForTimeout(200);
|
|
|
|
await page.waitForTimeout(200);
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
/*xml*/ `<affine:page>
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="111"
|
|
prop:type="text"
|
|
/>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="222"
|
|
prop:type="text"
|
|
/>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="333"
|
|
prop:type="text"
|
|
/>
|
|
</affine:note>
|
|
</affine:page>`
|
|
);
|
|
|
|
// drag bookmark block
|
|
await page.mouse.move(rect.x + 20, rect.y + 20);
|
|
await page.mouse.down();
|
|
await page.mouse.move(rect.x + 40, rect.y + rect.height + 80, { steps: 20 });
|
|
await page.mouse.up();
|
|
|
|
const rects = page.locator('affine-block-selection').locator('visible=true');
|
|
await expect(rects).toHaveCount(1);
|
|
|
|
await assertStoreMatchJSX(
|
|
page,
|
|
/*xml*/ `<affine:page>
|
|
<affine:note
|
|
prop:background="--affine-v2-edgeless-note-white"
|
|
prop:displayMode="both"
|
|
prop:edgeless={
|
|
Object {
|
|
"style": Object {
|
|
"borderRadius": 8,
|
|
"borderSize": 4,
|
|
"borderStyle": "none",
|
|
"shadowType": "--affine-note-shadow-box",
|
|
},
|
|
}
|
|
}
|
|
prop:hidden={false}
|
|
prop:index="a0"
|
|
prop:lockedBySelf={false}
|
|
>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="111"
|
|
prop:type="text"
|
|
/>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="222"
|
|
prop:type="text"
|
|
/>
|
|
<affine:attachment
|
|
prop:embed={false}
|
|
prop:index="a0"
|
|
prop:name="${FILE_NAME}"
|
|
prop:rotate={0}
|
|
prop:size={${FILE_SIZE}}
|
|
prop:sourceId="${FILE_ID}"
|
|
prop:style="horizontalThin"
|
|
prop:type="image/png"
|
|
/>
|
|
<affine:paragraph
|
|
prop:collapsed={false}
|
|
prop:text="333"
|
|
prop:type="text"
|
|
/>
|
|
</affine:note>
|
|
</affine:page>`
|
|
);
|
|
});
|
|
|
|
test('press backspace after bookmark block can select bookmark block', async ({
|
|
page,
|
|
}) => {
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyParagraphState(page);
|
|
const { insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await pressEnter(page);
|
|
await pressArrowUp(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await focusRichText(page);
|
|
await assertBlockCount(page, 'paragraph', 1);
|
|
await assertRichTextInlineRange(page, 0, 0);
|
|
await pressBackspace(page);
|
|
await assertBlockSelections(page, ['4']);
|
|
await assertBlockCount(page, 'paragraph', 0);
|
|
});
|
|
|
|
test('cancel file picker with input element resolves', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyParagraphState(page);
|
|
|
|
const { attachment } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await pressEnter(page);
|
|
await pressArrowUp(page);
|
|
|
|
await page.evaluate(() => {
|
|
// Force fallback to input[type=file]
|
|
window.showOpenFilePicker = undefined;
|
|
});
|
|
|
|
const slashMenu = page.locator(`.slash-menu`);
|
|
await waitNextFrame(page);
|
|
await type(page, '/file', 100);
|
|
await expect(slashMenu).toBeVisible();
|
|
|
|
const fileChooser = page.waitForEvent('filechooser');
|
|
await pressEnter(page);
|
|
const inputFile = page.locator("input[type='file']");
|
|
await expect(inputFile).toHaveCount(1);
|
|
|
|
// This does not trigger `cancel` event and,
|
|
// therefore, the test isn't representative.
|
|
// Waiting for https://github.com/microsoft/playwright/issues/27524
|
|
await (await fileChooser).setFiles([]);
|
|
|
|
await expect(attachment).toHaveCount(0);
|
|
await expect(inputFile).toHaveCount(0);
|
|
});
|
|
|
|
test('indent attachment block to paragraph', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyParagraphState(page);
|
|
const { insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await pressEnter(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await assertBlockChildrenIds(page, '1', ['2', '4']);
|
|
await assertBlockFlavour(page, '1', 'affine:note');
|
|
await assertBlockFlavour(page, '2', 'affine:paragraph');
|
|
await assertBlockFlavour(page, '4', 'affine:attachment');
|
|
|
|
await focusRichText(page);
|
|
await pressArrowDown(page);
|
|
await assertBlockSelections(page, ['4']);
|
|
await pressTab(page);
|
|
await assertBlockChildrenIds(page, '1', ['2']);
|
|
await assertBlockChildrenIds(page, '2', ['4']);
|
|
|
|
await pressShiftTab(page);
|
|
await assertBlockChildrenIds(page, '1', ['2', '4']);
|
|
});
|
|
|
|
test('indent attachment block to list', async ({ page }) => {
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyParagraphState(page);
|
|
const { insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await type(page, '- a');
|
|
await pressEnter(page);
|
|
await insertAttachment();
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await assertBlockChildrenIds(page, '1', ['3', '5']);
|
|
await assertBlockFlavour(page, '1', 'affine:note');
|
|
await assertBlockFlavour(page, '3', 'affine:list');
|
|
await assertBlockFlavour(page, '5', 'affine:attachment');
|
|
|
|
await focusRichText(page);
|
|
await pressArrowDown(page);
|
|
await assertBlockSelections(page, ['5']);
|
|
await pressTab(page);
|
|
await assertBlockChildrenIds(page, '1', ['3']);
|
|
await assertBlockChildrenIds(page, '3', ['5']);
|
|
|
|
await pressShiftTab(page);
|
|
await assertBlockChildrenIds(page, '1', ['3', '5']);
|
|
});
|
|
|
|
test('attachment can be dragged from note to surface top level block', async ({
|
|
page,
|
|
}) => {
|
|
await enterPlaygroundRoom(page);
|
|
await initEmptyEdgelessState(page);
|
|
const { insertAttachment, waitLoading } = getAttachment(page);
|
|
|
|
await focusRichText(page);
|
|
await insertAttachment();
|
|
|
|
// Wait for the attachment to be uploaded
|
|
await waitLoading();
|
|
|
|
await switchEditorMode(page);
|
|
await page.mouse.dblclick(450, 450);
|
|
|
|
await dragBlockToPoint(page, '4', { x: 200, y: 200 });
|
|
|
|
await waitNextFrame(page);
|
|
await assertParentBlockFlavour(page, '4', 'affine:surface');
|
|
});
|