From 2d4ec3b8776b4f76f3185bae3ad15786ecdf5228 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 13 Jul 2026 10:09:16 +0900 Subject: [PATCH] test(frontend): stabilize async coverage orchestration --- frontend/src/App.coverage.test.tsx | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/frontend/src/App.coverage.test.tsx b/frontend/src/App.coverage.test.tsx index d3bebea0..403a257e 100644 --- a/frontend/src/App.coverage.test.tsx +++ b/frontend/src/App.coverage.test.tsx @@ -322,8 +322,10 @@ describe('App orchestration coverage', () => { expect(screen.getAllByText('<Billing & Core>').length).toBeGreaterThan(0) fireEvent.click(screen.getByRole('button', { name: '전체 보기' })) expect(screen.getByRole('heading', { name: '프로젝트' })).toBeInTheDocument() - fireEvent.click(screen.getAllByRole('button', { name: '열기' })[1]!) + const openButtons = await screen.findAllByRole('button', { name: '열기' }) + fireEvent.click(openButtons[1]!) expect(screen.getByRole('heading', { name: '다이어그램' })).toBeInTheDocument() + await screen.findByText('ERD_all_2') fireEvent.change(screen.getByLabelText('다이어그램 검색'), { target: { value: 'no-match' } }) expect(screen.getByText('검색 결과가 없습니다.')).toBeInTheDocument() fireEvent.change(screen.getByLabelText('다이어그램 검색'), { target: { value: 'failed' } }) @@ -609,8 +611,9 @@ describe('App orchestration coverage', () => { it('logs auto-layout failures and preserves nodes added after the undo snapshot', async () => { await renderReadyApp() fireEvent.click(screen.getByRole('button', { name: '다이어그램' })) + const openButtons = await screen.findAllByRole('button', { name: '열기' }) vi.useFakeTimers() - fireEvent.click(screen.getAllByRole('button', { name: '열기' })[0]!) + fireEvent.click(openButtons[0]!) await act(async () => { vi.advanceTimersByTime(1000) await Promise.resolve() @@ -640,8 +643,9 @@ describe('App orchestration coverage', () => { .mockRejectedValueOnce(new Error('terminal refresh down')) await renderReadyApp() fireEvent.click(screen.getByRole('button', { name: '다이어그램' })) + const openButtons = await screen.findAllByRole('button', { name: '열기' }) vi.useFakeTimers() - fireEvent.click(screen.getAllByRole('button', { name: '열기' })[0]!) + fireEvent.click(openButtons[0]!) await act(async () => { vi.advanceTimersByTime(1000) await Promise.resolve() @@ -660,8 +664,16 @@ describe('App orchestration coverage', () => { .mockReturnValueOnce(new Promise((_resolve, reject) => { rejectSnapshots = reject })) .mockResolvedValueOnce(snapshots) await renderReadyApp() + await waitFor(() => { + expect(api.listConnections).toHaveBeenCalledWith('p1') + expect(api.listSnapshots).toHaveBeenCalledWith('p1') + }) fireEvent.click(screen.getByRole('button', { name: '편집기' })) fireEvent.change(screen.getByLabelText('Project'), { target: { value: 'p2' } }) + await waitFor(() => { + expect(api.listConnections).toHaveBeenCalledWith('p2') + expect(api.listSnapshots).toHaveBeenCalledWith('p2') + }) await act(async () => { rejectConnections(new Error('stale connections')) rejectSnapshots(new Error('stale snapshots')) @@ -743,8 +755,9 @@ describe('App orchestration coverage', () => { })) await renderReadyApp() fireEvent.click(screen.getByRole('button', { name: '다이어그램' })) + const openButtons = await screen.findAllByRole('button', { name: '열기' }) vi.useFakeTimers() - fireEvent.click(screen.getAllByRole('button', { name: '열기' })[0]!) + fireEvent.click(openButtons[0]!) await act(async () => { vi.advanceTimersByTime(1000) await Promise.resolve() @@ -783,8 +796,9 @@ describe('App orchestration coverage', () => { }) await renderReadyApp() fireEvent.click(screen.getByRole('button', { name: '다이어그램' })) + const openButtons = await screen.findAllByRole('button', { name: '열기' }) vi.useFakeTimers() - fireEvent.click(screen.getAllByRole('button', { name: '열기' })[0]!) + fireEvent.click(openButtons[0]!) await act(async () => { vi.advanceTimersByTime(1000) await Promise.resolve()