fix(e2e): more falsely failed e2e tests

This commit is contained in:
Ralph Khreish
2025-07-17 20:59:18 +03:00
parent 12b4aa7e59
commit 4361f6dd21
5 changed files with 65 additions and 92 deletions

View File

@@ -97,7 +97,7 @@ export default {
'<rootDir>/tests/e2e/**/parse-prd.test.js',
'<rootDir>/tests/e2e/**/generate.test.js',
'<rootDir>/tests/e2e/**/analyze-complexity.test.js',
'<rootDir>/tests/e2e/**/update-tasks.test.js'
'<rootDir>/tests/e2e/**/update.test.js'
],
// Heavy AI tests run sequentially to avoid rate limits
maxWorkers: 1,

View File

@@ -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%)

View File

@@ -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 () => {

View File

@@ -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/);
});
});

View File

@@ -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 }
);