test(editor): remove jsx snapshot (#9463)

This commit is contained in:
Saul-Mirone
2024-12-31 10:27:12 +00:00
parent 6c33eaace0
commit 36c1b103df
57 changed files with 2743 additions and 1656 deletions

View File

@@ -1,3 +1,6 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { sleep } from '@blocksuite/global/utils';
import { expect, type Page } from '@playwright/test';
import { switchEditorMode } from 'utils/actions/edgeless.js';
@@ -20,6 +23,7 @@ import {
captureHistory,
enterPlaygroundRoom,
focusRichText,
getPageSnapshot,
initEmptyEdgelessState,
initEmptyParagraphState,
resetHistory,
@@ -34,14 +38,12 @@ import {
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;
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const FILE_PATH = path.resolve(__dirname, `../playground/public/${FILE_NAME}`);
function getAttachment(page: Page) {
const attachment = page.locator('affine-attachment');
@@ -124,9 +126,9 @@ function getAttachment(page: Page) {
};
}
test('can insert attachment from slash menu', async ({ page }) => {
test('can insert attachment from slash menu', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { noteId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
const { insertAttachment, waitLoading, getName, getSize } =
getAttachment(page);
@@ -140,50 +142,14 @@ test('can insert attachment from slash menu', async ({ page }) => {
expect(await getName()).toBe(FILE_NAME);
expect(await getSize()).toBe('45.8 kB');
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('should undo/redo works for attachment', async ({ page }) => {
test('should undo/redo works for attachment', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { noteId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
const { insertAttachment, waitLoading } = getAttachment(page);
@@ -193,122 +159,24 @@ test('should undo/redo works for attachment', async ({ page }) => {
// Wait for the attachment to be uploaded
await waitLoading();
await assertStoreMatchJSX(
page,
` <affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await undoByKeyboard(page);
await waitNextFrame(page);
// The loading/error state should not be restored after undo
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
await redoByKeyboard(page);
await waitNextFrame(page);
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
// The loading/error state should not be restored after undo
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_3.json`
);
});
@@ -351,9 +219,9 @@ test('should rename attachment works', async ({ page }) => {
expect(await getName()).toBe('abc');
});
test('should turn attachment to image works', async ({ page }) => {
test('should turn attachment to image works', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { noteId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
const { insertAttachment, waitLoading, turnToEmbed, turnImageToCard } =
getAttachment(page);
@@ -364,90 +232,18 @@ test('should turn attachment to image works', async ({ page }) => {
await turnToEmbed();
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await turnImageToCard();
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
});
test('should attachment can be deleted', async ({ page }) => {
test('should attachment can be deleted', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { noteId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
const { attachment, insertAttachment, waitLoading } = getAttachment(page);
await focusRichText(page);
@@ -457,38 +253,16 @@ test('should attachment can be deleted', async ({ page }) => {
await attachment.click();
await pressBackspace(page);
await assertStoreMatchJSX(
page,
`
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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}
/>`,
noteId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test.fixme(`support dragging attachment block directly`, async ({ page }) => {
test(`support dragging attachment block directly`, async ({
page,
}, testInfo) => {
await enterPlaygroundRoom(page);
const { noteId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
const { insertAttachment, waitLoading, getName, getSize } =
getAttachment(page);
@@ -502,43 +276,8 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
expect(await getName()).toBe(FILE_NAME);
expect(await getSize()).toBe('45.8 kB');
await assertStoreMatchJSX(
page,
` <affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
const attachmentBlock = page.locator('affine-attachment');
@@ -562,58 +301,8 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
await page.waitForTimeout(200);
await page.waitForTimeout(200);
await assertStoreMatchJSX(
page,
/*xml*/ `<affine:page>
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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>`
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
// drag bookmark block
@@ -624,59 +313,8 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
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={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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>`
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_3.json`
);
});

View File

@@ -1,4 +1,5 @@
import { expect } from '@playwright/test';
import type { BlockSnapshot } from '@store/index.js';
import { lightThemeV2 } from '@toeverything/theme/v2';
import { initDatabaseColumn } from '../database/actions.js';
@@ -53,7 +54,6 @@ import {
assertExists,
assertRichTextModelType,
assertRichTexts,
assertStoreMatchJSX,
assertText,
} from '../utils/asserts.js';
import { scoped, test } from '../utils/playwright.js';
@@ -437,104 +437,17 @@ test(scoped`should copy and paste of database work`, async ({ page }) => {
await pasteByKeyboard(page);
await page.waitForTimeout(100);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:page>
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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:database
prop:columns="Array [2]"
prop:title="Database 1"
prop:views="Array [1]"
>
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>
</affine:database>
<affine:database
prop:columns="Array [2]"
prop:title="Database 1"
prop:views="Array [1]"
>
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>
</affine:database>
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>
</affine:note>
</affine:page>`
);
let pageJson = await getPageSnapshot(page, false);
let note = (pageJson as BlockSnapshot).children[0];
const database = note.children[0];
expect(database.flavour).toBe('affine:database');
await undoByKeyboard(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:page>
<affine:note
prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
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:database
prop:columns="Array [2]"
prop:title="Database 1"
prop:views="Array [1]"
>
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>
</affine:database>
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>
</affine:note>
</affine:page>`
);
pageJson = await getPageSnapshot(page, false);
note = (pageJson as BlockSnapshot).children[0];
const db = note.children.find(child => child.flavour === 'affine:database');
expect(db).toBeDefined();
});
test(`copy canvas element and text note in edgeless mode`, async ({ page }) => {

View File

@@ -29,7 +29,6 @@ import {
import {
assertBlockCount,
assertRichTexts,
assertStoreMatchJSX,
assertTitle,
} from '../utils/asserts.js';
import { test } from '../utils/playwright.js';
@@ -150,9 +149,9 @@ test('use shortcut can create code block', async ({ page }) => {
await expect(locator).toBeVisible();
});
test('change code language can work', async ({ page }) => {
test('change code language can work', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await initEmptyCodeBlockState(page);
await focusRichText(page);
const codeBlockController = getCodeBlock(page);
@@ -170,26 +169,12 @@ test('change code language can work', async ({ page }) => {
await codeBlockController.codeBlock.hover();
await expect(codeBlockController.languageButton).toHaveText('Rust');
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language="rust"
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await undoByKeyboard(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
// Can switch to another language
@@ -273,54 +258,33 @@ test('undo and redo works in code block', async ({ page }) => {
await assertRichTexts(page, ['const a = 10;']);
});
test('toggle code block wrap can work', async ({ page }) => {
test('toggle code block wrap can work', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await initEmptyCodeBlockState(page);
const codeBlockController = getCodeBlock(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await codeBlockController.codeBlock.hover();
await (await codeBlockController.openMore()).wrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={true}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
await codeBlockController.codeBlock.hover();
await (await codeBlockController.openMore()).cancelWrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_3.json`
);
});
test('add caption works', async ({ page }) => {
test('add caption works', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await initEmptyCodeBlockState(page);
const codeBlockController = getCodeBlock(page);
await codeBlockController.codeBlock.hover();
@@ -329,59 +293,31 @@ test('add caption works', async ({ page }) => {
await pressEnter(page);
await waitNextFrame(page, 100);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption="BlockSuite"
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('undo code block wrap can work', async ({ page }) => {
test('undo code block wrap can work', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await initEmptyCodeBlockState(page);
await focusRichText(page);
const codeBlockController = getCodeBlock(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await codeBlockController.codeBlock.hover();
await (await codeBlockController.openMore()).wrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={true}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
await focusRichText(page);
await undoByKeyboard(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:caption=""
prop:language={null}
prop:wrap={false}
/>`,
codeBlockId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_3.json`
);
});

View File

@@ -20,10 +20,7 @@ import {
type,
waitNextFrame,
} from './utils/actions/index.js';
import {
assertKeyboardWorkInInput,
assertStoreMatchJSX,
} from './utils/asserts.js';
import { assertKeyboardWorkInInput } from './utils/asserts.js';
import { test } from './utils/playwright.js';
const pressCreateLinkShortCut = async (page: Page) => {
@@ -146,63 +143,26 @@ async function createLinkBlock(page: Page, str: string, link: string) {
test('type character in link should not jump out link node', async ({
page,
}) => {
}, testInfo) => {
await enterPlaygroundRoom(page);
const id = await createLinkBlock(page, 'link text', 'http://example.com');
await createLinkBlock(page, 'link text', 'http://example.com');
await focusRichText(page, 0);
await page.keyboard.press('ArrowLeft');
await type(page, 'IN_LINK');
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="Hello"
/>
<text
insert="link texIN_LINKt"
link="http://example.com"
/>
</>
}
prop:type="text"
/>`,
id
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('type character after link should not extend the link attributes', async ({
page,
}) => {
}, testInfo) => {
await enterPlaygroundRoom(page);
const id = await createLinkBlock(page, 'link text', 'http://example.com');
await createLinkBlock(page, 'link text', 'http://example.com');
await focusRichText(page, 0);
await type(page, 'AFTER_LINK');
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="Hello"
/>
<text
insert="link text"
link="http://example.com"
/>
<text
insert="AFTER_LINK"
/>
</>
}
prop:type="text"
/>`,
id
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
@@ -237,11 +197,11 @@ test('readonly mode should not trigger link popup', async ({ page }) => {
await expect(linkPopoverInput).not.toBeVisible();
});
test('should mock selection not stored', async ({ page }) => {
test('should mock selection not stored', async ({ page }, testInfo) => {
const linkText = 'linkText';
const link = 'http://example.com';
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, linkText);
@@ -254,15 +214,8 @@ test('should mock selection not stored', async ({ page }) => {
await expect(mockSelectNode).toBeVisible();
// the mock select node should not be stored in the Y doc
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="linkText"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
await type(page, link);
@@ -346,9 +299,9 @@ test('link bar should not be appear when the range is collapsed', async ({
await expect(linkPopoverLocator).toBeVisible();
});
test('create link with paste', async ({ page }) => {
test('create link with paste', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, 'aaa');
@@ -375,22 +328,8 @@ test('create link with paste', async ({ page }) => {
await expect(confirmBtn).not.toHaveAttribute('disabled');
await pressEnter(page);
await expect(createLinkPopoverLocator).not.toBeVisible();
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="aaa"
link="http://affine.pro"
/>
</>
}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
@@ -447,8 +386,7 @@ test('convert link to card', async ({ page }, testInfo) => {
await expect(linkToEmbedBtn).not.toBeVisible();
});
//TODO: wait for embed block completed
test.skip('convert link to embed', async ({ page }) => {
test('convert link to embed', async ({ page }, testInfo) => {
const linkText = 'alinkTexta';
const link = 'https://www.youtube.com/watch?v=U6s2pdxebSo';
await enterPlaygroundRoom(page);
@@ -471,73 +409,13 @@ test.skip('convert link to embed', async ({ page }) => {
await expect(linkPopoverLocator).not.toBeVisible();
await focusRichText(page);
await assertStoreMatchJSX(
page,
`
<affine:page>
<affine:note
prop:background="--affine-note-background-blue"
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="aaa"
prop:type="text"
/>
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="a"
/>
<text
insert="linkText"
link="${link}"
/>
<text
insert="a"
/>
</>
}
prop:type="text"
/>
</affine:note>
</affine:page>`
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
const linkToCardBtn = page.getByTestId('link-to-card');
const linkToEmbedBtn = page.getByTestId('link-to-embed');
const linkLocator = page.locator('affine-link a');
await linkLocator.hover();
await waitNextFrame(page);
await expect(linkPopoverLocator).toBeVisible();
await expect(linkToCardBtn).toBeVisible();
await expect(linkToEmbedBtn).toBeVisible();
await page.mouse.move(0, 0);
await waitNextFrame(page);
await expect(linkPopoverLocator).not.toBeVisible();
await focusRichText(page, 1);
await pressTab(page);
await linkLocator.hover();
await waitNextFrame(page);
await expect(linkPopoverLocator).toBeVisible();
await expect(linkToCardBtn).not.toBeVisible();
await expect(linkToEmbedBtn).not.toBeVisible();
});

View File

@@ -16,11 +16,9 @@ import {
pressArrowRight,
pressBackspace,
pressEnter,
redoByKeyboard,
selectAllByKeyboard,
SHORT_KEY,
type,
undoByKeyboard,
} from './utils/actions/keyboard.js';
import {
captureHistory,
@@ -37,7 +35,6 @@ import {
assertExists,
assertParentBlockFlavour,
assertRichTexts,
assertStoreMatchJSX,
assertTitle,
} from './utils/asserts.js';
import { test } from './utils/playwright.js';
@@ -95,22 +92,17 @@ test.describe('multiple page', () => {
});
test.describe('reference node', () => {
test('linked doc popover can show and hide correctly', async ({ page }) => {
test('linked doc popover can show and hide correctly', async ({
page,
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, '[[');
// `[[` should be converted to `@`
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="@"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
const { linkedDocPopover } = getLinkedDocPopover(page);
await expect(linkedDocPopover).toBeVisible();
@@ -140,46 +132,23 @@ test.describe('reference node', () => {
await expect(linkedDocPopover).toBeHidden();
});
test('should reference node attributes correctly', async ({ page }) => {
test('should reference node attributes correctly', async ({
page,
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
const { id } = await addNewPage(page);
await initEmptyParagraphState(page);
await addNewPage(page);
await focusRichText(page);
await type(page, '[[');
await pressEnter(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
</>
}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await pressBackspace(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
});
@@ -211,10 +180,10 @@ test.describe('reference node', () => {
test('text inserted in the between of reference nodes should not be extend attributes', async ({
page,
}) => {
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
const { id } = await addNewPage(page);
await initEmptyParagraphState(page);
await addNewPage(page);
await focusRichText(page);
await type(page, '1');
@@ -234,51 +203,17 @@ test.describe('reference node', () => {
await type(page, '3');
await assertRichTexts(page, ['1 3 2']);
const snapshot = `
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="1"
/>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
<text
insert="3"
/>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
<text
insert="2"
/>
</>
}
prop:type="text"
/>`;
await assertStoreMatchJSX(page, snapshot, paragraphId);
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('text can be inserted as expected when reference node is in the start or end of line', async ({
page,
}) => {
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
const { id } = await addNewPage(page);
await initEmptyParagraphState(page);
await addNewPage(page);
await focusRichText(page);
await type(page, '@');
@@ -304,51 +239,17 @@ test.describe('reference node', () => {
await type(page, '1');
await assertRichTexts(page, ['1 3 2']);
const snapshot = `
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="1"
/>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
<text
insert="3"
/>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
<text
insert="2"
/>
</>
}
prop:type="text"
/>`;
await assertStoreMatchJSX(page, snapshot, paragraphId);
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('should the cursor move correctly around reference node', async ({
page,
}) => {
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
const { id } = await addNewPage(page);
await initEmptyParagraphState(page);
await addNewPage(page);
await focusRichText(page);
await type(page, '1');
@@ -370,57 +271,16 @@ test.describe('reference node', () => {
await type(page, '4');
await assertRichTexts(page, ['14 32']);
const snapshot = `
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="14"
/>
<text
insert=" "
reference={
Object {
"pageId": "${id}",
"type": "LinkedPage",
}
}
/>
<text
insert="32"
/>
</>
}
prop:type="text"
/>`;
await assertStoreMatchJSX(page, snapshot, paragraphId);
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await page.keyboard.press('ArrowRight');
await captureHistory(page);
await pressBackspace(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="1432"
prop:type="text"
/>`,
paragraphId
);
await undoByKeyboard(page);
await assertStoreMatchJSX(page, snapshot, paragraphId);
await redoByKeyboard(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="1432"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
});
@@ -747,13 +607,15 @@ test.describe('linked page with clipboard', () => {
});
});
test('should [[Selected text]] converted to linked page', async ({ page }) => {
test('should [[Selected text]] converted to linked page', async ({
page,
}, testInfo) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/toeverything/blocksuite/issues/2730',
});
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, '1234');
@@ -761,33 +623,8 @@ test('should [[Selected text]] converted to linked page', async ({ page }) => {
await type(page, '[');
await assertRichTexts(page, ['1[2]34']);
await type(page, '[');
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
insert="1"
/>
<text
insert=" "
reference={
Object {
"pageId": "3",
"type": "LinkedPage",
}
}
/>
<text
insert="34"
/>
</>
}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
await switchToPage(page, '3');
await assertTitle(page, '2');

View File

@@ -50,7 +50,6 @@ import {
assertDocTitleFocus,
assertRichTextInlineRange,
assertRichTexts,
assertStoreMatchJSX,
assertTitle,
} from './utils/asserts.js';
import { test } from './utils/playwright.js';
@@ -1296,9 +1295,11 @@ test.describe('readonly mode', () => {
await expect(placeholder).toBeHidden();
});
test('should readonly mode not be able to modify text', async ({ page }) => {
test('should readonly mode not be able to modify text', async ({
page,
}, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, 'hello');
@@ -1308,27 +1309,13 @@ test.describe('readonly mode', () => {
await type(page, 'world');
await dragBetweenIndices(page, [0, 1], [0, 3]);
await page.keyboard.press(`${SHORT_KEY}+b`);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="hello"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_1.json`
);
await undoByKeyboard(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="hello"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}_2.json`
);
});
});

View File

@@ -34,7 +34,6 @@ import {
assertBlockCount,
assertExists,
assertRichTexts,
assertStoreMatchJSX,
} from './utils/asserts.js';
import { test } from './utils/playwright.js';
@@ -62,9 +61,10 @@ test.describe('slash menu should show and hide correctly', () => {
await expect(slashMenu).toBeVisible();
});
test('slash menu should hide after click away', async ({ page }) => {
const id = await initEmptyParagraphState(page);
const paragraphId = id.paragraphId;
test('slash menu should hide after click away', async ({
page,
}, testInfo) => {
await initEmptyParagraphState(page);
const slashMenu = page.locator(`.slash-menu`);
await focusRichText(page);
await type(page, '/');
@@ -72,15 +72,9 @@ test.describe('slash menu should show and hide correctly', () => {
// Click outside should close slash menu
await page.mouse.click(0, 50);
await expect(slashMenu).toBeHidden();
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="/"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
@@ -106,9 +100,8 @@ test.describe('slash menu should show and hide correctly', () => {
test('delete the slash symbol should close the slash menu', async ({
page,
}) => {
const id = await initEmptyParagraphState(page);
const paragraphId = id.paragraphId;
}, testInfo) => {
await initEmptyParagraphState(page);
const slashMenu = page.locator(`.slash-menu`);
await focusRichText(page);
await type(page, '/');
@@ -116,14 +109,8 @@ test.describe('slash menu should show and hide correctly', () => {
await pressBackspace(page);
await expect(slashMenu).toBeHidden();
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
@@ -522,13 +509,15 @@ test('should slash menu works with fast type', async ({ page }) => {
await expect(slashMenu).toBeVisible();
});
test('should clean slash string after soft enter', async ({ page }) => {
test('should clean slash string after soft enter', async ({
page,
}, testInfo) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/toeverything/blocksuite/issues/1126',
});
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, 'hello');
await pressShiftEnter(page);
@@ -536,15 +525,8 @@ test('should clean slash string after soft enter', async ({ page }) => {
await type(page, '/copy');
await pressEnter(page);
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text="hello\n"
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
@@ -720,9 +702,9 @@ test.describe('slash menu with date & time', () => {
});
test.describe('slash menu with style', () => {
test('should style text line works', async ({ page }) => {
test('should style text line works', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, 'hello/');
@@ -730,28 +712,15 @@ test.describe('slash menu with style', () => {
await expect(slashMenu).toBeVisible();
const bold = page.getByTestId('Bold');
await bold.click();
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
bold={true}
insert="hello"
/>
</>
}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
test('should style empty line works', async ({ page }) => {
test('should style empty line works', async ({ page }, testInfo) => {
await enterPlaygroundRoom(page);
const { paragraphId } = await initEmptyParagraphState(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, '/');
@@ -761,22 +730,9 @@ test.describe('slash menu with style', () => {
await bold.click();
await page.waitForTimeout(50);
await type(page, 'hello');
await assertStoreMatchJSX(
page,
`
<affine:paragraph
prop:collapsed={false}
prop:text={
<>
<text
bold={true}
insert="hello"
/>
</>
}
prop:type="text"
/>`,
paragraphId
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
`${testInfo.title}.json`
);
});
});

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,40 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": []
}
]
}

View File

@@ -0,0 +1,59 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "4",
"flavour": "affine:image",
"version": 1,
"props": {
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA=",
"width": 0,
"height": 0,
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"size": 45801,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,61 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "5",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA=",
"caption": "",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "/"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
},
{
"type": "block",
"id": "4",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "111"
}
]
},
"collapsed": false
},
"children": []
},
{
"type": "block",
"id": "5",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "222"
}
]
},
"collapsed": false
},
"children": []
},
{
"type": "block",
"id": "6",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "333"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,117 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "4",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "111"
}
]
},
"collapsed": false
},
"children": []
},
{
"type": "block",
"id": "5",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "222"
}
]
},
"collapsed": false
},
"children": []
},
{
"type": "block",
"id": "3",
"flavour": "affine:attachment",
"version": 1,
"props": {
"name": "test-card-1.png",
"size": 45801,
"type": "image/png",
"embed": false,
"style": "horizontalThin",
"index": "a0",
"xywh": "[0,0,0,0]",
"lockedBySelf": false,
"rotate": 0,
"sourceId": "ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA="
},
"children": []
},
{
"type": "block",
"id": "6",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "333"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,72 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": "BlockSuite"
},
"children": []
},
{
"type": "block",
"id": "3",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": "rust",
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": true,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": true,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,57 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:code",
"version": 1,
"props": {
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"language": null,
"wrap": false,
"caption": ""
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,88 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "aaa"
}
]
},
"collapsed": false
},
"children": []
},
{
"type": "block",
"id": "3",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "a"
},
{
"insert": "linkText",
"attributes": {
"link": "https://www.youtube.com/watch?v=U6s2pdxebSo"
}
},
{
"insert": "a"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,63 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "aaa",
"attributes": {
"link": "http://affine.pro"
}
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "linkText"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,73 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "title"
}
]
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "Hello"
},
{
"insert": "link text",
"attributes": {
"link": "http://example.com"
}
},
{
"insert": "AFTER_LINK"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,70 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "title"
}
]
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "Hello"
},
{
"insert": "link texIN_LINKt",
"attributes": {
"link": "http://example.com"
}
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "@"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,72 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "1"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "34"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,66 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,56 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,72 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "14"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "32"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "1432"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,84 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "1"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "3"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "2"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,84 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "1"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "3"
},
{
"insert": " ",
"attributes": {
"reference": {
"type": "LinkedPage",
"pageId": "3"
}
}
},
{
"insert": "2"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "hello"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "hello"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,56 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": []
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "hello\n"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,63 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "hello",
"attributes": {
"bold": true
}
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,63 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "hello",
"attributes": {
"bold": true
}
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -0,0 +1,60 @@
{
"type": "block",
"id": "0",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": []
}
},
"children": [
{
"type": "block",
"id": "1",
"flavour": "affine:note",
"version": 1,
"props": {
"xywh": "[0,0,498,92]",
"background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0",
"lockedBySelf": false,
"hidden": false,
"displayMode": "both",
"edgeless": {
"style": {
"borderRadius": 8,
"borderSize": 4,
"borderStyle": "none",
"shadowType": "--affine-note-shadow-box"
}
}
},
"children": [
{
"type": "block",
"id": "2",
"flavour": "affine:paragraph",
"version": 1,
"props": {
"type": "text",
"text": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "/"
}
]
},
"collapsed": false
},
"children": []
}
]
}
]
}

View File

@@ -18,11 +18,6 @@ import type { InlineRootElement } from '@inline/inline-editor.js';
import { expect, type Locator, type Page } from '@playwright/test';
import { COLLECTION_VERSION, PAGE_VERSION } from '@store/consts.js';
import type { BlockModel } from '@store/index.js';
import type { JSXElement } from '@store/utils/jsx.js';
import {
format as prettyFormat,
plugins as prettyFormatPlugins,
} from 'pretty-format';
import {
getCanvasElementsCount,
@@ -50,7 +45,6 @@ import {
import {
captureHistory,
getClipboardCustomData,
getCurrentEditorDocId,
getCurrentThemeCSSPropertyValue,
getEditorLocator,
inlineEditorInnerTextToString,
@@ -633,116 +627,6 @@ export async function assertBlockTypes(page: Page, blockTypes: string[]) {
expect(actual).toEqual(blockTypes);
}
/**
* @example
* ```ts
* await assertMatchMarkdown(
* page,
* `title
* text1
* text2`
* );
* ```
* @deprecated experimental, use {@link assertStoreMatchJSX} instead
*/
export async function assertMatchMarkdown(page: Page, text: string) {
const jsonDoc = (await page.evaluate(() =>
window.collection.doc.toJSON()
)) as Record<string, Record<string, unknown>>;
const titleNode = jsonDoc['doc:home']['0'] as Record<string, unknown>;
const markdownVisitor = (node: Record<string, unknown>): string => {
// TODO use schema
if (node['sys:flavour'] === 'affine:page') {
return (node['prop:title'] as Text).toString() ?? '';
}
if (!('prop:type' in node)) {
return '[? unknown node]';
}
if (node['prop:type'] === 'text') {
return node['prop:text'] as string;
}
if (node['prop:type'] === 'bulleted') {
return `- ${node['prop:text']}`;
}
// TODO please fix this
return `[? ${node['prop:type']} node]`;
};
const INDENT_SIZE = 2;
const visitNodes = (
node: Record<string, unknown>,
visitor: (node: Record<string, unknown>) => string
): string[] => {
if (!('sys:children' in node) || !Array.isArray(node['sys:children'])) {
throw new Error("Failed to visit nodes: 'sys:children' is not an array");
// return visitor(node);
}
const children = node['sys:children'].map(id => jsonDoc['doc:home'][id]);
return [
visitor(node),
...children.flatMap(child =>
visitNodes(child as Record<string, unknown>, visitor).map(line => {
if (node['sys:flavour'] === 'affine:page') {
// Ad hoc way to remove the title indent
return line;
}
return ' '.repeat(INDENT_SIZE) + line;
})
),
];
};
const visitRet = visitNodes(titleNode, markdownVisitor);
const actual = visitRet.join('\n');
expect(actual).toEqual(text);
}
export async function assertStoreMatchJSX(
page: Page,
snapshot: string,
blockId?: string
) {
const docId = await getCurrentEditorDocId(page);
const element = (await page.evaluate(
([blockId, docId]) => window.collection.exportJSX(blockId, docId),
[blockId, docId]
)) as JSXElement;
// Fix symbol can not be serialized, we need to set $$typeof manually
// If the function passed to the page.evaluate(pageFunction[, arg]) returns a non-Serializable value,
// then page.evaluate(pageFunction[, arg]) resolves to undefined.
// See https://playwright.dev/docs/api/class-page#page-evaluate
const testSymbol = Symbol.for('react.test.json');
const markSymbol = (node: JSXElement) => {
node.$$typeof = testSymbol;
if (!node.children) {
return;
}
const propText = node.props['prop:text'];
if (propText && typeof propText === 'object') {
markSymbol(propText);
}
node.children.forEach(child => {
if (!(typeof child === 'object')) {
return;
}
markSymbol(child);
});
};
markSymbol(element);
// See https://github.com/facebook/jest/blob/main/packages/pretty-format
const formattedJSX = prettyFormat(element, {
plugins: [prettyFormatPlugins.ReactTestComponent],
printFunctionName: false,
});
expect(formattedJSX, formattedJSX).toEqual(snapshot.trimStart());
}
type MimeType = 'text/plain' | 'blocksuite/x-c+w' | 'text/html';
export function assertClipItems(_page: Page, _key: MimeType, _value: unknown) {