From a9ad01491ca26009e0783866c7a50926bf94716f Mon Sep 17 00:00:00 2001 From: L-Sun Date: Wed, 23 Apr 2025 08:17:41 +0000 Subject: [PATCH] test(core): enable no-floating-promises rule for tests (#11915) Sometimes, missing `await` in the test code can cause timing issues, leading to test failures. This PR enables the `no-floating-promises` rule for the test code to ensure that such errors do not occur. --- .../src/__tests__/utils/renderer-entry.ts | 4 +- eslint.config.mjs | 5 +- .../server/src/__tests__/copilot.e2e.ts | 20 ++-- .../backend/server/src/__tests__/e2e/test.ts | 4 +- .../__tests__/e2e/workspace/invite.spec.ts | 8 +- .../src/__tests__/mocks/copilot.mock.ts | 6 +- .../backend/server/src/__tests__/team.e2e.ts | 111 +++++++++--------- .../server/src/__tests__/worker.e2e.ts | 2 +- .../server/src/__tests__/workspace.e2e.ts | 4 +- .../src/base/storage/__tests__/fs.spec.ts | 4 +- .../src/utils/__tests__/async-queue.spec.ts | 18 ++- .../ui/audio-player/audio-player.stories.tsx | 4 +- .../e2e/basic/chat.spec.ts | 4 +- .../e2e/chat-with/network.spec.ts | 2 +- .../insertion/add-to-edgeless-as-note.spec.ts | 2 +- .../e2e/insertion/insert.spec.ts | 2 +- .../e2e/utils/chat-panel-utils.ts | 8 +- .../e2e/utils/editor-utils.ts | 10 +- tests/affine-cloud/e2e/collaboration.spec.ts | 2 +- tests/affine-cloud/e2e/template.spec.ts | 2 +- .../affine-local/e2e/blocksuite/list.spec.ts | 2 +- .../e2e/local-first-workspace-list.spec.ts | 7 +- .../e2e/edgeless/frame/frame-mindmap.spec.ts | 2 +- tests/blocksuite/e2e/edgeless/lock.spec.ts | 4 +- .../e2e/embed-synced-doc/edgeless.spec.ts | 2 +- .../blocksuite/e2e/embed-synced-doc/utils.ts | 14 ++- tests/kit/src/utils/editor.ts | 2 +- tests/kit/src/utils/properties.ts | 2 +- 28 files changed, 136 insertions(+), 121 deletions(-) diff --git a/blocksuite/integration-test/src/__tests__/utils/renderer-entry.ts b/blocksuite/integration-test/src/__tests__/utils/renderer-entry.ts index d8ceea9bbe..269e812536 100644 --- a/blocksuite/integration-test/src/__tests__/utils/renderer-entry.ts +++ b/blocksuite/integration-test/src/__tests__/utils/renderer-entry.ts @@ -11,7 +11,7 @@ import { addSampleNotes } from './doc-generator.js'; import { createPainterWorker, setupEditor } from './setup.js'; async function init() { - setupEditor('edgeless', [ + await setupEditor('edgeless', [ ParagraphLayoutHandlerExtension, ListLayoutHandlerExtension, ImageLayoutHandlerExtension, @@ -29,4 +29,4 @@ async function init() { window.renderer = renderer; } -init(); +await init(); diff --git a/eslint.config.mjs b/eslint.config.mjs index f8929b50f8..e6b9aced6a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -299,7 +299,10 @@ export default tseslint.config( '**/e2e/**/*', ], rules: { - '@typescript-eslint/no-floating-promises': 0, + '@typescript-eslint/no-floating-promises': [ + 'error', + { ignoreVoid: true }, + ], '@typescript-eslint/no-misused-promises': 0, '@typescript-eslint/no-restricted-imports': 0, }, diff --git a/packages/backend/server/src/__tests__/copilot.e2e.ts b/packages/backend/server/src/__tests__/copilot.e2e.ts index 04d507eee5..a5fd17f5a7 100644 --- a/packages/backend/server/src/__tests__/copilot.e2e.ts +++ b/packages/backend/server/src/__tests__/copilot.e2e.ts @@ -181,7 +181,7 @@ test('should create session correctly', async t => { ); }); - app.switchUser(u1); + await app.switchUser(u1); const inviteId = await inviteUser(app, id, u2.email); await app.login(u2); await acceptInviteById(app, id, inviteId, false); @@ -329,9 +329,9 @@ test('should fork session correctly', async t => { ); }); - app.switchUser(u1); + await app.switchUser(u1); const inviteId = await inviteUser(app, id, u2.email); - app.switchUser(u2); + await app.switchUser(u2); await acceptInviteById(app, id, inviteId, false); await assertForkSession(id, sessionId, randomUUID(), '', async x => { await t.throwsAsync( @@ -341,14 +341,14 @@ test('should fork session correctly', async t => { ); }); - app.switchUser(u1); + await app.switchUser(u1); const histories = await getHistories(app, { workspaceId: id }); const latestMessageId = histories .find(h => h.sessionId === forkedSessionId) ?.messages.findLast(m => m.role === 'assistant')?.id; t.truthy(latestMessageId, 'should find latest message id'); - app.switchUser(u2); + await app.switchUser(u2); await assertForkSession( id, forkedSessionId, @@ -654,10 +654,10 @@ test('should reject request from different user', async t => { // should reject chat from different user { - app.switchUser(u1); + await app.switchUser(u1); const messageId = await createCopilotMessage(app, sessionId); { - app.switchUser(u2); + await app.switchUser(u2); await t.throwsAsync( chatWithText(app, sessionId, messageId), { instanceOf: Error }, @@ -723,9 +723,9 @@ test('should reject request that user have not permission', async t => { // should able to list history after user have permission { - app.switchUser(u1); + await app.switchUser(u1); const inviteId = await inviteUser(app, workspaceId, u2.email); - app.switchUser(u2); + await app.switchUser(u2); await acceptInviteById(app, workspaceId, inviteId, false); t.deepEqual( @@ -753,7 +753,7 @@ test('should reject request that user have not permission', async t => { 'should able to list history' ); - app.switchUser(u1); + await app.switchUser(u1); t.deepEqual( await getHistories(app, { workspaceId }), [], diff --git a/packages/backend/server/src/__tests__/e2e/test.ts b/packages/backend/server/src/__tests__/e2e/test.ts index 30ac3998ae..7b6972dd3f 100644 --- a/packages/backend/server/src/__tests__/e2e/test.ts +++ b/packages/backend/server/src/__tests__/e2e/test.ts @@ -6,6 +6,6 @@ export const e2e = test; // @ts-expect-error created in prelude.ts export const app: TestingApp = globalThis.app; -registerCompletionHandler(() => { - app.close(); +registerCompletionHandler(async () => { + await app.close(); }); diff --git a/packages/backend/server/src/__tests__/e2e/workspace/invite.spec.ts b/packages/backend/server/src/__tests__/e2e/workspace/invite.spec.ts index 280d4e4962..64e55530e3 100644 --- a/packages/backend/server/src/__tests__/e2e/workspace/invite.spec.ts +++ b/packages/backend/server/src/__tests__/e2e/workspace/invite.spec.ts @@ -77,7 +77,7 @@ e2e('should leave a workspace', async t => { userId: u2.id, }); - app.switchUser(u2.id); + await app.switchUser(u2.id); const { leaveWorkspace } = await app.gql({ query: leaveWorkspaceMutation, variables: { @@ -182,7 +182,7 @@ e2e('should invite a user by link', async t => { }, }); - app.switchUser(u2); + await app.switchUser(u2); const accept = await app.gql({ query: acceptInviteByInviteIdMutation, variables: { @@ -192,7 +192,7 @@ e2e('should invite a user by link', async t => { }); t.true(accept.acceptInviteById, 'failed to accept invite'); - app.switchUser(owner); + await app.switchUser(owner); const invite2 = await app.gql({ query: inviteByEmailMutation, variables: { @@ -233,7 +233,7 @@ e2e('should send invitation notification and leave email', async t => { t.is(invitationNotification.payload.inviterId, owner.id); t.is(invitationNotification.payload.inviteId, invite.invite); - app.switchUser(u2); + await app.switchUser(u2); const accept = await app.gql({ query: acceptInviteByInviteIdMutation, variables: { diff --git a/packages/backend/server/src/__tests__/mocks/copilot.mock.ts b/packages/backend/server/src/__tests__/mocks/copilot.mock.ts index 0d34dde72d..006884883e 100644 --- a/packages/backend/server/src/__tests__/mocks/copilot.mock.ts +++ b/packages/backend/server/src/__tests__/mocks/copilot.mock.ts @@ -42,7 +42,7 @@ export class MockCopilotProvider extends OpenAIProvider { model: string = 'test', options: CopilotChatOptions = {} ): Promise { - this.checkParams({ messages, model, options }); + await this.checkParams({ messages, model, options }); // make some time gap for history test case await sleep(100); return 'generate text to text'; @@ -53,7 +53,7 @@ export class MockCopilotProvider extends OpenAIProvider { model: string = 'gpt-4.1-mini', options: CopilotChatOptions = {} ): AsyncIterable { - this.checkParams({ messages, model, options }); + await this.checkParams({ messages, model, options }); // make some time gap for history test case await sleep(100); @@ -74,7 +74,7 @@ export class MockCopilotProvider extends OpenAIProvider { options: CopilotEmbeddingOptions = { dimensions: DEFAULT_DIMENSIONS } ): Promise { messages = Array.isArray(messages) ? messages : [messages]; - this.checkParams({ embeddings: messages, model, options }); + await this.checkParams({ embeddings: messages, model, options }); // make some time gap for history test case await sleep(100); diff --git a/packages/backend/server/src/__tests__/team.e2e.ts b/packages/backend/server/src/__tests__/team.e2e.ts index 6f0097c67b..d9865855b2 100644 --- a/packages/backend/server/src/__tests__/team.e2e.ts +++ b/packages/backend/server/src/__tests__/team.e2e.ts @@ -90,9 +90,14 @@ const init = async ( const workspace = await createWorkspace(app); const teamWorkspace = await createWorkspace(app); { - models.workspaceFeature.add(teamWorkspace.id, 'team_plan_v1', 'test', { - memberLimit, - }); + await models.workspaceFeature.add( + teamWorkspace.id, + 'team_plan_v1', + 'test', + { + memberLimit, + } + ); } const invite = async ( @@ -104,29 +109,29 @@ const init = async ( { // normal workspace - app.switchUser(owner); + await app.switchUser(owner); const inviteId = await inviteUser( app, workspace.id, member.email, shouldSendEmail ); - app.switchUser(member); + await app.switchUser(member); await acceptInviteById(app, workspace.id, inviteId, shouldSendEmail); } { // team workspace - app.switchUser(owner); + await app.switchUser(owner); const inviteId = await inviteUser( app, teamWorkspace.id, member.email, shouldSendEmail ); - app.switchUser(member); + await app.switchUser(member); await acceptInviteById(app, teamWorkspace.id, inviteId, shouldSendEmail); - app.switchUser(owner); + await app.switchUser(owner); await grantMember(app, teamWorkspace.id, member.id, permission); } @@ -143,7 +148,7 @@ const init = async ( members.push(member); } - app.switchUser(owner); + await app.switchUser(owner); const invites = await inviteUsers( app, teamWorkspace.id, @@ -154,7 +159,7 @@ const init = async ( }; const getCreateInviteLinkFetcher = async (ws: WorkspaceType) => { - app.switchUser(owner); + await app.switchUser(owner); const { link } = await createInviteLink(app, ws.id, 'OneDay'); const inviteId = link.split('/').pop()!; return [ @@ -165,7 +170,7 @@ const init = async ( return member; }, async (userId: string) => { - app.switchUser(userId); + await app.switchUser(userId); await acceptInviteById(app, ws.id, inviteId, false); }, ] as const; @@ -183,7 +188,7 @@ const init = async ( WorkspaceRole.External ); - app.switchUser(owner.id); + await app.switchUser(owner.id); return { invite, inviteBatch, @@ -204,13 +209,13 @@ test('should be able to invite multiple users', async t => { { // no permission - app.switchUser(read); + await app.switchUser(read); await t.throwsAsync( inviteUsers(app, ws.id, ['test@affine.pro']), { instanceOf: Error }, 'should throw error if not manager' ); - app.switchUser(write); + await app.switchUser(write); await t.throwsAsync( inviteUsers(app, ws.id, ['test@affine.pro']), { instanceOf: Error }, @@ -222,13 +227,13 @@ test('should be able to invite multiple users', async t => { // manager const m1 = await app.signupV1('m1@affine.pro'); const m2 = await app.signupV1('m2@affine.pro'); - app.switchUser(owner); + await app.switchUser(owner); t.is( (await inviteUsers(app, ws.id, [m1.email])).length, 1, 'should be able to invite user' ); - app.switchUser(admin); + await app.switchUser(admin); t.is( (await inviteUsers(app, ws.id, [m2.email])).length, 1, @@ -263,7 +268,7 @@ test('should be able to check seat limit', async t => { { message: 'You have exceeded your workspace member quota.' }, 'should throw error if exceed member limit' ); - models.workspaceFeature.add(ws.id, 'team_plan_v1', 'test', { + await models.workspaceFeature.add(ws.id, 'team_plan_v1', 'test', { memberLimit: 6, }); await t.notThrowsAsync( @@ -310,14 +315,14 @@ test('should be able to grant team member permission', async t => { const { app, models } = t.context; const { owner, teamWorkspace: ws, write, read } = await init(app); - app.switchUser(read); + await app.switchUser(read); await t.throwsAsync( grantMember(app, ws.id, write.id, WorkspaceRole.Collaborator), { instanceOf: Error }, 'should throw error if not owner' ); - app.switchUser(write); + await app.switchUser(write); await t.throwsAsync( grantMember(app, ws.id, read.id, WorkspaceRole.Collaborator), { instanceOf: Error }, @@ -326,7 +331,7 @@ test('should be able to grant team member permission', async t => { { // owner should be able to grant permission - app.switchUser(owner); + await app.switchUser(owner); t.true( (await models.workspaceUser.get(ws.id, read.id))?.type === WorkspaceRole.Collaborator, @@ -348,24 +353,24 @@ test('should be able to leave workspace', async t => { const { app } = t.context; const { owner, teamWorkspace: ws, admin, write, read } = await init(app); - app.switchUser(owner); + await app.switchUser(owner); await t.throwsAsync(leaveWorkspace(app, ws.id), { message: 'Owner can not leave the workspace.', }); - app.switchUser(admin); + await app.switchUser(admin); t.true( await leaveWorkspace(app, ws.id), 'admin should be able to leave workspace' ); - app.switchUser(write); + await app.switchUser(write); t.true( await leaveWorkspace(app, ws.id), 'write should be able to leave workspace' ); - app.switchUser(read); + await app.switchUser(read); t.true( await leaveWorkspace(app, ws.id), 'read should be able to leave workspace' @@ -378,7 +383,7 @@ test('should be able to revoke team member', async t => { { // no permission - app.switchUser(read); + await app.switchUser(read); await t.throwsAsync( revokeUser(app, ws.id, read.id), { instanceOf: Error }, @@ -393,7 +398,7 @@ test('should be able to revoke team member', async t => { { // manager - app.switchUser(admin); + await app.switchUser(admin); t.true( await revokeUser(app, ws.id, read.id), 'admin should be able to revoke member' @@ -405,7 +410,7 @@ test('should be able to revoke team member', async t => { 'should not be able to revoke themselves' ); - app.switchUser(owner); + await app.switchUser(owner); t.true( await revokeUser(app, ws.id, write.id), 'owner should be able to revoke member' @@ -416,7 +421,7 @@ test('should be able to revoke team member', async t => { }); await revokeUser(app, ws.id, admin.id); - app.switchUser(admin); + await app.switchUser(admin); await t.throwsAsync( revokeUser(app, ws.id, read.id), { instanceOf: Error }, @@ -441,7 +446,7 @@ test('should be able to manage invite link', async t => { [tws, [owner, admin]], ] as const) { for (const manager of managers) { - app.switchUser(manager.id); + await app.switchUser(manager.id); const { link } = await createInviteLink(app, workspace.id, 'OneDay'); const { link: currLink } = await getInviteLink(app, workspace.id); t.is(link, currLink, 'should be able to get invite link'); @@ -453,7 +458,7 @@ test('should be able to manage invite link', async t => { } for (const collaborator of [write, read]) { - app.switchUser(collaborator.id); + await app.switchUser(collaborator.id); await t.throwsAsync( createInviteLink(app, workspace.id, 'OneDay'), { instanceOf: Error }, @@ -478,7 +483,7 @@ test('should be able to approve team member', async t => { const { teamWorkspace: tws, owner, admin, write, read } = await init(app, 6); { - app.switchUser(owner); + await app.switchUser(owner); const { link } = await createInviteLink(app, tws.id, 'OneDay'); const inviteId = link.split('/').pop()!; @@ -488,7 +493,7 @@ test('should be able to approve team member', async t => { 'should be able to accept invite' ); - app.switchUser(owner); + await app.switchUser(owner); const { members } = await getWorkspace(app, tws.id); const memberInvite = members.find(m => m.id === member.id)!; t.is(memberInvite.status, 'UnderReview', 'should be under review'); @@ -509,21 +514,21 @@ test('should be able to approve team member', async t => { } { - app.switchUser(admin); + await app.switchUser(admin); await t.throwsAsync( approveMember(app, tws.id, 'not_exists_id'), { instanceOf: Error }, 'should throw error if member not exists' ); - app.switchUser(write); + await app.switchUser(write); await t.throwsAsync( approveMember(app, tws.id, 'not_exists_id'), { instanceOf: Error }, 'should throw error if not manager' ); - app.switchUser(read); + await app.switchUser(read); await t.throwsAsync( approveMember(app, tws.id, 'not_exists_id'), { instanceOf: Error }, @@ -547,7 +552,7 @@ test('should be able to invite by link', async t => { const member = await app.signup(); { // check invite link - app.switchUser(member); + await app.switchUser(member); const info = await getInviteInfo(app, inviteId); t.is(info.workspace.id, ws.id, 'should be able to get invite info'); t.falsy(info.status); @@ -601,7 +606,7 @@ test('should be able to invite by link', async t => { 'should not change status' ); - models.workspaceFeature.add(tws.id, 'team_plan_v1', 'test', { + await models.workspaceFeature.add(tws.id, 'team_plan_v1', 'test', { memberLimit: 6, }); await models.workspaceUser.refresh(tws.id, 6); @@ -616,7 +621,7 @@ test('should be able to invite by link', async t => { 'should not change status' ); - models.workspaceFeature.add(tws.id, 'team_plan_v1', 'test', { + await models.workspaceFeature.add(tws.id, 'team_plan_v1', 'test', { memberLimit: 7, }); await models.workspaceUser.refresh(tws.id, 7); @@ -670,7 +675,7 @@ test('should be able to emit events and send notifications', async t => { const { teamWorkspace: tws, owner, createInviteLink } = await init(app); const [, invite] = await createInviteLink(tws); const user = await invite('m3@affine.pro'); - app.switchUser(owner); + await app.switchUser(owner); const { members } = await getWorkspace(app, tws.id); const memberInvite = members.find(m => m.id === user.id)!; const requestRequestNotification = app.queue.last( @@ -688,7 +693,7 @@ test('should be able to emit events and send notifications', async t => { 'should send review request notification' ); - app.switchUser(owner); + await app.switchUser(owner); await revokeUser(app, tws.id, user.id); const requestDeclinedNotification = app.queue.last( 'notification.sendInvitationReviewDeclined' @@ -735,7 +740,7 @@ test('should be able to emit events and send notifications', async t => { 'should emit owner transferred event' ); - app.switchUser(read); + await app.switchUser(read); await revokeMember(app, tws.id, owner.id); const [memberRemoved, memberUpdated] = event.emit .getCalls() @@ -777,7 +782,7 @@ test('should be able to grant and revoke users role in page', async t => { } = await init(app, 5); const docId = nanoid(); - app.switchUser(admin); + await app.switchUser(admin); const res = await grantDocUserRoles( app, ws.id, @@ -795,7 +800,7 @@ test('should be able to grant and revoke users role in page', async t => { await grantDocUserRoles(app, ws.id, docId, [read.id], DocRole.Reader); // read still be the Manager of this doc - app.switchUser(read); + await app.switchUser(read); const res = await grantDocUserRoles( app, ws.id, @@ -807,7 +812,7 @@ test('should be able to grant and revoke users role in page', async t => { grantDocUserRoles: true, }); - app.switchUser(admin); + await app.switchUser(admin); const docUsersList = await docGrantedUsersList(app, ws.id, docId); t.is(docUsersList.workspace.doc.grantedUsersList.totalCount, 3); const externalRole = docUsersList.workspace.doc.grantedUsersList.edges.find( @@ -821,7 +826,7 @@ test('should be able to change the default role in page', async t => { const { app } = t.context; const { teamWorkspace: ws, admin } = await init(app, 5); const docId = nanoid(); - app.switchUser(admin); + await app.switchUser(admin); const res = await updateDocDefaultRole(app, ws.id, docId, DocRole.Reader); t.deepEqual(res, { @@ -840,7 +845,7 @@ test('default page role should be able to override the workspace role', async t const docId = nanoid(); - app.switchUser(admin); + await app.switchUser(admin); const res = await updateDocDefaultRole( app, workspace.id, @@ -854,7 +859,7 @@ test('default page role should be able to override the workspace role', async t // reader can manage the page if the page default role is Manager { - app.switchUser(read); + await app.switchUser(read); const readerRes = await updateDocDefaultRole( app, workspace.id, @@ -869,7 +874,7 @@ test('default page role should be able to override the workspace role', async t // external can't manage the page even if the page default role is Manager { - app.switchUser(external); + await app.switchUser(external); await t.throwsAsync( updateDocDefaultRole(app, workspace.id, docId, DocRole.Manager), { @@ -884,7 +889,7 @@ test('should be able to grant and revoke doc user role', async t => { const { teamWorkspace: ws, admin, read, external } = await init(app, 5); const docId = nanoid(); - app.switchUser(admin); + await app.switchUser(admin); const res = await grantDocUserRoles( app, ws.id, @@ -899,7 +904,7 @@ test('should be able to grant and revoke doc user role', async t => { // external user can never be able to manage the page { - app.switchUser(external); + await app.switchUser(external); await t.throwsAsync( grantDocUserRoles(app, ws.id, docId, [read.id], DocRole.Manager), { @@ -910,7 +915,7 @@ test('should be able to grant and revoke doc user role', async t => { // revoke the role of the external user { - app.switchUser(admin); + await app.switchUser(admin); const revokeRes = await revokeDocUserRoles(app, ws.id, docId, external.id); t.deepEqual(revokeRes, { @@ -918,7 +923,7 @@ test('should be able to grant and revoke doc user role', async t => { }); // external user can't manage the page - app.switchUser(external); + await app.switchUser(external); await t.throwsAsync(revokeDocUserRoles(app, ws.id, docId, read.id), { message: `You do not have permission to perform Doc.Users.Manage action on doc ${docId}.`, }); @@ -930,7 +935,7 @@ test('update page default role should throw error if the space does not exist', const { admin } = await init(app, 5); const docId = nanoid(); const nonExistWorkspaceId = 'non-exist-workspace'; - app.switchUser(admin); + await app.switchUser(admin); await t.throwsAsync( updateDocDefaultRole(app, nonExistWorkspaceId, docId, DocRole.Manager), { diff --git a/packages/backend/server/src/__tests__/worker.e2e.ts b/packages/backend/server/src/__tests__/worker.e2e.ts index 6521ee61df..c789884321 100644 --- a/packages/backend/server/src/__tests__/worker.e2e.ts +++ b/packages/backend/server/src/__tests__/worker.e2e.ts @@ -47,7 +47,7 @@ const assertAndSnapshotRaw = async ( .send(options?.body) .expect(status) .expect(checker); - t.notThrowsAsync(res, message); + await t.notThrowsAsync(res, message); t.snapshot((await res).body); }; diff --git a/packages/backend/server/src/__tests__/workspace.e2e.ts b/packages/backend/server/src/__tests__/workspace.e2e.ts index 5135e6e956..52d602ed2a 100644 --- a/packages/backend/server/src/__tests__/workspace.e2e.ts +++ b/packages/backend/server/src/__tests__/workspace.e2e.ts @@ -122,7 +122,7 @@ test('should be able to get workspace doc', async t => { const u1 = await app.signupV1('u1@affine.pro'); const u2 = await app.signupV1('u2@affine.pro'); - app.switchUser(u1.id); + await app.switchUser(u1.id); const workspace = await createWorkspace(app); const res1 = await app @@ -136,7 +136,7 @@ test('should be able to get workspace doc', async t => { 'failed to get doc with u1 token' ); - app.switchUser(u2.id); + await app.switchUser(u2.id); await app .GET(`/api/workspaces/${workspace.id}/docs/${workspace.id}`) .expect(403); diff --git a/packages/backend/server/src/base/storage/__tests__/fs.spec.ts b/packages/backend/server/src/base/storage/__tests__/fs.spec.ts index 3f1f36b874..84ac4c4881 100644 --- a/packages/backend/server/src/base/storage/__tests__/fs.spec.ts +++ b/packages/backend/server/src/base/storage/__tests__/fs.spec.ts @@ -28,12 +28,12 @@ async function randomPut( ): Promise { const key = prefix + 'test-key-' + Math.random().toString(16).substring(2, 8); const body = Buffer.from(key); - provider.put(key, body); + await provider.put(key, body); return key; } test.after.always(() => { - fs.rm(config.path, { recursive: true }); + fs.rm(config.path, { recursive: true }).catch(console.error); }); test('put & get', async t => { diff --git a/packages/common/infra/src/utils/__tests__/async-queue.spec.ts b/packages/common/infra/src/utils/__tests__/async-queue.spec.ts index 017401ec84..d5ddc5e312 100644 --- a/packages/common/infra/src/utils/__tests__/async-queue.spec.ts +++ b/packages/common/infra/src/utils/__tests__/async-queue.spec.ts @@ -22,12 +22,18 @@ describe('async-queue', () => { let v = -1; // setup 2 pop tasks - queue.next().then(next => { - v = next; - }); - queue.next().then(next => { - v = next; - }); + queue + .next() + .then(next => { + v = next; + }) + .catch(console.error); + queue + .next() + .then(next => { + v = next; + }) + .catch(console.error); // Wait for 100ms await new Promise(resolve => setTimeout(resolve, 100)); diff --git a/packages/frontend/component/src/ui/audio-player/audio-player.stories.tsx b/packages/frontend/component/src/ui/audio-player/audio-player.stories.tsx index b3e79378ac..c58288bba5 100644 --- a/packages/frontend/component/src/ui/audio-player/audio-player.stories.tsx +++ b/packages/frontend/component/src/ui/audio-player/audio-player.stories.tsx @@ -82,7 +82,7 @@ const AudioWrapper = () => { e.preventDefault(); const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('audio/')) { - handleFileChange(file); + handleFileChange(file).catch(console.error); } }, [handleFileChange] @@ -92,7 +92,7 @@ const AudioWrapper = () => { (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { - handleFileChange(file); + handleFileChange(file).catch(console.error); } }, [handleFileChange] diff --git a/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts b/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts index 632f7ac0e9..c25a9d9d90 100644 --- a/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts +++ b/tests/affine-cloud-copilot/e2e/basic/chat.spec.ts @@ -113,7 +113,7 @@ test.describe('AIBasic/Chat', () => { }, ]); - expect(page.getByTestId('chat-action-list')).toBeVisible(); + await expect(page.getByTestId('chat-action-list')).toBeVisible(); await utils.chatPanel.makeChat(page, 'Nice to meet you'); await utils.chatPanel.waitForHistory(page, [ { @@ -458,7 +458,7 @@ test.describe('AIBasic/Chat', () => { await sendButton.click(); await expect(page.getByTestId('sidebar-tab-content-chat')).toBeVisible(); - expect(await page.locator('chat-content-images')).toBeVisible(); + await expect(page.locator('chat-content-images')).toBeVisible(); await utils.chatPanel.waitForHistory(page, [ { role: 'user', diff --git a/tests/affine-cloud-copilot/e2e/chat-with/network.spec.ts b/tests/affine-cloud-copilot/e2e/chat-with/network.spec.ts index b22182d399..4a25510672 100644 --- a/tests/affine-cloud-copilot/e2e/chat-with/network.spec.ts +++ b/tests/affine-cloud-copilot/e2e/chat-with/network.spec.ts @@ -81,7 +81,7 @@ test.describe('AIChatWith/Network', () => { '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'; const buffer = Buffer.from(image, 'base64'); - page.evaluate(() => { + await page.evaluate(() => { delete window.showOpenFilePicker; }, buffer); diff --git a/tests/affine-cloud-copilot/e2e/insertion/add-to-edgeless-as-note.spec.ts b/tests/affine-cloud-copilot/e2e/insertion/add-to-edgeless-as-note.spec.ts index 89c5e4ee26..6419f177f3 100644 --- a/tests/affine-cloud-copilot/e2e/insertion/add-to-edgeless-as-note.spec.ts +++ b/tests/affine-cloud-copilot/e2e/insertion/add-to-edgeless-as-note.spec.ts @@ -44,7 +44,7 @@ test.describe('AIInsertion/AddToEdgelessAsNote', () => { // Delete default note await (await page.waitForSelector('affine-edgeless-note')).click(); - page.keyboard.press('Delete'); + await page.keyboard.press('Delete'); await utils.chatPanel.openChatPanel(page); await utils.chatPanel.makeChat(page, 'Hello'); diff --git a/tests/affine-cloud-copilot/e2e/insertion/insert.spec.ts b/tests/affine-cloud-copilot/e2e/insertion/insert.spec.ts index c5ff40de74..cf1d110edc 100644 --- a/tests/affine-cloud-copilot/e2e/insertion/insert.spec.ts +++ b/tests/affine-cloud-copilot/e2e/insertion/insert.spec.ts @@ -170,7 +170,7 @@ test.describe('AIInsertion/Insert', () => { // Delete default note await (await page.waitForSelector('affine-edgeless-note')).click(); - page.keyboard.press('Delete'); + await page.keyboard.press('Delete'); await utils.chatPanel.openChatPanel(page); await utils.chatPanel.makeChat(page, 'Hello'); diff --git a/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts b/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts index c245c43d4c..13c6e1a1bf 100644 --- a/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts +++ b/tests/affine-cloud-copilot/e2e/utils/chat-panel-utils.ts @@ -30,6 +30,10 @@ export class ChatPanelUtils { await page.getByTestId('right-sidebar-toggle').click({ delay: 200, }); + await page.waitForTimeout(500); // wait the sidebar stable + } + if (await page.getByTestId('notification-close-button').isVisible()) { + await page.getByTestId('notification-close-button').click(); } await page.getByTestId('sidebar-tab-chat').click(); await expect(page.getByTestId('sidebar-tab-content-chat')).toBeVisible(); @@ -291,14 +295,14 @@ export class ChatPanelUtils { } public static async enableNetworkSearch(page: Page) { - const networkSearch = await page.getByTestId('chat-network-search'); + const networkSearch = page.getByTestId('chat-network-search'); if ((await networkSearch.getAttribute('data-active')) === 'false') { await networkSearch.click(); } } public static async disableNetworkSearch(page: Page) { - const networkSearch = await page.getByTestId('chat-network-search'); + const networkSearch = page.getByTestId('chat-network-search'); if ((await networkSearch.getAttribute('data-active')) === 'true') { await networkSearch.click(); } diff --git a/tests/affine-cloud-copilot/e2e/utils/editor-utils.ts b/tests/affine-cloud-copilot/e2e/utils/editor-utils.ts index a8dde1dc32..e732a7d9b6 100644 --- a/tests/affine-cloud-copilot/e2e/utils/editor-utils.ts +++ b/tests/affine-cloud-copilot/e2e/utils/editor-utils.ts @@ -51,7 +51,7 @@ export class EditorUtils { public static async switchToEdgelessMode(page: Page) { const editor = await page.waitForSelector('page-editor'); await page.getByTestId('switch-edgeless-mode-button').click(); - editor.waitForElementState('hidden'); + await editor.waitForElementState('hidden'); await page.waitForSelector('edgeless-editor'); try { const edgelessNotificationClose = page.getByTestId( @@ -408,9 +408,7 @@ export class EditorUtils { checkCodeError: this.createAction(page, () => page.getByTestId('action-check-code-error').click() ), - continueWithAi: async () => { - page.getByTestId('action-continue-with-ai').click(); - }, + continueWithAi: () => page.getByTestId('action-continue-with-ai').click(), continueWriting: this.createAction(page, () => page.getByTestId('action-continue-writing').click() ), @@ -596,9 +594,7 @@ export class EditorUtils { checkCodeError: this.createAction(page, () => page.getByTestId('action-check-code-error').click() ), - continueWithAi: async () => { - page.getByTestId('action-continue-with-ai').click(); - }, + continueWithAi: () => page.getByTestId('action-continue-with-ai').click(), continueWriting: this.createAction(page, () => page.getByTestId('action-continue-writing').click() ), diff --git a/tests/affine-cloud/e2e/collaboration.spec.ts b/tests/affine-cloud/e2e/collaboration.spec.ts index 8868218588..c562c057da 100644 --- a/tests/affine-cloud/e2e/collaboration.spec.ts +++ b/tests/affine-cloud/e2e/collaboration.spec.ts @@ -164,7 +164,7 @@ test('can sync svg between different browsers', async ({ page, browser }) => { const fileChooserPromise = page.waitForEvent('filechooser'); await page.keyboard.press('Enter', { delay: 50 }); const fileChooser = await fileChooserPromise; - fileChooser.setFiles(Path.dir(import.meta.url).join('logo.svg').value); + await fileChooser.setFiles(Path.dir(import.meta.url).join('logo.svg').value); await expect(image).toBeVisible(); // the user should see the svg diff --git a/tests/affine-cloud/e2e/template.spec.ts b/tests/affine-cloud/e2e/template.spec.ts index 573bd0ba62..09e6cb6c1b 100644 --- a/tests/affine-cloud/e2e/template.spec.ts +++ b/tests/affine-cloud/e2e/template.spec.ts @@ -28,6 +28,6 @@ test('import from template should work', async ({ page }) => { const btn = page.getByTestId('import-template-to-workspace-btn'); await btn.isVisible(); - btn.click(); + await btn.click(); await waitForEditorLoad(page); }); diff --git a/tests/affine-local/e2e/blocksuite/list.spec.ts b/tests/affine-local/e2e/blocksuite/list.spec.ts index 5ba70a6646..89c7d206b6 100644 --- a/tests/affine-local/e2e/blocksuite/list.spec.ts +++ b/tests/affine-local/e2e/blocksuite/list.spec.ts @@ -48,7 +48,7 @@ test.describe('split list', () => { listLocator.nth(2).locator('.affine-list-block__numbered') ).toHaveText('2.'); await expect(listLocator.nth(3).locator('rich-text')).toHaveText('ddd'); - expect( + await expect( listLocator.nth(3).locator('.affine-list-block__numbered') ).toHaveText('3.'); diff --git a/tests/affine-local/e2e/local-first-workspace-list.spec.ts b/tests/affine-local/e2e/local-first-workspace-list.spec.ts index b919e78ea5..e082131e98 100644 --- a/tests/affine-local/e2e/local-first-workspace-list.spec.ts +++ b/tests/affine-local/e2e/local-first-workspace-list.spec.ts @@ -137,15 +137,14 @@ test.skip('create multi workspace in the workspace list', async ({ await expect(workspaceCards).toHaveCount(3); } - const workspaceChangePromise = page.evaluate(() => { - new Promise(resolve => { + await page.getByTestId('draggable-item').nth(2).click(); + await page.evaluate(async () => { + await new Promise(resolve => { window.addEventListener('affine:workspace:change', resolve, { once: true, }); }); }); - await page.getByTestId('draggable-item').nth(2).click(); - await workspaceChangePromise; const nextWorkspace = await workspace.current(); diff --git a/tests/blocksuite/e2e/edgeless/frame/frame-mindmap.spec.ts b/tests/blocksuite/e2e/edgeless/frame/frame-mindmap.spec.ts index 3cb41587b3..3b4869a98e 100644 --- a/tests/blocksuite/e2e/edgeless/frame/frame-mindmap.spec.ts +++ b/tests/blocksuite/e2e/edgeless/frame/frame-mindmap.spec.ts @@ -178,7 +178,7 @@ test('add mindmap into frame, then drag root node of mindmap out.', async ({ // drag out { const mindmapBound = await getSelectedBound(page); - pressEscape(page); + await pressEscape(page); await clickView(page, [ mindmapBound[0] + 10, mindmapBound[1] + 0.5 * mindmapBound[3], diff --git a/tests/blocksuite/e2e/edgeless/lock.spec.ts b/tests/blocksuite/e2e/edgeless/lock.spec.ts index 9f80c54912..51eec1266e 100644 --- a/tests/blocksuite/e2e/edgeless/lock.spec.ts +++ b/tests/blocksuite/e2e/edgeless/lock.spec.ts @@ -290,8 +290,8 @@ test.describe('lock', () => { await selectAllByKeyboard(page); await dragBetweenViewCoords(page, [100, 100], [150, 150]); - assertEdgelessElementBound(page, frame, [100, 100, 200, 200]); - assertEdgelessElementBound(page, shape, [150, 150, 50, 50]); + await assertEdgelessElementBound(page, frame, [100, 100, 200, 200]); + await assertEdgelessElementBound(page, shape, [150, 150, 50, 50]); }); test('locked element should not be scalable and rotatable. unlocking will recover', async ({ diff --git a/tests/blocksuite/e2e/embed-synced-doc/edgeless.spec.ts b/tests/blocksuite/e2e/embed-synced-doc/edgeless.spec.ts index 0748cdc6c5..ea0f795543 100644 --- a/tests/blocksuite/e2e/embed-synced-doc/edgeless.spec.ts +++ b/tests/blocksuite/e2e/embed-synced-doc/edgeless.spec.ts @@ -196,7 +196,7 @@ test.describe('Embed synced doc in edgeless mode', () => { await expect(edgelessNotes).toHaveCount(2); expect(await getSelectedIds(page)).toHaveLength(1); expect(await getSelectedIds(page)).not.toContain(prevIds); - expect(edgelessNotes.last()).toBeVisible(); + await expect(edgelessNotes.last()).toBeVisible(); const noteBound = await getSelectedBound(page); expect(isIntersected(embedDocBound, noteBound)).toBe(false); diff --git a/tests/blocksuite/e2e/embed-synced-doc/utils.ts b/tests/blocksuite/e2e/embed-synced-doc/utils.ts index 823429b89c..cfcc67b6d7 100644 --- a/tests/blocksuite/e2e/embed-synced-doc/utils.ts +++ b/tests/blocksuite/e2e/embed-synced-doc/utils.ts @@ -27,7 +27,7 @@ export async function initEmbedSyncedDocState( } return await page.evaluate( - ({ data, option }) => { + async ({ data, option }) => { const createDoc = async ( docId: string, title: string, @@ -69,11 +69,13 @@ export async function initEmbedSyncedDocState( return note ?? null; }; - const docIds = data.map(({ title, content }, index) => { - const id = index === 0 ? window.doc.id : `embed-doc-${index}`; - createDoc(id, title, content); - return id; - }); + const docIds = await Promise.all( + data.map(async ({ title, content }, index) => { + const id = index === 0 ? window.doc.id : `embed-doc-${index}`; + await createDoc(id, title, content); + return id; + }) + ); const { NoteBlockModel, NoteDisplayMode } = window.$blocksuite.affineModel; diff --git a/tests/kit/src/utils/editor.ts b/tests/kit/src/utils/editor.ts index 3b3086d6da..bd24c13a09 100644 --- a/tests/kit/src/utils/editor.ts +++ b/tests/kit/src/utils/editor.ts @@ -473,7 +473,7 @@ export async function createEdgelessNoteBlock( ) { await setEdgelessTool(page, 'note', undefined, editorIndex); if (position.length === 4) { - dragView( + await dragView( page, [position[0], position[1]], [position[0] + position[2], position[1] + position[3]] diff --git a/tests/kit/src/utils/properties.ts b/tests/kit/src/utils/properties.ts index 6495c385d7..3a8676674b 100644 --- a/tests/kit/src/utils/properties.ts +++ b/tests/kit/src/utils/properties.ts @@ -122,7 +122,7 @@ export const addCustomProperty = async ( root: Locator | Page, type: string ) => { - ensureAddPropertyButtonVisible(page, root); + await ensureAddPropertyButtonVisible(page, root); await clickAddPropertyButton(root); await page .locator(