fix(e2e): more falsely failed e2e tests
This commit is contained in:
@@ -97,7 +97,7 @@ export default {
|
|||||||
'<rootDir>/tests/e2e/**/parse-prd.test.js',
|
'<rootDir>/tests/e2e/**/parse-prd.test.js',
|
||||||
'<rootDir>/tests/e2e/**/generate.test.js',
|
'<rootDir>/tests/e2e/**/generate.test.js',
|
||||||
'<rootDir>/tests/e2e/**/analyze-complexity.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
|
// Heavy AI tests run sequentially to avoid rate limits
|
||||||
maxWorkers: 1,
|
maxWorkers: 1,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
## Commands Found in commands.js
|
## Commands Found in commands.js
|
||||||
|
|
||||||
1. **parse-prd** ✅ (has test: parse-prd.test.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)
|
3. **update-task** ✅ (has test: update-task.test.js)
|
||||||
4. **update-subtask** ✅ (has test: update-subtask.test.js)
|
4. **update-subtask** ✅ (has test: update-subtask.test.js)
|
||||||
5. **generate** ✅ (has test: generate.test.js)
|
5. **generate** ✅ (has test: generate.test.js)
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
18. **set-status** - 17/17 tests pass (100%)
|
18. **set-status** - 17/17 tests pass (100%)
|
||||||
19. **tags** - 14/14 tests pass (100%)
|
19. **tags** - 14/14 tests pass (100%)
|
||||||
20. **update-subtask** - Core functionality working (test file includes tests for unimplemented options)
|
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%)
|
22. **use-tag** - 6/6 tests pass (100%)
|
||||||
23. **validate-dependencies** - 8/8 tests pass (100%)
|
23. **validate-dependencies** - 8/8 tests pass (100%)
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ describe('task-master copy-tag', () => {
|
|||||||
expect(result.stdout).toContain('Successfully copied tag');
|
expect(result.stdout).toContain('Successfully copied tag');
|
||||||
expect(result.stdout).toContain('feature');
|
expect(result.stdout).toContain('feature');
|
||||||
expect(result.stdout).toContain('feature-backup');
|
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
|
// Verify the new tag exists
|
||||||
const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir });
|
const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir });
|
||||||
@@ -162,7 +162,7 @@ describe('task-master copy-tag', () => {
|
|||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Successfully copied tag');
|
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
|
// Verify both tags exist
|
||||||
const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir });
|
const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir });
|
||||||
@@ -179,7 +179,7 @@ describe('task-master copy-tag', () => {
|
|||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Successfully copied tag');
|
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
|
// Verify copy exists
|
||||||
const tagsResult = await helpers.taskMaster('tags', [], { cwd: testDir });
|
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 });
|
const listResult = await helpers.taskMaster('list', [], { cwd: testDir });
|
||||||
// Just verify the task is there (title may be truncated)
|
// Just verify the task is there (title may be truncated)
|
||||||
expect(listResult.stdout).toContain('Shared');
|
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('Successfully copied tag');
|
||||||
expect(result.stdout).toContain('dev');
|
expect(result.stdout).toContain('dev');
|
||||||
expect(result.stdout).toContain('dev-backup');
|
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 () => {
|
it('should handle verbose output if supported', async () => {
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ describe('task-master fix-dependencies command', () => {
|
|||||||
|
|
||||||
// Should handle gracefully
|
// Should handle gracefully
|
||||||
expect(result).toHaveExitCode(0);
|
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/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -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
|
* Tests all aspects of bulk task updates including AI-powered updates
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ describe('update command', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Create test directory
|
// Create test directory
|
||||||
testDir = mkdtempSync(join(tmpdir(), 'task-master-update-tasks-'));
|
testDir = mkdtempSync(join(tmpdir(), 'task-master-update-'));
|
||||||
|
|
||||||
// Initialize test helpers
|
// Initialize test helpers
|
||||||
const context = global.createTestContext('update');
|
const context = global.createTestContext('update');
|
||||||
@@ -118,36 +118,35 @@ describe('update command', () => {
|
|||||||
expect(allTasksValid).toBe(true);
|
expect(allTasksValid).toBe(true);
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
it('should update specific tasks by IDs', async () => {
|
it('should update tasks from ID 2 onwards', async () => {
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--ids', '1,3', '--prompt', 'Add performance optimization notes'],
|
['--from', '2', '--prompt', 'Add performance optimization notes'],
|
||||||
{ cwd: testDir, timeout: 45000 }
|
{ cwd: testDir, timeout: 45000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Updated 2 task');
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
|
expect(result.stdout).toContain('2 tasks');
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
it('should update tasks by status filter', async () => {
|
it('should update all tasks from ID 1', async () => {
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--status', 'pending', '--prompt', 'Add estimated time requirements'],
|
['--from', '1', '--prompt', 'Add estimated time requirements'],
|
||||||
{ cwd: testDir, timeout: 45000 }
|
{ cwd: testDir, timeout: 45000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
// Should update tasks 1 and 2 (pending status)
|
// Should update all 3 tasks
|
||||||
expect(result.stdout).toContain('Updated 2 task');
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
|
expect(result.stdout).toContain('3 tasks');
|
||||||
|
|
||||||
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
||||||
const tasks = JSON.parse(readFileSync(tasksPath, 'utf8'));
|
const tasks = JSON.parse(readFileSync(tasksPath, 'utf8'));
|
||||||
|
|
||||||
// Verify only pending tasks were updated
|
// Verify tasks were updated
|
||||||
const pendingTasks = tasks.master.tasks.filter(
|
const hasTimeEstimates = tasks.master.tasks.some(
|
||||||
(t) => t.status === 'pending'
|
|
||||||
);
|
|
||||||
const hasTimeEstimates = pendingTasks.some(
|
|
||||||
(t) =>
|
(t) =>
|
||||||
t.details &&
|
t.details &&
|
||||||
(t.details.includes('time') ||
|
(t.details.includes('time') ||
|
||||||
@@ -179,7 +178,7 @@ describe('update command', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Updated');
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
|
|
||||||
// Research mode should produce more detailed updates
|
// Research mode should produce more detailed updates
|
||||||
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
||||||
@@ -241,10 +240,10 @@ describe('update command', () => {
|
|||||||
|
|
||||||
it('should handle empty filter results gracefully', async () => {
|
it('should handle empty filter results gracefully', async () => {
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
[
|
[
|
||||||
'--status',
|
'--from',
|
||||||
'completed',
|
'999',
|
||||||
'--prompt',
|
'--prompt',
|
||||||
'This should not update anything'
|
'This should not update anything'
|
||||||
],
|
],
|
||||||
@@ -252,7 +251,8 @@ describe('update command', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
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);
|
}, 45000);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ describe('update command', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Updated');
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
|
|
||||||
// Verify task in tag was updated
|
// Verify task in tag was updated
|
||||||
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
const tasksPath = join(testDir, '.taskmaster/tasks/tasks.json');
|
||||||
@@ -294,13 +294,13 @@ describe('update command', () => {
|
|||||||
|
|
||||||
// Update all tasks across all tags
|
// Update all tasks across all tags
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--prompt', 'Add error handling strategies'],
|
['--prompt', 'Add error handling strategies'],
|
||||||
{ cwd: testDir, timeout: 45000 }
|
{ cwd: testDir, timeout: 45000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
expect(result.stdout).toContain('Updated');
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
}, 60000);
|
}, 60000);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -320,18 +320,13 @@ describe('update command', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
expect(result).toHaveExitCode(0);
|
||||||
|
expect(result.stdout).toContain('Successfully updated');
|
||||||
// Output should be valid JSON
|
|
||||||
const jsonOutput = JSON.parse(result.stdout);
|
|
||||||
expect(jsonOutput.success).toBe(true);
|
|
||||||
expect(jsonOutput.updated).toBeDefined();
|
|
||||||
expect(jsonOutput.tasks).toBeDefined();
|
|
||||||
}, 60000);
|
}, 60000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Error handling', () => {
|
describe('Error handling', () => {
|
||||||
it('should fail without prompt', async () => {
|
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,
|
cwd: testDir,
|
||||||
allowFailure: true
|
allowFailure: true
|
||||||
});
|
});
|
||||||
@@ -342,35 +337,37 @@ describe('update command', () => {
|
|||||||
|
|
||||||
it('should handle invalid task IDs gracefully', async () => {
|
it('should handle invalid task IDs gracefully', async () => {
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--ids', '999,1000', '--prompt', 'Update non-existent tasks'],
|
['--from', '999', '--prompt', 'Update non-existent tasks'],
|
||||||
{ cwd: testDir }
|
{ cwd: testDir }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
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(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--status', 'invalid-status', '--prompt', 'Test invalid status'],
|
['--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 }
|
{ cwd: testDir, allowFailure: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.exitCode).not.toBe(0);
|
expect(result.exitCode).not.toBe(0);
|
||||||
expect(result.stderr).toContain('Invalid status');
|
expect(result.stderr).toContain('The update command uses --from');
|
||||||
});
|
|
||||||
|
|
||||||
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');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -394,14 +391,15 @@ describe('update command', () => {
|
|||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--prompt', 'Add brief implementation notes'],
|
['--from', '1', '--prompt', 'Add brief implementation notes'],
|
||||||
{ cwd: testDir, timeout: 120000 }
|
{ cwd: testDir, timeout: 120000 }
|
||||||
);
|
);
|
||||||
const duration = Date.now() - startTime;
|
const duration = Date.now() - startTime;
|
||||||
|
|
||||||
expect(result).toHaveExitCode(0);
|
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
|
expect(duration).toBeLessThan(120000); // Should complete within 2 minutes
|
||||||
}, 150000);
|
}, 150000);
|
||||||
|
|
||||||
@@ -414,8 +412,8 @@ describe('update command', () => {
|
|||||||
writeFileSync(tasksPath, JSON.stringify(currentTasks, null, 2));
|
writeFileSync(tasksPath, JSON.stringify(currentTasks, null, 2));
|
||||||
|
|
||||||
const result = await helpers.taskMaster(
|
const result = await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--prompt', 'Clarify implementation order'],
|
['--from', '1', '--prompt', 'Clarify implementation order'],
|
||||||
{ cwd: testDir, timeout: 45000 }
|
{ cwd: testDir, timeout: 45000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -428,40 +426,14 @@ describe('update command', () => {
|
|||||||
}, 60000);
|
}, 60000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Dry run mode', () => {
|
// Note: The update command doesn't support 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);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Integration with other commands', () => {
|
describe('Integration with other commands', () => {
|
||||||
it('should work with expand command on bulk-updated tasks', async () => {
|
it('should work with expand command on bulk-updated tasks', async () => {
|
||||||
// First bulk update
|
// First bulk update
|
||||||
await helpers.taskMaster(
|
await helpers.taskMaster(
|
||||||
'update-tasks',
|
'update',
|
||||||
['--ids', '1', '--prompt', 'Add detailed specifications'],
|
['--from', '1', '--prompt', 'Add detailed specifications'],
|
||||||
{ cwd: testDir, timeout: 45000 }
|
{ cwd: testDir, timeout: 45000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
Reference in New Issue
Block a user