From e01cfd2f04573791855d52802a5c295ab4612b7f Mon Sep 17 00:00:00 2001 From: Karin Hendrikse <30577427+khendrikse@users.noreply.github.com> Date: Fri, 17 Oct 2025 14:04:12 +0200 Subject: [PATCH 1/2] fix: agents-create.test.ts hangs because of awaiting input --- .../commands/agents/agents-create.test.ts | 104 +++++++++--------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/tests/integration/commands/agents/agents-create.test.ts b/tests/integration/commands/agents/agents-create.test.ts index 04529165b08..407fa3814ce 100644 --- a/tests/integration/commands/agents/agents-create.test.ts +++ b/tests/integration/commands/agents/agents-create.test.ts @@ -1,17 +1,13 @@ import { beforeEach, describe, expect, test, vi } from 'vitest' +import execa from 'execa' import { callCli } from '../../utils/call-cli.js' +import { cliPath } from '../../utils/cli-path.js' import { getCLIOptions, withMockApi } from '../../utils/mock-api.js' import { withSiteBuilder } from '../../utils/site-builder.js' +import { answerWithValue, handleQuestions } from '../../utils/handle-questions.js' import { mockSiteInfo, mockSiteInfoNoRepo, mockAgentRunner, mockAgentRunnerNoRepo } from './fixtures.js' -// Mock inquirer for interactive prompts -vi.mock('inquirer', () => ({ - default: { - prompt: vi.fn(), - }, -})) - // Mock spinner to avoid UI interference in tests vi.mock('../../../../src/lib/spinner.js', () => ({ startSpinner: vi.fn(() => ({ text: 'test' })), @@ -72,12 +68,16 @@ describe('agents:create command', () => { await builder.build() await withMockApi(routes, async ({ apiUrl }) => { - const cliResponse = (await callCli( - ['agents:create', 'Create a form', '--agent', 'claude', '--json'], - getCLIOptions({ apiUrl, builder }), - true, // parseJson - )) as typeof mockAgentRunner - + const { stdout } = await execa( + cliPath, + ['agents:create', 'Create a form', '--agent', 'claude', '--branch', 'main', '--json'], + { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }, + ) + + const cliResponse = JSON.parse(stdout) as typeof mockAgentRunner expect(cliResponse).toEqual(mockAgentRunner) }) }) @@ -128,8 +128,11 @@ describe('agents:create command', () => { await withMockApi(routes, async ({ apiUrl }) => { await expect( - callCli(['agents:create', 'Create a form', '--agent', 'claude'], getCLIOptions({ apiUrl, builder })), - ).rejects.toThrow('Failed to create agent task: Unauthorized') + execa(cliPath, ['agents:create', 'Create a form', '--agent', 'claude', '--branch', 'main'], { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }), + ).rejects.toThrow() }) }) }) @@ -172,17 +175,17 @@ describe('agents:create command', () => { await builder.build() await withMockApi(routes, async ({ apiUrl }) => { - const cliResponse = (await callCli( - ['agents:create', 'Add a contact form', '--agent', 'claude'], - getCLIOptions({ apiUrl, builder, env: { NETLIFY_SITE_ID: 'zip_site_id' } }), - )) as string - - expect(cliResponse).toContain('Agent task created successfully!') - expect(cliResponse).toContain('Task ID: agent_runner_no_repo_id') - expect(cliResponse).toContain('Prompt: Add a contact form') - expect(cliResponse).toContain('Agent: Claude') - expect(cliResponse).toContain('Base: Latest production deployment') - expect(cliResponse).not.toContain('Branch:') + const { stdout } = await execa(cliPath, ['agents:create', 'Add a contact form', '--agent', 'claude'], { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'zip_site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }) + + expect(stdout).toContain('Agent task created successfully!') + expect(stdout).toContain('Task ID: agent_runner_no_repo_id') + expect(stdout).toContain('Prompt: Add a contact form') + expect(stdout).toContain('Agent: Claude') + expect(stdout).toContain('Base: Latest production deployment') + expect(stdout).not.toContain('Branch:') }) }) }) @@ -207,24 +210,23 @@ describe('agents:create command', () => { await builder.build() await withMockApi(routes, async ({ apiUrl }) => { - const cliResponse = (await callCli( + const { stdout } = await execa( + cliPath, ['agents:create', 'Create a dashboard', '--agent', 'claude', '--branch', 'feature-branch'], - getCLIOptions({ apiUrl, builder }), - )) as string - - expect(cliResponse).toContain('Agent task created successfully!') - expect(cliResponse).toContain('Branch: main') // Mock returns main branch - expect(cliResponse).not.toContain('Base: Latest production deployment') + { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }, + ) + + expect(stdout).toContain('Agent task created successfully!') + expect(stdout).toContain('Branch: feature-branch') + expect(stdout).not.toContain('Base: Latest production deployment') }) }) }) test('should prompt for branch when none provided for git site', async (t) => { - const inquirer = await import('inquirer') - - // Mock the branch input prompt - vi.mocked(inquirer.default.prompt).mockResolvedValue({ branchInput: 'develop' }) - const routes = [ ...baseRoutes, { @@ -242,20 +244,22 @@ describe('agents:create command', () => { await builder.build() await withMockApi(routes, async ({ apiUrl }) => { - const cliResponse = (await callCli( - ['agents:create', 'Create a form', '--agent', 'claude'], - getCLIOptions({ apiUrl, builder }), - )) as string - - expect(inquirer.default.prompt).toHaveBeenCalledWith([ - expect.objectContaining({ - name: 'branchInput', - message: 'Which branch would you like to work on?', - default: 'main', // Should use repo default - }), + const childProcess = execa(cliPath, ['agents:create', 'Create a form', '--agent', 'claude'], { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }) + + handleQuestions(childProcess, [ + { + question: 'Which branch would you like to work on?', + answer: answerWithValue('develop'), + }, ]) - expect(cliResponse).toContain('Branch: develop') + const result = await childProcess + + expect(result.stdout).toContain('Agent task created successfully!') + expect(result.stdout).toContain('Branch: develop') }) }) }) From 9a815d8c8dc3955ebf3bf7b97fa0137fbd9b1a1c Mon Sep 17 00:00:00 2001 From: Karin Hendrikse <30577427+khendrikse@users.noreply.github.com> Date: Fri, 17 Oct 2025 14:06:23 +0200 Subject: [PATCH 2/2] fix: add interactive mode test for agents create command --- .../commands/agents/agents-create.test.ts | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tests/integration/commands/agents/agents-create.test.ts b/tests/integration/commands/agents/agents-create.test.ts index 407fa3814ce..6ae89bc2368 100644 --- a/tests/integration/commands/agents/agents-create.test.ts +++ b/tests/integration/commands/agents/agents-create.test.ts @@ -83,7 +83,44 @@ describe('agents:create command', () => { }) }) - test.todo('should handle interactive mode when no prompt provided') + test('should handle interactive mode when no prompt provided', async (t) => { + const routes = [ + ...baseRoutes, + { + path: 'agent_runners', + method: 'POST' as const, + response: mockAgentRunner, + validateRequest: (request: { body: string }) => { + const body = JSON.parse(request.body) as { prompt: string; branch: string } + expect(body.prompt).toBe('Build a contact form') + expect(body.branch).toBe('main') + }, + }, + ] + + await withSiteBuilder(t, async (builder) => { + await builder.build() + + await withMockApi(routes, async ({ apiUrl }) => { + const childProcess = execa(cliPath, ['agents:create', '--agent', 'claude', '--branch', 'main'], { + cwd: builder.directory, + env: { NETLIFY_API_URL: apiUrl, NETLIFY_SITE_ID: 'site_id', NETLIFY_AUTH_TOKEN: 'fake-token' }, + }) + + handleQuestions(childProcess, [ + { + question: 'What would you like the agent to do?', + answer: answerWithValue('Build a contact form'), + }, + ]) + + const result = await childProcess + + expect(result.stdout).toContain('Agent task created successfully!') + expect(result.stdout).toContain('Prompt: Build a contact form') + }) + }) + }) test('should validate prompt input', async (t) => { await withSiteBuilder(t, async (builder) => {