From 4361f6dd21886d127e7d668494b7edd0e9bbb466 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Thu, 17 Jul 2025 20:59:18 +0300 Subject: [PATCH] fix(e2e): more falsely failed e2e tests --- jest.e2e.projects.config.js | 2 +- tests/e2e/tests/commands/command-coverage.md | 4 +- tests/e2e/tests/commands/copy-tag.test.js | 10 +- .../tests/commands/fix-dependencies.test.js | 3 +- .../{update-tasks.test.js => update.test.js} | 138 +++++++----------- 5 files changed, 65 insertions(+), 92 deletions(-) rename tests/e2e/tests/commands/{update-tasks.test.js => update.test.js} (78%) diff --git a/jest.e2e.projects.config.js b/jest.e2e.projects.config.js index 27f72f28..72f54d2c 100644 --- a/jest.e2e.projects.config.js +++ b/jest.e2e.projects.config.js @@ -97,7 +97,7 @@ export default { '/tests/e2e/**/parse-prd.test.js', '/tests/e2e/**/generate.test.js', '/tests/e2e/**/analyze-complexity.test.js', - '/tests/e2e/**/update-tasks.test.js' + '/tests/e2e/**/update.test.js' ], // Heavy AI tests run sequentially to avoid rate limits maxWorkers: 1, diff --git a/tests/e2e/tests/commands/command-coverage.md b/tests/e2e/tests/commands/command-coverage.md index c78fd09d..4608d227 100644 --- a/tests/e2e/tests/commands/command-coverage.md +++ b/tests/e2e/tests/commands/command-coverage.md @@ -3,7 +3,7 @@ ## Commands Found in commands.js 1. **parse-prd** ✅ (has test: parse-prd.test.js) -2. **update** ✅ (has test: update-tasks.test.js) +2. **update** ✅ (has test: update.test.js) 3. **update-task** ✅ (has test: update-task.test.js) 4. **update-subtask** ✅ (has test: update-subtask.test.js) 5. **generate** ✅ (has test: generate.test.js) @@ -84,7 +84,7 @@ 18. **set-status** - 17/17 tests pass (100%) 19. **tags** - 14/14 tests pass (100%) 20. **update-subtask** - Core functionality working (test file includes tests for unimplemented options) -21. **update** (update-tasks) - Core functionality working (test file expects features that don't exist) +21. **update** - Fixed: test file renamed from update-tasks.test.js to update.test.js, uses correct --from parameter instead of non-existent --ids/--status/--priority 22. **use-tag** - 6/6 tests pass (100%) 23. **validate-dependencies** - 8/8 tests pass (100%) diff --git a/tests/e2e/tests/commands/copy-tag.test.js b/tests/e2e/tests/commands/copy-tag.test.js index 76589d51..dfd55c1e 100644 --- a/tests/e2e/tests/commands/copy-tag.test.js +++ b/tests/e2e/tests/commands/copy-tag.test.js @@ -73,7 +73,7 @@ describe('task-master copy-tag', () => { expect(result.stdout).toContain('Successfully copied tag'); expect(result.stdout).toContain('feature'); expect(result.stdout).toContain('feature-backup'); - expect(result.stdout).toContain('Tasks Copied: 2'); + expect(result.stdout).toMatch(/Tasks Copied:\s+2/); // Verify the new tag exists const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir }); @@ -162,7 +162,7 @@ describe('task-master copy-tag', () => { expect(result).toHaveExitCode(0); expect(result.stdout).toContain('Successfully copied tag'); - expect(result.stdout).toContain('Tasks Copied: 2'); + expect(result.stdout).toMatch(/Tasks Copied:\s+2/); // Verify both tags exist const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir }); @@ -179,7 +179,7 @@ describe('task-master copy-tag', () => { expect(result).toHaveExitCode(0); expect(result.stdout).toContain('Successfully copied tag'); - expect(result.stdout).toContain('Tasks Copied: 0'); + expect(result.stdout).toMatch(/Tasks Copied:\s+0/); // Verify copy exists const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir }); @@ -292,7 +292,7 @@ describe('task-master copy-tag', () => { const listResult = await helpers.taskMaster('list', [], { cwd: testDir }); // Just verify the task is there (title may be truncated) expect(listResult.stdout).toContain('Shared'); - expect(listResult.stdout).toContain('Pending: 1'); + expect(listResult.stdout).toMatch(/Pending:\s+1/); }); }); @@ -311,7 +311,7 @@ describe('task-master copy-tag', () => { expect(result.stdout).toContain('Successfully copied tag'); expect(result.stdout).toContain('dev'); expect(result.stdout).toContain('dev-backup'); - expect(result.stdout).toContain('Tasks Copied: 2'); + expect(result.stdout).toMatch(/Tasks Copied:\s+2/); }); it('should handle verbose output if supported', async () => { diff --git a/tests/e2e/tests/commands/fix-dependencies.test.js b/tests/e2e/tests/commands/fix-dependencies.test.js index 655db62f..b44f6716 100644 --- a/tests/e2e/tests/commands/fix-dependencies.test.js +++ b/tests/e2e/tests/commands/fix-dependencies.test.js @@ -419,6 +419,7 @@ describe('task-master fix-dependencies command', () => { // Should handle gracefully expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Tasks checked: 0'); + // The output includes this in a formatted box + expect(result.stdout).toMatch(/Tasks checked:\s+0/); }); }); \ No newline at end of file diff --git a/tests/e2e/tests/commands/update-tasks.test.js b/tests/e2e/tests/commands/update.test.js similarity index 78% rename from tests/e2e/tests/commands/update-tasks.test.js rename to tests/e2e/tests/commands/update.test.js index 7529752e..3b232d89 100644 --- a/tests/e2e/tests/commands/update-tasks.test.js +++ b/tests/e2e/tests/commands/update.test.js @@ -1,5 +1,5 @@ /** - * Comprehensive E2E tests for update-tasks command (bulk update) + * Comprehensive E2E tests for update command (bulk update) * Tests all aspects of bulk task updates including AI-powered updates */ @@ -21,7 +21,7 @@ describe('update command', () => { beforeEach(async () => { // Create test directory - testDir = mkdtempSync(join(tmpdir(), 'task-master-update-tasks-')); + testDir = mkdtempSync(join(tmpdir(), 'task-master-update-')); // Initialize test helpers const context = global.createTestContext('update'); @@ -118,36 +118,35 @@ describe('update command', () => { expect(allTasksValid).toBe(true); }, 60000); - it('should update specific tasks by IDs', async () => { + it('should update tasks from ID 2 onwards', async () => { const result = await helpers.taskMaster( - 'update-tasks', - ['--ids', '1,3', '--prompt', 'Add performance optimization notes'], + 'update', + ['--from', '2', '--prompt', 'Add performance optimization notes'], { cwd: testDir, timeout: 45000 } ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Updated 2 task'); + expect(result.stdout).toContain('Successfully updated'); + expect(result.stdout).toContain('2 tasks'); }, 60000); - it('should update tasks by status filter', async () => { + it('should update all tasks from ID 1', async () => { const result = await helpers.taskMaster( - 'update-tasks', - ['--status', 'pending', '--prompt', 'Add estimated time requirements'], + 'update', + ['--from', '1', '--prompt', 'Add estimated time requirements'], { cwd: testDir, timeout: 45000 } ); expect(result).toHaveExitCode(0); - // Should update tasks 1 and 2 (pending status) - expect(result.stdout).toContain('Updated 2 task'); + // Should update all 3 tasks + expect(result.stdout).toContain('Successfully updated'); + expect(result.stdout).toContain('3 tasks'); const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json'); const tasks = JSON.parse(readFileSync(tasksPath, 'utf8')); - // Verify only pending tasks were updated - const pendingTasks = tasks.master.tasks.filter( - (t) => t.status === 'pending' - ); - const hasTimeEstimates = pendingTasks.some( + // Verify tasks were updated + const hasTimeEstimates = tasks.master.tasks.some( (t) => t.details && (t.details.includes('time') || @@ -179,7 +178,7 @@ describe('update command', () => { ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Updated'); + expect(result.stdout).toContain('Successfully updated'); // Research mode should produce more detailed updates const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json'); @@ -241,10 +240,10 @@ describe('update command', () => { it('should handle empty filter results gracefully', async () => { const result = await helpers.taskMaster( - 'update-tasks', + 'update', [ - '--status', - 'completed', + '--from', + '999', '--prompt', 'This should not update anything' ], @@ -252,7 +251,8 @@ describe('update command', () => { ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('No tasks found matching the criteria'); + expect(result.stdout).toContain('Successfully updated'); + expect(result.stdout).toContain('0 tasks'); }, 45000); }); @@ -275,7 +275,7 @@ describe('update command', () => { ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Updated'); + expect(result.stdout).toContain('Successfully updated'); // Verify task in tag was updated const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json'); @@ -294,13 +294,13 @@ describe('update command', () => { // Update all tasks across all tags const result = await helpers.taskMaster( - 'update-tasks', + 'update', ['--prompt', 'Add error handling strategies'], { cwd: testDir, timeout: 45000 } ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Updated'); + expect(result.stdout).toContain('Successfully updated'); }, 60000); }); @@ -320,18 +320,13 @@ describe('update command', () => { ); expect(result).toHaveExitCode(0); - - // Output should be valid JSON - const jsonOutput = JSON.parse(result.stdout); - expect(jsonOutput.success).toBe(true); - expect(jsonOutput.updated).toBeDefined(); - expect(jsonOutput.tasks).toBeDefined(); + expect(result.stdout).toContain('Successfully updated'); }, 60000); }); describe('Error handling', () => { it('should fail without prompt', async () => { - const result = await helpers.taskMaster('update-tasks', ['--ids', '1'], { + const result = await helpers.taskMaster('update', ['--from', '1'], { cwd: testDir, allowFailure: true }); @@ -342,35 +337,37 @@ describe('update command', () => { it('should handle invalid task IDs gracefully', async () => { const result = await helpers.taskMaster( - 'update-tasks', - ['--ids', '999,1000', '--prompt', 'Update non-existent tasks'], + 'update', + ['--from', '999', '--prompt', 'Update non-existent tasks'], { cwd: testDir } ); expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('No tasks found'); + expect(result.stdout).toContain('Successfully updated'); + expect(result.stdout).toContain('0 tasks'); }); - it('should handle invalid status filter', async () => { + it('should handle missing required --from parameter', async () => { const result = await helpers.taskMaster( - 'update-tasks', - ['--status', 'invalid-status', '--prompt', 'Test invalid status'], + 'update', + ['--prompt', 'Test missing from parameter'], + { cwd: testDir } + ); + + // The --from parameter defaults to '1' so this should succeed + expect(result).toHaveExitCode(0); + expect(result.stdout).toContain('Successfully updated'); + }); + + it('should handle using --id instead of --from', async () => { + const result = await helpers.taskMaster( + 'update', + ['--id', '1', '--prompt', 'Test wrong parameter'], { cwd: testDir, allowFailure: true } ); expect(result.exitCode).not.toBe(0); - expect(result.stderr).toContain('Invalid status'); - }); - - it('should handle invalid priority filter', async () => { - const result = await helpers.taskMaster( - 'update-tasks', - ['--priority', 'urgent', '--prompt', 'Test invalid priority'], - { cwd: testDir, allowFailure: true } - ); - - expect(result.exitCode).not.toBe(0); - expect(result.stderr).toContain('Invalid priority'); + expect(result.stderr).toContain('The update command uses --from'); }); }); @@ -394,14 +391,15 @@ describe('update command', () => { const startTime = Date.now(); const result = await helpers.taskMaster( - 'update-tasks', - ['--prompt', 'Add brief implementation notes'], + 'update', + ['--from', '1', '--prompt', 'Add brief implementation notes'], { cwd: testDir, timeout: 120000 } ); const duration = Date.now() - startTime; expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('Updated 20 task'); + expect(result.stdout).toContain('Successfully updated'); + expect(result.stdout).toContain('20 tasks'); expect(duration).toBeLessThan(120000); // Should complete within 2 minutes }, 150000); @@ -414,8 +412,8 @@ describe('update command', () => { writeFileSync(tasksPath, JSON.stringify(currentTasks, null, 2)); const result = await helpers.taskMaster( - 'update-tasks', - ['--prompt', 'Clarify implementation order'], + 'update', + ['--from', '1', '--prompt', 'Clarify implementation order'], { cwd: testDir, timeout: 45000 } ); @@ -428,40 +426,14 @@ describe('update command', () => { }, 60000); }); - describe('Dry run mode', () => { - it('should preview updates without applying them', async () => { - const result = await helpers.taskMaster( - 'update-tasks', - [ - '--ids', - '1,2', - '--prompt', - 'Add test coverage requirements', - '--dry-run' - ], - { cwd: testDir, timeout: 45000 } - ); - - expect(result).toHaveExitCode(0); - expect(result.stdout).toContain('DRY RUN'); - expect(result.stdout).toContain('Would update'); - - // Verify tasks were NOT actually updated - const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json'); - const tasks = JSON.parse(readFileSync(tasksPath, 'utf8')); - const hasTestCoverage = tasks.master.tasks.some( - (t) => t.details && t.details.toLowerCase().includes('test coverage') - ); - expect(hasTestCoverage).toBe(false); - }, 60000); - }); + // Note: The update command doesn't support dry-run mode describe('Integration with other commands', () => { it('should work with expand command on bulk-updated tasks', async () => { // First bulk update await helpers.taskMaster( - 'update-tasks', - ['--ids', '1', '--prompt', 'Add detailed specifications'], + 'update', + ['--from', '1', '--prompt', 'Add detailed specifications'], { cwd: testDir, timeout: 45000 } );