fix(editor): test stability (#15377)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
  * Improved automated validation for AI file embedding readiness.
* Expanded coverage for paragraph behavior when converting between list
types and deleting content.
* Strengthened checks for block structure and formatting outcomes to
help prevent regressions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-07-30 19:56:48 +08:00
committed by GitHub
parent a1defa8a3b
commit dd1c8dc7dd
2 changed files with 40 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
import { cleanupWorkspace } from '@affine-test/kit/utils/cloud'; import { cleanupWorkspace, runPrisma } from '@affine-test/kit/utils/cloud';
import { expect, type Page } from '@playwright/test'; import { expect, type Page } from '@playwright/test';
const WORKSPACE_EMBEDDING_SWITCH_TEST_ID = 'workspace-embedding-setting-switch'; const WORKSPACE_EMBEDDING_SWITCH_TEST_ID = 'workspace-embedding-setting-switch';
@@ -268,6 +268,15 @@ export class SettingsPanelUtils {
await expect(attachmentItems).toHaveCount(expectedFileCount); await expect(attachmentItems).toHaveCount(expectedFileCount);
}).toPass({ timeout }); }).toPass({ timeout });
await this.waitForEmbeddingComplete(page, timeout); const workspaceId = page.url().split('/').slice(-2)[0] || '';
await cleanupWorkspace(workspaceId);
await expect(async () => {
const embeddedFileCount = await runPrisma(client =>
client.aiWorkspaceFiles.count({
where: { workspaceId, embeddings: { some: {} } },
})
);
expect(embeddedFileCount).toBe(expectedFileCount);
}).toPass({ timeout });
} }
} }

View File

@@ -7,6 +7,7 @@ import {
dragOverTitle, dragOverTitle,
enterPlaygroundRoom, enterPlaygroundRoom,
focusRichText, focusRichText,
focusRichTextEnd,
focusTitle, focusTitle,
getBlockIds, getBlockIds,
getIndexCoordinate, getIndexCoordinate,
@@ -49,6 +50,7 @@ import {
assertBlockSelections, assertBlockSelections,
assertBlockTextContent, assertBlockTextContent,
assertBlockType, assertBlockType,
assertBlockTypes,
assertClassName, assertClassName,
assertDivider, assertDivider,
assertDocTitleFocus, assertDocTitleFocus,
@@ -661,58 +663,64 @@ test('delete at start of paragraph immediately following list', async ({
await captureHistory(page); await captureHistory(page);
await assertRichTexts(page, ['hello', 'a']); await assertRichTexts(page, ['hello', 'a']);
await assertBlockChildrenIds(page, '1', ['2', '3']); await assertBlockTypes(page, ['text', 'text']);
await assertBlockType(page, '3', 'text');
// text -> bulleted // text -> bulleted
await focusRichText(page, 1); await focusRichText(page, 1);
await updateBlockType(page, 'affine:list', 'bulleted'); await updateBlockType(page, 'affine:list', 'bulleted');
await assertBlockType(page, '2', 'text'); await assertBlockTypes(page, ['text', 'bulleted']);
await assertBlockType(page, '4', 'bulleted'); await focusRichTextEnd(page, 1);
await pressBackspace(page, 2); await pressBackspace(page, 2);
await waitNextFrame(page); await waitNextFrame(page);
await assertBlockType(page, '5', 'text'); await assertBlockTypes(page, ['text', 'text']);
await assertBlockChildrenIds(page, '1', ['2', '5']); await assertBlockChildrenFlavours(page, '1', [
'affine:paragraph',
'affine:paragraph',
]);
await pressBackspace(page); await pressBackspace(page);
await assertBlockChildrenIds(page, '1', ['2']); await assertBlockTypes(page, ['text']);
// reset // reset
await undoByClick(page); await undoByClick(page);
await undoByClick(page); await undoByClick(page);
await assertRichTexts(page, ['hello', 'a']); await assertRichTexts(page, ['hello', 'a']);
await assertBlockChildrenIds(page, '1', ['2', '3']); await assertBlockTypes(page, ['text', 'text']);
await assertBlockType(page, '3', 'text');
// text -> numbered // text -> numbered
await focusRichText(page, 1); await focusRichText(page, 1);
await updateBlockType(page, 'affine:list', 'numbered'); await updateBlockType(page, 'affine:list', 'numbered');
await assertBlockType(page, '2', 'text'); await assertBlockTypes(page, ['text', 'numbered']);
await assertBlockType(page, '6', 'numbered'); await focusRichTextEnd(page, 1);
await pressBackspace(page, 2); await pressBackspace(page, 2);
await waitNextFrame(page); await waitNextFrame(page);
await assertBlockType(page, '7', 'text'); await assertBlockTypes(page, ['text', 'text']);
await assertBlockChildrenIds(page, '1', ['2', '7']); await assertBlockChildrenFlavours(page, '1', [
'affine:paragraph',
'affine:paragraph',
]);
await pressBackspace(page); await pressBackspace(page);
await assertBlockChildrenIds(page, '1', ['2']); await assertBlockTypes(page, ['text']);
// reset // reset
await undoByClick(page); await undoByClick(page);
await undoByClick(page); await undoByClick(page);
await assertRichTexts(page, ['hello', 'a']); await assertRichTexts(page, ['hello', 'a']);
await assertBlockChildrenIds(page, '1', ['2', '3']); await assertBlockTypes(page, ['text', 'text']);
await assertBlockType(page, '3', 'text');
// text -> todo // text -> todo
await focusRichText(page, 1); await focusRichText(page, 1);
await updateBlockType(page, 'affine:list', 'todo'); await updateBlockType(page, 'affine:list', 'todo');
await assertBlockType(page, '2', 'text'); await assertBlockTypes(page, ['text', 'todo']);
await assertBlockType(page, '8', 'todo'); await focusRichTextEnd(page, 1);
await pressBackspace(page, 2); await pressBackspace(page, 2);
await waitNextFrame(page); await waitNextFrame(page);
await assertBlockType(page, '9', 'text'); await assertBlockTypes(page, ['text', 'text']);
await assertBlockChildrenIds(page, '1', ['2', '9']); await assertBlockChildrenFlavours(page, '1', [
'affine:paragraph',
'affine:paragraph',
]);
await pressBackspace(page); await pressBackspace(page);
await assertBlockChildrenIds(page, '1', ['2']); await assertBlockTypes(page, ['text']);
}); });
test('delete at start of paragraph with content', async ({ page }) => { test('delete at start of paragraph with content', async ({ page }) => {