From 05e433538962fc62ef1c7eed2277a6fdc760b58e Mon Sep 17 00:00:00 2001 From: LordMathis Date: Tue, 23 Sep 2025 19:45:45 +0200 Subject: [PATCH] Fix instance management tests --- webui/src/__tests__/App.test.tsx | 15 +++- .../__tests__/InstanceCard.test.tsx | 73 ++++++++++++++----- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/webui/src/__tests__/App.test.tsx b/webui/src/__tests__/App.test.tsx index 4358321..857ff0e 100644 --- a/webui/src/__tests__/App.test.tsx +++ b/webui/src/__tests__/App.test.tsx @@ -160,7 +160,7 @@ describe('App Component - Critical Business Logic Only', () => { expect(screen.getAllByTitle('Start instance').length).toBeGreaterThan(0) expect(screen.getAllByTitle('Stop instance').length).toBeGreaterThan(0) expect(screen.getAllByTitle('Edit instance').length).toBe(2) - expect(screen.getAllByTitle('Delete instance').length).toBeGreaterThan(0) + expect(screen.getAllByTitle('More actions').length).toBe(2) }) it('delete confirmation calls correct API', async () => { @@ -174,8 +174,17 @@ describe('App Component - Critical Business Logic Only', () => { expect(screen.getByText('test-instance-1')).toBeInTheDocument() }) - const deleteButtons = screen.getAllByTitle('Delete instance') - await user.click(deleteButtons[0]) + // First click the "More actions" button to reveal the delete button + const moreActionsButtons = screen.getAllByTitle('More actions') + await user.click(moreActionsButtons[0]) + + // Wait for the delete button to appear and click it + await waitFor(() => { + expect(screen.getByTitle('Delete instance')).toBeInTheDocument() + }) + + const deleteButton = screen.getByTitle('Delete instance') + await user.click(deleteButton) // Verify confirmation and API call expect(confirmSpy).toHaveBeenCalledWith('Are you sure you want to delete instance "test-instance-1"?') diff --git a/webui/src/components/__tests__/InstanceCard.test.tsx b/webui/src/components/__tests__/InstanceCard.test.tsx index e0c788a..f45b65b 100644 --- a/webui/src/components/__tests__/InstanceCard.test.tsx +++ b/webui/src/components/__tests__/InstanceCard.test.tsx @@ -102,7 +102,7 @@ afterEach(() => { it('opens logs dialog when logs button clicked', async () => { const user = userEvent.setup() - + render( { /> ) + // First click "More actions" to reveal the logs button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + const logsButton = screen.getByTitle('View logs') await user.click(logsButton) - + // Should open logs dialog (we can verify this by checking if dialog title appears) expect(screen.getByText(`Logs: ${stoppedInstance.name}`)).toBeInTheDocument() }) @@ -125,7 +129,7 @@ afterEach(() => { it('shows confirmation dialog and calls deleteInstance when confirmed', async () => { const user = userEvent.setup() const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true) - + render( { /> ) + // First click "More actions" to reveal the delete button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + const deleteButton = screen.getByTitle('Delete instance') await user.click(deleteButton) - + expect(confirmSpy).toHaveBeenCalledWith('Are you sure you want to delete instance "test-instance"?') expect(mockDeleteInstance).toHaveBeenCalledWith('test-instance') - + confirmSpy.mockRestore() }) it('does not call deleteInstance when confirmation cancelled', async () => { const user = userEvent.setup() const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(false) - + render( { /> ) + // First click "More actions" to reveal the delete button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + const deleteButton = screen.getByTitle('Delete instance') await user.click(deleteButton) - + expect(confirmSpy).toHaveBeenCalled() expect(mockDeleteInstance).not.toHaveBeenCalled() - + confirmSpy.mockRestore() }) }) describe('Button State Based on Instance Status', () => { - it('disables start button and enables stop button for running instance', () => { + it('disables start button and enables stop button for running instance', async () => { + const user = userEvent.setup() + render( { /> ) - expect(screen.getByTitle('Start instance')).toBeDisabled() + expect(screen.queryByTitle('Start instance')).not.toBeInTheDocument() expect(screen.getByTitle('Stop instance')).not.toBeDisabled() + + // Expand more actions to access delete button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + expect(screen.getByTitle('Delete instance')).toBeDisabled() // Can't delete running instance }) - it('enables start button and disables stop button for stopped instance', () => { + it('enables start button and disables stop button for stopped instance', async () => { + const user = userEvent.setup() + render( { ) expect(screen.getByTitle('Start instance')).not.toBeDisabled() - expect(screen.getByTitle('Stop instance')).toBeDisabled() + expect(screen.queryByTitle('Stop instance')).not.toBeInTheDocument() + + // Expand more actions to access delete button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + expect(screen.getByTitle('Delete instance')).not.toBeDisabled() // Can delete stopped instance }) - it('edit and logs buttons are always enabled', () => { + it('edit and logs buttons are always enabled', async () => { + const user = userEvent.setup() + render( { ) expect(screen.getByTitle('Edit instance')).not.toBeDisabled() + + // Expand more actions to access logs button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + expect(screen.getByTitle('View logs')).not.toBeDisabled() }) }) @@ -268,7 +301,7 @@ afterEach(() => { describe('Integration with LogsModal', () => { it('passes correct props to LogsModal', async () => { const user = userEvent.setup() - + render( { /> ) + // First click "More actions" to reveal the logs button + const moreActionsButton = screen.getByTitle('More actions') + await user.click(moreActionsButton) + // Open logs dialog await user.click(screen.getByTitle('View logs')) - + // Verify dialog opened with correct instance data expect(screen.getByText('Logs: running-instance')).toBeInTheDocument() - + // Close dialog to test close functionality const closeButtons = screen.getAllByText('Close') - const dialogCloseButton = closeButtons.find(button => + const dialogCloseButton = closeButtons.find(button => button.closest('[data-slot="dialog-content"]') ) expect(dialogCloseButton).toBeTruthy() await user.click(dialogCloseButton!) - + // Modal should close expect(screen.queryByText('Logs: running-instance')).not.toBeInTheDocument() })