test(editor): remove jsx snapshot (#9463)
This commit is contained in:
@@ -865,68 +865,6 @@ describe('getBlock', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inline snapshot is not supported under describe.parallel config
|
|
||||||
describe('collection.exportJSX works', () => {
|
|
||||||
it('collection matches snapshot', () => {
|
|
||||||
const options = createTestOptions();
|
|
||||||
const collection = new DocCollection(options);
|
|
||||||
collection.meta.initialize();
|
|
||||||
const doc = collection.createDoc({ id: 'doc:home' });
|
|
||||||
|
|
||||||
doc.addBlock('affine:page', { title: new doc.Text('hello') });
|
|
||||||
|
|
||||||
expect(collection.exportJSX()).toMatchInlineSnapshot(`
|
|
||||||
<affine:page
|
|
||||||
prop:count={0}
|
|
||||||
prop:items={[]}
|
|
||||||
prop:style={{}}
|
|
||||||
prop:title="hello"
|
|
||||||
/>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('empty collection matches snapshot', () => {
|
|
||||||
const options = createTestOptions();
|
|
||||||
const collection = new DocCollection(options);
|
|
||||||
collection.meta.initialize();
|
|
||||||
collection.createDoc({ id: 'doc:home' });
|
|
||||||
|
|
||||||
expect(collection.exportJSX()).toMatchInlineSnapshot('null');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('collection with multiple blocks children matches snapshot', () => {
|
|
||||||
const options = createTestOptions();
|
|
||||||
const collection = new DocCollection(options);
|
|
||||||
collection.meta.initialize();
|
|
||||||
const doc = collection.createDoc({ id: 'doc:home' });
|
|
||||||
doc.load(() => {
|
|
||||||
const rootId = doc.addBlock('affine:page', {
|
|
||||||
title: new doc.Text(),
|
|
||||||
});
|
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
|
||||||
doc.addBlock('affine:paragraph', {}, noteId);
|
|
||||||
doc.addBlock('affine:paragraph', {}, noteId);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(collection.exportJSX()).toMatchInlineSnapshot(/* xml */ `
|
|
||||||
<affine:page
|
|
||||||
prop:count={0}
|
|
||||||
prop:items={[]}
|
|
||||||
prop:style={{}}
|
|
||||||
>
|
|
||||||
<affine:note>
|
|
||||||
<affine:paragraph
|
|
||||||
prop:type="text"
|
|
||||||
/>
|
|
||||||
<affine:paragraph
|
|
||||||
prop:type="text"
|
|
||||||
/>
|
|
||||||
</affine:note>
|
|
||||||
</affine:page>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('flags', () => {
|
describe('flags', () => {
|
||||||
it('update flags', () => {
|
it('update flags', () => {
|
||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
// checkout https://vitest.dev/guide/debugging.html for debugging tests
|
|
||||||
|
|
||||||
import { describe, expect, it } from 'vitest';
|
|
||||||
|
|
||||||
import { yDocToJSXNode } from '../utils/jsx.js';
|
|
||||||
|
|
||||||
describe('basic', () => {
|
|
||||||
it('serialized doc match snapshot', () => {
|
|
||||||
expect(
|
|
||||||
yDocToJSXNode(
|
|
||||||
{
|
|
||||||
'0': {
|
|
||||||
'sys:id': '0',
|
|
||||||
'sys:children': ['1'],
|
|
||||||
'sys:flavour': 'affine:page',
|
|
||||||
},
|
|
||||||
'1': {
|
|
||||||
'sys:id': '1',
|
|
||||||
'sys:children': [],
|
|
||||||
'sys:flavour': 'affine:paragraph',
|
|
||||||
'prop:text': [],
|
|
||||||
'prop:type': 'text',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'0'
|
|
||||||
)
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
<affine:page>
|
|
||||||
<affine:paragraph
|
|
||||||
prop:type="text"
|
|
||||||
/>
|
|
||||||
</affine:page>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('block with plain text should match snapshot', () => {
|
|
||||||
expect(
|
|
||||||
yDocToJSXNode(
|
|
||||||
{
|
|
||||||
'0': {
|
|
||||||
'sys:id': '0',
|
|
||||||
'sys:flavour': 'affine:page',
|
|
||||||
'sys:children': ['1'],
|
|
||||||
'prop:title': 'this is title',
|
|
||||||
},
|
|
||||||
'1': {
|
|
||||||
'sys:id': '2',
|
|
||||||
'sys:flavour': 'affine:paragraph',
|
|
||||||
'sys:children': [],
|
|
||||||
'prop:type': 'text',
|
|
||||||
'prop:text': [{ insert: 'just plain text' }],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'0'
|
|
||||||
)
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
<affine:page
|
|
||||||
prop:title="this is title"
|
|
||||||
>
|
|
||||||
<affine:paragraph
|
|
||||||
prop:text="just plain text"
|
|
||||||
prop:type="text"
|
|
||||||
/>
|
|
||||||
</affine:page>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('doc record match snapshot', () => {
|
|
||||||
expect(
|
|
||||||
yDocToJSXNode(
|
|
||||||
{
|
|
||||||
'0': {
|
|
||||||
'sys:id': '0',
|
|
||||||
'sys:flavour': 'affine:page',
|
|
||||||
'sys:children': ['1'],
|
|
||||||
'prop:title': 'this is title',
|
|
||||||
},
|
|
||||||
'1': {
|
|
||||||
'sys:id': '2',
|
|
||||||
'sys:flavour': 'affine:paragraph',
|
|
||||||
'sys:children': [],
|
|
||||||
'prop:type': 'text',
|
|
||||||
'prop:text': [
|
|
||||||
{ insert: 'this is ' },
|
|
||||||
{
|
|
||||||
insert: 'a ',
|
|
||||||
attributes: { link: 'http://www.example.com' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
insert: 'link',
|
|
||||||
attributes: { link: 'http://www.example.com', bold: true },
|
|
||||||
},
|
|
||||||
{ insert: ' with', attributes: { bold: true } },
|
|
||||||
{ insert: ' bold' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'0'
|
|
||||||
)
|
|
||||||
).toMatchInlineSnapshot(`
|
|
||||||
<affine:page
|
|
||||||
prop:title="this is title"
|
|
||||||
>
|
|
||||||
<affine:paragraph
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
insert="this is "
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
insert="a "
|
|
||||||
link="http://www.example.com"
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
bold={true}
|
|
||||||
insert="link"
|
|
||||||
link="http://www.example.com"
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
bold={true}
|
|
||||||
insert=" with"
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
insert=" bold"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>
|
|
||||||
</affine:page>
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export { test } from './test.js';
|
|
||||||
export { DocCollectionAddonType } from './type.js';
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import type { DocCollection, DocCollectionOptions } from '../collection.js';
|
|
||||||
|
|
||||||
type DocCollectionConstructor<Keys extends string> = {
|
|
||||||
new (storeOptions: DocCollectionOptions): Omit<DocCollection, Keys>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AddOn<Keys extends string> = (
|
|
||||||
originalClass: DocCollectionConstructor<Keys>,
|
|
||||||
context: ClassDecoratorContext
|
|
||||||
) => { new (storeOptions: DocCollectionOptions): unknown };
|
|
||||||
|
|
||||||
export type AddOnReturn<Keys extends string> = (
|
|
||||||
originalClass: DocCollectionConstructor<Keys>,
|
|
||||||
context: ClassDecoratorContext
|
|
||||||
) => typeof DocCollection;
|
|
||||||
|
|
||||||
export function addOnFactory<Keys extends string>(fn: AddOn<Keys>) {
|
|
||||||
return fn as AddOnReturn<Keys>;
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
|
|
||||||
import type { JSXElement } from '../../utils/jsx.js';
|
|
||||||
import { serializeYDoc, yDocToJSXNode } from '../../utils/jsx.js';
|
|
||||||
import { addOnFactory } from './shared.js';
|
|
||||||
|
|
||||||
export interface TestAddon {
|
|
||||||
importDocSnapshot: (json: unknown, docId: string) => Promise<void>;
|
|
||||||
exportJSX: (blockId?: string, docId?: string) => JSXElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const test = addOnFactory<keyof TestAddon>(
|
|
||||||
originalClass =>
|
|
||||||
class extends originalClass {
|
|
||||||
/** @internal Only for testing */
|
|
||||||
exportJSX(blockId?: string, docId = this.meta.docMetas.at(0)?.id) {
|
|
||||||
assertExists(docId);
|
|
||||||
const doc = this.doc.spaces.get(docId);
|
|
||||||
assertExists(doc);
|
|
||||||
const docJson = serializeYDoc(doc);
|
|
||||||
if (!docJson) {
|
|
||||||
throw new Error(`Doc ${docId} doesn't exist`);
|
|
||||||
}
|
|
||||||
const blockJson = docJson.blocks as Record<string, unknown>;
|
|
||||||
if (!blockId) {
|
|
||||||
const rootId = Object.keys(blockJson).at(0);
|
|
||||||
if (!rootId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
blockId = rootId;
|
|
||||||
}
|
|
||||||
if (!blockJson[blockId]) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return yDocToJSXNode(blockJson, blockId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import type { TestAddon } from './test.js';
|
|
||||||
|
|
||||||
export class DocCollectionAddonType implements TestAddon {
|
|
||||||
exportJSX!: TestAddon['exportJSX'];
|
|
||||||
|
|
||||||
importDocSnapshot!: TestAddon['importDocSnapshot'];
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,6 @@ import {
|
|||||||
BlockSuiteDoc,
|
BlockSuiteDoc,
|
||||||
type RawAwarenessState,
|
type RawAwarenessState,
|
||||||
} from '../yjs/index.js';
|
} from '../yjs/index.js';
|
||||||
import { DocCollectionAddonType, test } from './addon/index.js';
|
|
||||||
import { BlockCollection, type GetDocOptions } from './doc/block-collection.js';
|
import { BlockCollection, type GetDocOptions } from './doc/block-collection.js';
|
||||||
import type { Doc, Query } from './doc/index.js';
|
import type { Doc, Query } from './doc/index.js';
|
||||||
import type { IdGeneratorType } from './id.js';
|
import type { IdGeneratorType } from './id.js';
|
||||||
@@ -73,10 +72,7 @@ export interface StackItem {
|
|||||||
meta: Map<'cursor-location' | 'selection-state', unknown>;
|
meta: Map<'cursor-location' | 'selection-state', unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// oxlint-disable-next-line
|
export class DocCollection {
|
||||||
// @ts-ignore FIXME: typecheck error
|
|
||||||
@test
|
|
||||||
export class DocCollection extends DocCollectionAddonType {
|
|
||||||
static Y = Y;
|
static Y = Y;
|
||||||
|
|
||||||
protected readonly _schema: Schema;
|
protected readonly _schema: Schema;
|
||||||
@@ -142,7 +138,6 @@ export class DocCollection extends DocCollectionAddonType {
|
|||||||
},
|
},
|
||||||
logger = new NoopLogger(),
|
logger = new NoopLogger(),
|
||||||
}: DocCollectionOptions) {
|
}: DocCollectionOptions) {
|
||||||
super();
|
|
||||||
this._schema = schema;
|
this._schema = schema;
|
||||||
|
|
||||||
this.id = id || '';
|
this.id = id || '';
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
import { BlockModel } from '../schema/base.js';
|
|
||||||
|
|
||||||
function isBlockModel(a: unknown): a is BlockModel {
|
|
||||||
return a instanceof BlockModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ported from https://github.com/vuejs/core/blob/main/packages/runtime-core/src/customFormatter.ts
|
|
||||||
*
|
|
||||||
* See [Custom Object Formatters in Chrome DevTools](https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U)
|
|
||||||
*/
|
|
||||||
function initCustomFormatter() {
|
|
||||||
if (
|
|
||||||
!(process.env.NODE_ENV === 'development') ||
|
|
||||||
typeof window === 'undefined'
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bannerStyle = {
|
|
||||||
style:
|
|
||||||
'color: #eee; background: #3F6FDB; margin-right: 5px; padding: 2px; border-radius: 4px',
|
|
||||||
};
|
|
||||||
const typeStyle = {
|
|
||||||
style:
|
|
||||||
'color: #eee; background: #DB6D56; margin-right: 5px; padding: 2px; border-radius: 4px',
|
|
||||||
};
|
|
||||||
|
|
||||||
// custom formatter for Chrome
|
|
||||||
// https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
|
|
||||||
const formatter = {
|
|
||||||
header(obj: unknown, config = { expand: false }) {
|
|
||||||
if (!isBlockModel(obj) || config.expand) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (obj.text) {
|
|
||||||
return [
|
|
||||||
'div',
|
|
||||||
{},
|
|
||||||
['span', bannerStyle, obj.constructor.name],
|
|
||||||
['span', typeStyle, obj.flavour],
|
|
||||||
obj.text.toString(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'div',
|
|
||||||
{},
|
|
||||||
['span', bannerStyle, obj.constructor.name],
|
|
||||||
['span', typeStyle, obj.flavour],
|
|
||||||
];
|
|
||||||
},
|
|
||||||
hasBody() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
body(obj: unknown) {
|
|
||||||
return ['object', { object: obj, config: { expand: true } }];
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((window as any).devtoolsFormatters) {
|
|
||||||
(window as any).devtoolsFormatters.push(formatter);
|
|
||||||
} else {
|
|
||||||
(window as any).devtoolsFormatters = [formatter];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initCustomFormatter();
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
import * as Y from 'yjs';
|
|
||||||
|
|
||||||
type DocRecord = Record<
|
|
||||||
string,
|
|
||||||
{
|
|
||||||
'sys:id': string;
|
|
||||||
'sys:flavour': string;
|
|
||||||
'sys:children': string[];
|
|
||||||
[id: string]: unknown;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
export interface JSXElement {
|
|
||||||
// Ad-hoc for `ReactTestComponent` identify.
|
|
||||||
// Use ReactTestComponent serializer prevent snapshot be be wrapped in a string, which cases " to be escaped.
|
|
||||||
// See https://github.com/facebook/jest/blob/f1263368cc85c3f8b70eaba534ddf593392c44f3/packages/pretty-format/src/plugins/ReactTestComponent.ts#L78-L79
|
|
||||||
$$typeof: symbol | 0xea71357;
|
|
||||||
type: string;
|
|
||||||
props: { 'prop:text'?: string | JSXElement } & Record<string, unknown>;
|
|
||||||
children?: null | (JSXElement | string | number)[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ad-hoc for `ReactTestComponent` identify.
|
|
||||||
// See https://github.com/facebook/jest/blob/f1263368cc85c3f8b70eaba534ddf593392c44f3/packages/pretty-format/src/plugins/ReactTestComponent.ts#L26-L29
|
|
||||||
const testSymbol = Symbol.for('react.test.json');
|
|
||||||
|
|
||||||
function isValidRecord(data: unknown): data is DocRecord {
|
|
||||||
if (typeof data !== 'object' || data === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO enhance this check
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IGNORED_PROPS = new Set([
|
|
||||||
'sys:id',
|
|
||||||
'sys:version',
|
|
||||||
'sys:flavour',
|
|
||||||
'sys:children',
|
|
||||||
'prop:xywh',
|
|
||||||
'prop:cells',
|
|
||||||
'prop:elements',
|
|
||||||
]);
|
|
||||||
|
|
||||||
export function yDocToJSXNode(
|
|
||||||
serializedDoc: Record<string, unknown>,
|
|
||||||
nodeId: string
|
|
||||||
): JSXElement {
|
|
||||||
if (!isValidRecord(serializedDoc)) {
|
|
||||||
throw new Error('Failed to parse doc record! Invalid data.');
|
|
||||||
}
|
|
||||||
const node = serializedDoc[nodeId];
|
|
||||||
if (!node) {
|
|
||||||
throw new Error(
|
|
||||||
`Failed to parse doc record! Node not found! id: ${nodeId}.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// TODO maybe need set PascalCase
|
|
||||||
const flavour = node['sys:flavour'];
|
|
||||||
// TODO maybe need check children recursively nested
|
|
||||||
const children = node['sys:children'];
|
|
||||||
const props = Object.fromEntries(
|
|
||||||
Object.entries(node).filter(([key]) => !IGNORED_PROPS.has(key))
|
|
||||||
);
|
|
||||||
|
|
||||||
if ('prop:text' in props && props['prop:text'] instanceof Array) {
|
|
||||||
props['prop:text'] = parseDelta(props['prop:text'] as DeltaText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('prop:title' in props && props['prop:title'] instanceof Array) {
|
|
||||||
props['prop:title'] = parseDelta(props['prop:title'] as DeltaText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('prop:columns' in props && props['prop:columns'] instanceof Array) {
|
|
||||||
props['prop:columns'] = `Array [${props['prop:columns'].length}]`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('prop:views' in props && props['prop:views'] instanceof Array) {
|
|
||||||
props['prop:views'] = `Array [${props['prop:views'].length}]`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
$$typeof: testSymbol,
|
|
||||||
type: flavour,
|
|
||||||
props,
|
|
||||||
children: children?.map(id => yDocToJSXNode(serializedDoc, id)) ?? [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serializeYDoc(doc: Y.Doc) {
|
|
||||||
const json: Record<string, unknown> = {};
|
|
||||||
doc.share.forEach((value, key) => {
|
|
||||||
if (value instanceof Y.Map) {
|
|
||||||
json[key] = serializeYMap(value);
|
|
||||||
} else {
|
|
||||||
json[key] = value.toJSON();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
function serializeY(value: unknown): unknown {
|
|
||||||
if (value instanceof Y.Doc) {
|
|
||||||
return serializeYDoc(value);
|
|
||||||
}
|
|
||||||
if (value instanceof Y.Map) {
|
|
||||||
return serializeYMap(value);
|
|
||||||
}
|
|
||||||
if (value instanceof Y.Text) {
|
|
||||||
return serializeYText(value);
|
|
||||||
}
|
|
||||||
if (value instanceof Y.Array) {
|
|
||||||
return value.toArray().map(x => serializeY(x));
|
|
||||||
}
|
|
||||||
if (value instanceof Y.AbstractType) {
|
|
||||||
return value.toJSON();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function serializeYMap(map: Y.Map<unknown>) {
|
|
||||||
const json: Record<string, unknown> = {};
|
|
||||||
map.forEach((value, key) => {
|
|
||||||
json[key] = serializeY(value);
|
|
||||||
});
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeltaText = {
|
|
||||||
insert: string;
|
|
||||||
attributes?: Record<string, unknown>;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
function serializeYText(text: Y.Text): DeltaText {
|
|
||||||
const delta = text.toDelta();
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseDelta(text: DeltaText) {
|
|
||||||
if (!text.length) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (text.length === 1 && !text[0].attributes) {
|
|
||||||
// just plain text
|
|
||||||
return text[0].insert;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
// The `Symbol.for('react.fragment')` will render as `<React.Fragment>`
|
|
||||||
// so we use a empty string to render it as `<>`.
|
|
||||||
// But it will empty children ad `< />`
|
|
||||||
// so we return `undefined` directly if not delta text.
|
|
||||||
$$typeof: testSymbol, // Symbol.for('react.element'),
|
|
||||||
type: '', // Symbol.for('react.fragment'),
|
|
||||||
props: {},
|
|
||||||
children: text?.map(({ insert, attributes }) => ({
|
|
||||||
$$typeof: testSymbol,
|
|
||||||
type: 'text',
|
|
||||||
props: {
|
|
||||||
// Not place at `children` to avoid the trailing whitespace be trim by formatter.
|
|
||||||
insert,
|
|
||||||
...attributes,
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -21,6 +21,8 @@ const fieldChecker: Record<string, (value: any) => boolean> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const skipFields = new Set(['_lastXYWH']);
|
||||||
|
|
||||||
const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
||||||
const pageService = window.editor.host!.std.getService('affine:page');
|
const pageService = window.editor.host!.std.getService('affine:page');
|
||||||
if (!pageService) {
|
if (!pageService) {
|
||||||
@@ -66,10 +68,16 @@ const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skipFields.has(field)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fieldChecker[typeField] || fieldChecker[field]) {
|
if (fieldChecker[typeField] || fieldChecker[field]) {
|
||||||
const checker = fieldChecker[typeField] || fieldChecker[field];
|
const checker = fieldChecker[typeField] || fieldChecker[field];
|
||||||
expect(checker(value)).toBe(true);
|
expect(checker(value)).toBe(true);
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
value,
|
value,
|
||||||
`type: ${element.type} field: "${field}"`
|
`type: ${element.type} field: "${field}"`
|
||||||
@@ -77,7 +85,6 @@ const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
|||||||
expect(value, `type: ${element.type} field: "${field}"`).not.toBeNull();
|
expect(value, `type: ${element.type} field: "${field}"`).not.toBeNull();
|
||||||
expect(value, `type: ${element.type} field: "${field}"`).not.toBeNaN();
|
expect(value, `type: ${element.type} field: "${field}"`).not.toBeNaN();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,13 +96,11 @@ beforeEach(async () => {
|
|||||||
|
|
||||||
const xywhPattern = /\[(\s*-?\d+(\.\d+)?\s*,){3}(\s*-?\d+(\.\d+)?\s*)\]/;
|
const xywhPattern = /\[(\s*-?\d+(\.\d+)?\s*,){3}(\s*-?\d+(\.\d+)?\s*)\]/;
|
||||||
|
|
||||||
// FIXME: snapshot tests
|
test('snapshot 1 importing', async () => {
|
||||||
test.skip('snapshot 1 importing', async () => {
|
|
||||||
await snapshotTest('https://test.affineassets.com/test-snapshot-1.zip', 25);
|
await snapshotTest('https://test.affineassets.com/test-snapshot-1.zip', 25);
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: snapshot tests
|
test('snapshot 2 importing', async () => {
|
||||||
test.skip('snapshot 2 importing', async () => {
|
|
||||||
await snapshotTest(
|
await snapshotTest(
|
||||||
'https://test.affineassets.com/test-snapshot-2%20(onboarding).zip',
|
'https://test.affineassets.com/test-snapshot-2%20(onboarding).zip',
|
||||||
174
|
174
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import { sleep } from '@blocksuite/global/utils';
|
import { sleep } from '@blocksuite/global/utils';
|
||||||
import { expect, type Page } from '@playwright/test';
|
import { expect, type Page } from '@playwright/test';
|
||||||
import { switchEditorMode } from 'utils/actions/edgeless.js';
|
import { switchEditorMode } from 'utils/actions/edgeless.js';
|
||||||
@@ -20,6 +23,7 @@ import {
|
|||||||
captureHistory,
|
captureHistory,
|
||||||
enterPlaygroundRoom,
|
enterPlaygroundRoom,
|
||||||
focusRichText,
|
focusRichText,
|
||||||
|
getPageSnapshot,
|
||||||
initEmptyEdgelessState,
|
initEmptyEdgelessState,
|
||||||
initEmptyParagraphState,
|
initEmptyParagraphState,
|
||||||
resetHistory,
|
resetHistory,
|
||||||
@@ -34,14 +38,12 @@ import {
|
|||||||
assertParentBlockFlavour,
|
assertParentBlockFlavour,
|
||||||
assertRichImage,
|
assertRichImage,
|
||||||
assertRichTextInlineRange,
|
assertRichTextInlineRange,
|
||||||
assertStoreMatchJSX,
|
|
||||||
} from './utils/asserts.js';
|
} from './utils/asserts.js';
|
||||||
import { test } from './utils/playwright.js';
|
import { test } from './utils/playwright.js';
|
||||||
|
|
||||||
const FILE_NAME = 'test-card-1.png';
|
const FILE_NAME = 'test-card-1.png';
|
||||||
const FILE_PATH = `../playground/public/${FILE_NAME}`;
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const FILE_ID = 'ejImogf-Tb7AuKY-v94uz1zuOJbClqK-tWBxVr_ksGA=';
|
const FILE_PATH = path.resolve(__dirname, `../playground/public/${FILE_NAME}`);
|
||||||
const FILE_SIZE = 45801;
|
|
||||||
|
|
||||||
function getAttachment(page: Page) {
|
function getAttachment(page: Page) {
|
||||||
const attachment = page.locator('affine-attachment');
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { noteId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
|
|
||||||
const { insertAttachment, waitLoading, getName, getSize } =
|
const { insertAttachment, waitLoading, getName, getSize } =
|
||||||
getAttachment(page);
|
getAttachment(page);
|
||||||
@@ -140,50 +142,14 @@ test('can insert attachment from slash menu', async ({ page }) => {
|
|||||||
expect(await getName()).toBe(FILE_NAME);
|
expect(await getName()).toBe(FILE_NAME);
|
||||||
expect(await getSize()).toBe('45.8 kB');
|
expect(await getSize()).toBe('45.8 kB');
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should undo/redo works for attachment', async ({ page }) => {
|
test('should undo/redo works for attachment', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { noteId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
|
|
||||||
const { insertAttachment, waitLoading } = getAttachment(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
|
// Wait for the attachment to be uploaded
|
||||||
await waitLoading();
|
await waitLoading();
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
` <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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await undoByKeyboard(page);
|
await undoByKeyboard(page);
|
||||||
await waitNextFrame(page);
|
await waitNextFrame(page);
|
||||||
|
|
||||||
// The loading/error state should not be restored after undo
|
// The loading/error state should not be restored after undo
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await redoByKeyboard(page);
|
await redoByKeyboard(page);
|
||||||
await waitNextFrame(page);
|
await waitNextFrame(page);
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
// The loading/error state should not be restored after undo
|
||||||
`
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
<affine:note
|
`${testInfo.title}_3.json`
|
||||||
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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -351,9 +219,9 @@ test('should rename attachment works', async ({ page }) => {
|
|||||||
expect(await getName()).toBe('abc');
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { noteId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { insertAttachment, waitLoading, turnToEmbed, turnImageToCard } =
|
const { insertAttachment, waitLoading, turnToEmbed, turnImageToCard } =
|
||||||
getAttachment(page);
|
getAttachment(page);
|
||||||
|
|
||||||
@@ -364,90 +232,18 @@ test('should turn attachment to image works', async ({ page }) => {
|
|||||||
|
|
||||||
await turnToEmbed();
|
await turnToEmbed();
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
await turnImageToCard();
|
await turnImageToCard();
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should attachment can be deleted', async ({ page }) => {
|
test('should attachment can be deleted', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { noteId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { attachment, insertAttachment, waitLoading } = getAttachment(page);
|
const { attachment, insertAttachment, waitLoading } = getAttachment(page);
|
||||||
|
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
@@ -457,38 +253,16 @@ test('should attachment can be deleted', async ({ page }) => {
|
|||||||
|
|
||||||
await attachment.click();
|
await attachment.click();
|
||||||
await pressBackspace(page);
|
await pressBackspace(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.fixme(`support dragging attachment block directly`, async ({ page }) => {
|
test(`support dragging attachment block directly`, async ({
|
||||||
|
page,
|
||||||
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { noteId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
|
|
||||||
const { insertAttachment, waitLoading, getName, getSize } =
|
const { insertAttachment, waitLoading, getName, getSize } =
|
||||||
getAttachment(page);
|
getAttachment(page);
|
||||||
@@ -502,43 +276,8 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
|
|||||||
expect(await getName()).toBe(FILE_NAME);
|
expect(await getName()).toBe(FILE_NAME);
|
||||||
expect(await getSize()).toBe('45.8 kB');
|
expect(await getSize()).toBe('45.8 kB');
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
` <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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const attachmentBlock = page.locator('affine-attachment');
|
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 page.waitForTimeout(200);
|
await page.waitForTimeout(200);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
/*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>`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// drag bookmark block
|
// 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');
|
const rects = page.locator('affine-block-selection').locator('visible=true');
|
||||||
await expect(rects).toHaveCount(1);
|
await expect(rects).toHaveCount(1);
|
||||||
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
await assertStoreMatchJSX(
|
`${testInfo.title}_3.json`
|
||||||
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>`
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
|
import type { BlockSnapshot } from '@store/index.js';
|
||||||
import { lightThemeV2 } from '@toeverything/theme/v2';
|
import { lightThemeV2 } from '@toeverything/theme/v2';
|
||||||
|
|
||||||
import { initDatabaseColumn } from '../database/actions.js';
|
import { initDatabaseColumn } from '../database/actions.js';
|
||||||
@@ -53,7 +54,6 @@ import {
|
|||||||
assertExists,
|
assertExists,
|
||||||
assertRichTextModelType,
|
assertRichTextModelType,
|
||||||
assertRichTexts,
|
assertRichTexts,
|
||||||
assertStoreMatchJSX,
|
|
||||||
assertText,
|
assertText,
|
||||||
} from '../utils/asserts.js';
|
} from '../utils/asserts.js';
|
||||||
import { scoped, test } from '../utils/playwright.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 pasteByKeyboard(page);
|
||||||
await page.waitForTimeout(100);
|
await page.waitForTimeout(100);
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
let pageJson = await getPageSnapshot(page, false);
|
||||||
page,
|
let note = (pageJson as BlockSnapshot).children[0];
|
||||||
/*xml*/ `
|
const database = note.children[0];
|
||||||
<affine:page>
|
expect(database.flavour).toBe('affine:database');
|
||||||
<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>`
|
|
||||||
);
|
|
||||||
|
|
||||||
await undoByKeyboard(page);
|
await undoByKeyboard(page);
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
pageJson = await getPageSnapshot(page, false);
|
||||||
/*xml*/ `
|
note = (pageJson as BlockSnapshot).children[0];
|
||||||
<affine:page>
|
const db = note.children.find(child => child.flavour === 'affine:database');
|
||||||
<affine:note
|
expect(db).toBeDefined();
|
||||||
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>`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test(`copy canvas element and text note in edgeless mode`, async ({ page }) => {
|
test(`copy canvas element and text note in edgeless mode`, async ({ page }) => {
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
assertBlockCount,
|
assertBlockCount,
|
||||||
assertRichTexts,
|
assertRichTexts,
|
||||||
assertStoreMatchJSX,
|
|
||||||
assertTitle,
|
assertTitle,
|
||||||
} from '../utils/asserts.js';
|
} from '../utils/asserts.js';
|
||||||
import { test } from '../utils/playwright.js';
|
import { test } from '../utils/playwright.js';
|
||||||
@@ -150,9 +149,9 @@ test('use shortcut can create code block', async ({ page }) => {
|
|||||||
await expect(locator).toBeVisible();
|
await expect(locator).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('change code language can work', async ({ page }) => {
|
test('change code language can work', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { codeBlockId } = await initEmptyCodeBlockState(page);
|
await initEmptyCodeBlockState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
const codeBlockController = getCodeBlock(page);
|
const codeBlockController = getCodeBlock(page);
|
||||||
@@ -170,26 +169,12 @@ test('change code language can work', async ({ page }) => {
|
|||||||
await codeBlockController.codeBlock.hover();
|
await codeBlockController.codeBlock.hover();
|
||||||
await expect(codeBlockController.languageButton).toHaveText('Rust');
|
await expect(codeBlockController.languageButton).toHaveText('Rust');
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language="rust"
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
await undoByKeyboard(page);
|
await undoByKeyboard(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Can switch to another language
|
// 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;']);
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { codeBlockId } = await initEmptyCodeBlockState(page);
|
await initEmptyCodeBlockState(page);
|
||||||
|
|
||||||
const codeBlockController = getCodeBlock(page);
|
const codeBlockController = getCodeBlock(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await codeBlockController.codeBlock.hover();
|
await codeBlockController.codeBlock.hover();
|
||||||
await (await codeBlockController.openMore()).wrapButton.click();
|
await (await codeBlockController.openMore()).wrapButton.click();
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={true}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await codeBlockController.codeBlock.hover();
|
await codeBlockController.codeBlock.hover();
|
||||||
await (await codeBlockController.openMore()).cancelWrapButton.click();
|
await (await codeBlockController.openMore()).cancelWrapButton.click();
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_3.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('add caption works', async ({ page }) => {
|
test('add caption works', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { codeBlockId } = await initEmptyCodeBlockState(page);
|
await initEmptyCodeBlockState(page);
|
||||||
|
|
||||||
const codeBlockController = getCodeBlock(page);
|
const codeBlockController = getCodeBlock(page);
|
||||||
await codeBlockController.codeBlock.hover();
|
await codeBlockController.codeBlock.hover();
|
||||||
@@ -329,59 +293,31 @@ test('add caption works', async ({ page }) => {
|
|||||||
await pressEnter(page);
|
await pressEnter(page);
|
||||||
await waitNextFrame(page, 100);
|
await waitNextFrame(page, 100);
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption="BlockSuite"
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('undo code block wrap can work', async ({ page }) => {
|
test('undo code block wrap can work', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { codeBlockId } = await initEmptyCodeBlockState(page);
|
await initEmptyCodeBlockState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
const codeBlockController = getCodeBlock(page);
|
const codeBlockController = getCodeBlock(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await codeBlockController.codeBlock.hover();
|
await codeBlockController.codeBlock.hover();
|
||||||
await (await codeBlockController.openMore()).wrapButton.click();
|
await (await codeBlockController.openMore()).wrapButton.click();
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={true}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await undoByKeyboard(page);
|
await undoByKeyboard(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_3.json`
|
||||||
/*xml*/ `
|
|
||||||
<affine:code
|
|
||||||
prop:caption=""
|
|
||||||
prop:language={null}
|
|
||||||
prop:wrap={false}
|
|
||||||
/>`,
|
|
||||||
codeBlockId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ import {
|
|||||||
type,
|
type,
|
||||||
waitNextFrame,
|
waitNextFrame,
|
||||||
} from './utils/actions/index.js';
|
} from './utils/actions/index.js';
|
||||||
import {
|
import { assertKeyboardWorkInInput } from './utils/asserts.js';
|
||||||
assertKeyboardWorkInInput,
|
|
||||||
assertStoreMatchJSX,
|
|
||||||
} from './utils/asserts.js';
|
|
||||||
import { test } from './utils/playwright.js';
|
import { test } from './utils/playwright.js';
|
||||||
|
|
||||||
const pressCreateLinkShortCut = async (page: Page) => {
|
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 ({
|
test('type character in link should not jump out link node', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
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 focusRichText(page, 0);
|
||||||
await page.keyboard.press('ArrowLeft');
|
await page.keyboard.press('ArrowLeft');
|
||||||
await type(page, 'IN_LINK');
|
await type(page, 'IN_LINK');
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
insert="Hello"
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
insert="link texIN_LINKt"
|
|
||||||
link="http://example.com"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
id
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('type character after link should not extend the link attributes', async ({
|
test('type character after link should not extend the link attributes', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
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 focusRichText(page, 0);
|
||||||
await type(page, 'AFTER_LINK');
|
await type(page, 'AFTER_LINK');
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -237,11 +197,11 @@ test('readonly mode should not trigger link popup', async ({ page }) => {
|
|||||||
await expect(linkPopoverInput).not.toBeVisible();
|
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 linkText = 'linkText';
|
||||||
const link = 'http://example.com';
|
const link = 'http://example.com';
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, linkText);
|
await type(page, linkText);
|
||||||
|
|
||||||
@@ -254,15 +214,8 @@ test('should mock selection not stored', async ({ page }) => {
|
|||||||
await expect(mockSelectNode).toBeVisible();
|
await expect(mockSelectNode).toBeVisible();
|
||||||
|
|
||||||
// the mock select node should not be stored in the Y doc
|
// the mock select node should not be stored in the Y doc
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="linkText"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await type(page, link);
|
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();
|
await expect(linkPopoverLocator).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('create link with paste', async ({ page }) => {
|
test('create link with paste', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, 'aaa');
|
await type(page, 'aaa');
|
||||||
|
|
||||||
@@ -375,22 +328,8 @@ test('create link with paste', async ({ page }) => {
|
|||||||
await expect(confirmBtn).not.toHaveAttribute('disabled');
|
await expect(confirmBtn).not.toHaveAttribute('disabled');
|
||||||
await pressEnter(page);
|
await pressEnter(page);
|
||||||
await expect(createLinkPopoverLocator).not.toBeVisible();
|
await expect(createLinkPopoverLocator).not.toBeVisible();
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
insert="aaa"
|
|
||||||
link="http://affine.pro"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -447,8 +386,7 @@ test('convert link to card', async ({ page }, testInfo) => {
|
|||||||
await expect(linkToEmbedBtn).not.toBeVisible();
|
await expect(linkToEmbedBtn).not.toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO: wait for embed block completed
|
test('convert link to embed', async ({ page }, testInfo) => {
|
||||||
test.skip('convert link to embed', async ({ page }) => {
|
|
||||||
const linkText = 'alinkTexta';
|
const linkText = 'alinkTexta';
|
||||||
const link = 'https://www.youtube.com/watch?v=U6s2pdxebSo';
|
const link = 'https://www.youtube.com/watch?v=U6s2pdxebSo';
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
@@ -471,73 +409,13 @@ test.skip('convert link to embed', async ({ page }) => {
|
|||||||
await expect(linkPopoverLocator).not.toBeVisible();
|
await expect(linkPopoverLocator).not.toBeVisible();
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<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>`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const linkToCardBtn = page.getByTestId('link-to-card');
|
|
||||||
const linkToEmbedBtn = page.getByTestId('link-to-embed');
|
|
||||||
const linkLocator = page.locator('affine-link a');
|
const linkLocator = page.locator('affine-link a');
|
||||||
|
|
||||||
await linkLocator.hover();
|
await linkLocator.hover();
|
||||||
await waitNextFrame(page);
|
await waitNextFrame(page);
|
||||||
await expect(linkPopoverLocator).toBeVisible();
|
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();
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ import {
|
|||||||
pressArrowRight,
|
pressArrowRight,
|
||||||
pressBackspace,
|
pressBackspace,
|
||||||
pressEnter,
|
pressEnter,
|
||||||
redoByKeyboard,
|
|
||||||
selectAllByKeyboard,
|
selectAllByKeyboard,
|
||||||
SHORT_KEY,
|
SHORT_KEY,
|
||||||
type,
|
type,
|
||||||
undoByKeyboard,
|
|
||||||
} from './utils/actions/keyboard.js';
|
} from './utils/actions/keyboard.js';
|
||||||
import {
|
import {
|
||||||
captureHistory,
|
captureHistory,
|
||||||
@@ -37,7 +35,6 @@ import {
|
|||||||
assertExists,
|
assertExists,
|
||||||
assertParentBlockFlavour,
|
assertParentBlockFlavour,
|
||||||
assertRichTexts,
|
assertRichTexts,
|
||||||
assertStoreMatchJSX,
|
|
||||||
assertTitle,
|
assertTitle,
|
||||||
} from './utils/asserts.js';
|
} from './utils/asserts.js';
|
||||||
import { test } from './utils/playwright.js';
|
import { test } from './utils/playwright.js';
|
||||||
@@ -95,22 +92,17 @@ test.describe('multiple page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('reference node', () => {
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, '[[');
|
await type(page, '[[');
|
||||||
|
|
||||||
// `[[` should be converted to `@`
|
// `[[` should be converted to `@`
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="@"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
const { linkedDocPopover } = getLinkedDocPopover(page);
|
const { linkedDocPopover } = getLinkedDocPopover(page);
|
||||||
await expect(linkedDocPopover).toBeVisible();
|
await expect(linkedDocPopover).toBeVisible();
|
||||||
@@ -140,46 +132,23 @@ test.describe('reference node', () => {
|
|||||||
await expect(linkedDocPopover).toBeHidden();
|
await expect(linkedDocPopover).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should reference node attributes correctly', async ({ page }) => {
|
test('should reference node attributes correctly', async ({
|
||||||
|
page,
|
||||||
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { id } = await addNewPage(page);
|
await addNewPage(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, '[[');
|
await type(page, '[[');
|
||||||
await pressEnter(page);
|
await pressEnter(page);
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
insert=" "
|
|
||||||
reference={
|
|
||||||
Object {
|
|
||||||
"pageId": "${id}",
|
|
||||||
"type": "LinkedPage",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await pressBackspace(page);
|
await pressBackspace(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -211,10 +180,10 @@ test.describe('reference node', () => {
|
|||||||
|
|
||||||
test('text inserted in the between of reference nodes should not be extend attributes', async ({
|
test('text inserted in the between of reference nodes should not be extend attributes', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { id } = await addNewPage(page);
|
await addNewPage(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await type(page, '1');
|
await type(page, '1');
|
||||||
@@ -234,51 +203,17 @@ test.describe('reference node', () => {
|
|||||||
await type(page, '3');
|
await type(page, '3');
|
||||||
await assertRichTexts(page, ['1 3 2']);
|
await assertRichTexts(page, ['1 3 2']);
|
||||||
|
|
||||||
const snapshot = `
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
<affine:paragraph
|
`${testInfo.title}.json`
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('text can be inserted as expected when reference node is in the start or end of line', async ({
|
test('text can be inserted as expected when reference node is in the start or end of line', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { id } = await addNewPage(page);
|
await addNewPage(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await type(page, '@');
|
await type(page, '@');
|
||||||
@@ -304,51 +239,17 @@ test.describe('reference node', () => {
|
|||||||
await type(page, '1');
|
await type(page, '1');
|
||||||
await assertRichTexts(page, ['1 3 2']);
|
await assertRichTexts(page, ['1 3 2']);
|
||||||
|
|
||||||
const snapshot = `
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
<affine:paragraph
|
`${testInfo.title}.json`
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should the cursor move correctly around reference node', async ({
|
test('should the cursor move correctly around reference node', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const { id } = await addNewPage(page);
|
await addNewPage(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await type(page, '1');
|
await type(page, '1');
|
||||||
@@ -370,57 +271,16 @@ test.describe('reference node', () => {
|
|||||||
await type(page, '4');
|
await type(page, '4');
|
||||||
await assertRichTexts(page, ['14 32']);
|
await assertRichTexts(page, ['14 32']);
|
||||||
|
|
||||||
const snapshot = `
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
<affine:paragraph
|
`${testInfo.title}_1.json`
|
||||||
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);
|
|
||||||
|
|
||||||
await page.keyboard.press('ArrowRight');
|
await page.keyboard.press('ArrowRight');
|
||||||
await captureHistory(page);
|
await captureHistory(page);
|
||||||
await pressBackspace(page);
|
await pressBackspace(page);
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
`
|
`${testInfo.title}_2.json`
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -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({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/toeverything/blocksuite/issues/2730',
|
description: 'https://github.com/toeverything/blocksuite/issues/2730',
|
||||||
});
|
});
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, '1234');
|
await type(page, '1234');
|
||||||
|
|
||||||
@@ -761,33 +623,8 @@ test('should [[Selected text]] converted to linked page', async ({ page }) => {
|
|||||||
await type(page, '[');
|
await type(page, '[');
|
||||||
await assertRichTexts(page, ['1[2]34']);
|
await assertRichTexts(page, ['1[2]34']);
|
||||||
await type(page, '[');
|
await type(page, '[');
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<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
|
|
||||||
);
|
);
|
||||||
await switchToPage(page, '3');
|
await switchToPage(page, '3');
|
||||||
await assertTitle(page, '2');
|
await assertTitle(page, '2');
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import {
|
|||||||
assertDocTitleFocus,
|
assertDocTitleFocus,
|
||||||
assertRichTextInlineRange,
|
assertRichTextInlineRange,
|
||||||
assertRichTexts,
|
assertRichTexts,
|
||||||
assertStoreMatchJSX,
|
|
||||||
assertTitle,
|
assertTitle,
|
||||||
} from './utils/asserts.js';
|
} from './utils/asserts.js';
|
||||||
import { test } from './utils/playwright.js';
|
import { test } from './utils/playwright.js';
|
||||||
@@ -1296,9 +1295,11 @@ test.describe('readonly mode', () => {
|
|||||||
await expect(placeholder).toBeHidden();
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
|
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, 'hello');
|
await type(page, 'hello');
|
||||||
@@ -1308,27 +1309,13 @@ test.describe('readonly mode', () => {
|
|||||||
await type(page, 'world');
|
await type(page, 'world');
|
||||||
await dragBetweenIndices(page, [0, 1], [0, 3]);
|
await dragBetweenIndices(page, [0, 1], [0, 3]);
|
||||||
await page.keyboard.press(`${SHORT_KEY}+b`);
|
await page.keyboard.press(`${SHORT_KEY}+b`);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_1.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="hello"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await undoByKeyboard(page);
|
await undoByKeyboard(page);
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}_2.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="hello"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import {
|
|||||||
assertBlockCount,
|
assertBlockCount,
|
||||||
assertExists,
|
assertExists,
|
||||||
assertRichTexts,
|
assertRichTexts,
|
||||||
assertStoreMatchJSX,
|
|
||||||
} from './utils/asserts.js';
|
} from './utils/asserts.js';
|
||||||
import { test } from './utils/playwright.js';
|
import { test } from './utils/playwright.js';
|
||||||
|
|
||||||
@@ -62,9 +61,10 @@ test.describe('slash menu should show and hide correctly', () => {
|
|||||||
await expect(slashMenu).toBeVisible();
|
await expect(slashMenu).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('slash menu should hide after click away', async ({ page }) => {
|
test('slash menu should hide after click away', async ({
|
||||||
const id = await initEmptyParagraphState(page);
|
page,
|
||||||
const paragraphId = id.paragraphId;
|
}, testInfo) => {
|
||||||
|
await initEmptyParagraphState(page);
|
||||||
const slashMenu = page.locator(`.slash-menu`);
|
const slashMenu = page.locator(`.slash-menu`);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, '/');
|
await type(page, '/');
|
||||||
@@ -72,15 +72,9 @@ test.describe('slash menu should show and hide correctly', () => {
|
|||||||
// Click outside should close slash menu
|
// Click outside should close slash menu
|
||||||
await page.mouse.click(0, 50);
|
await page.mouse.click(0, 50);
|
||||||
await expect(slashMenu).toBeHidden();
|
await expect(slashMenu).toBeHidden();
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
`
|
`${testInfo.title}.json`
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="/"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -106,9 +100,8 @@ test.describe('slash menu should show and hide correctly', () => {
|
|||||||
|
|
||||||
test('delete the slash symbol should close the slash menu', async ({
|
test('delete the slash symbol should close the slash menu', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}, testInfo) => {
|
||||||
const id = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
const paragraphId = id.paragraphId;
|
|
||||||
const slashMenu = page.locator(`.slash-menu`);
|
const slashMenu = page.locator(`.slash-menu`);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, '/');
|
await type(page, '/');
|
||||||
@@ -116,14 +109,8 @@ test.describe('slash menu should show and hide correctly', () => {
|
|||||||
|
|
||||||
await pressBackspace(page);
|
await pressBackspace(page);
|
||||||
await expect(slashMenu).toBeHidden();
|
await expect(slashMenu).toBeHidden();
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -522,13 +509,15 @@ test('should slash menu works with fast type', async ({ page }) => {
|
|||||||
await expect(slashMenu).toBeVisible();
|
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({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/toeverything/blocksuite/issues/1126',
|
description: 'https://github.com/toeverything/blocksuite/issues/1126',
|
||||||
});
|
});
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
await type(page, 'hello');
|
await type(page, 'hello');
|
||||||
await pressShiftEnter(page);
|
await pressShiftEnter(page);
|
||||||
@@ -536,15 +525,8 @@ test('should clean slash string after soft enter', async ({ page }) => {
|
|||||||
await type(page, '/copy');
|
await type(page, '/copy');
|
||||||
await pressEnter(page);
|
await pressEnter(page);
|
||||||
|
|
||||||
await assertStoreMatchJSX(
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
page,
|
`${testInfo.title}.json`
|
||||||
`
|
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text="hello\n"
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -720,9 +702,9 @@ test.describe('slash menu with date & time', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('slash menu with style', () => {
|
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);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await type(page, 'hello/');
|
await type(page, 'hello/');
|
||||||
@@ -730,28 +712,15 @@ test.describe('slash menu with style', () => {
|
|||||||
await expect(slashMenu).toBeVisible();
|
await expect(slashMenu).toBeVisible();
|
||||||
const bold = page.getByTestId('Bold');
|
const bold = page.getByTestId('Bold');
|
||||||
await bold.click();
|
await bold.click();
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
`
|
`${testInfo.title}.json`
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
bold={true}
|
|
||||||
insert="hello"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should style empty line works', async ({ page }) => {
|
test('should style empty line works', async ({ page }, testInfo) => {
|
||||||
await enterPlaygroundRoom(page);
|
await enterPlaygroundRoom(page);
|
||||||
const { paragraphId } = await initEmptyParagraphState(page);
|
await initEmptyParagraphState(page);
|
||||||
await focusRichText(page);
|
await focusRichText(page);
|
||||||
|
|
||||||
await type(page, '/');
|
await type(page, '/');
|
||||||
@@ -761,22 +730,9 @@ test.describe('slash menu with style', () => {
|
|||||||
await bold.click();
|
await bold.click();
|
||||||
await page.waitForTimeout(50);
|
await page.waitForTimeout(50);
|
||||||
await type(page, 'hello');
|
await type(page, 'hello');
|
||||||
await assertStoreMatchJSX(
|
|
||||||
page,
|
expect(await getPageSnapshot(page, true)).toMatchSnapshot(
|
||||||
`
|
`${testInfo.title}.json`
|
||||||
<affine:paragraph
|
|
||||||
prop:collapsed={false}
|
|
||||||
prop:text={
|
|
||||||
<>
|
|
||||||
<text
|
|
||||||
bold={true}
|
|
||||||
insert="hello"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
prop:type="text"
|
|
||||||
/>`,
|
|
||||||
paragraphId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -18,11 +18,6 @@ import type { InlineRootElement } from '@inline/inline-editor.js';
|
|||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
import { COLLECTION_VERSION, PAGE_VERSION } from '@store/consts.js';
|
import { COLLECTION_VERSION, PAGE_VERSION } from '@store/consts.js';
|
||||||
import type { BlockModel } from '@store/index.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 {
|
import {
|
||||||
getCanvasElementsCount,
|
getCanvasElementsCount,
|
||||||
@@ -50,7 +45,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
captureHistory,
|
captureHistory,
|
||||||
getClipboardCustomData,
|
getClipboardCustomData,
|
||||||
getCurrentEditorDocId,
|
|
||||||
getCurrentThemeCSSPropertyValue,
|
getCurrentThemeCSSPropertyValue,
|
||||||
getEditorLocator,
|
getEditorLocator,
|
||||||
inlineEditorInnerTextToString,
|
inlineEditorInnerTextToString,
|
||||||
@@ -633,116 +627,6 @@ export async function assertBlockTypes(page: Page, blockTypes: string[]) {
|
|||||||
expect(actual).toEqual(blockTypes);
|
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';
|
type MimeType = 'text/plain' | 'blocksuite/x-c+w' | 'text/html';
|
||||||
|
|
||||||
export function assertClipItems(_page: Page, _key: MimeType, _value: unknown) {
|
export function assertClipItems(_page: Page, _key: MimeType, _value: unknown) {
|
||||||
|
|||||||
Reference in New Issue
Block a user