Skip to content

Commit 123f7fa

Browse files
committed
fix(cli): track assertion failures correctly with continueOnError=true
1 parent d44e3c0 commit 123f7fa

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

packages/cli/src/batch-runner.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,12 @@ class BatchRunner {
355355

356356
for (const context of executedContexts) {
357357
const { file, player, duration } = context;
358-
const success = player.status !== 'error';
358+
// A file is successful only if:
359+
// 1. Player status is not 'error', AND
360+
// 2. No individual tasks have failed status
361+
const hasFailedTasks =
362+
player.taskStatusList?.some((task) => task.status === 'error') ?? false;
363+
const success = player.status !== 'error' && !hasFailedTasks;
359364
let reportFile: string | undefined;
360365

361366
if (player.reportFile) {
@@ -377,7 +382,8 @@ class BatchRunner {
377382
duration,
378383
error:
379384
player.errorInSetup?.message ||
380-
(player.status === 'error' ? 'Execution failed' : undefined),
385+
(player.status === 'error' ? 'Execution failed' : undefined) ||
386+
(hasFailedTasks ? 'Some tasks failed' : undefined),
381387
});
382388
}
383389

packages/cli/tests/unit-test/batch-runner.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,63 @@ describe('BatchRunner', () => {
369369
);
370370
consoleSpy.mockRestore();
371371
});
372+
373+
test('continueOnError: failed tasks should be counted as failed files', async () => {
374+
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
375+
376+
// Create a mock player that simulates continueOnError behavior:
377+
// - player.status = 'done' (execution completed)
378+
// - but taskStatusList contains failed tasks
379+
const createMockPlayerWithFailedTasks = (
380+
fileName: string,
381+
): ScriptPlayer<MidsceneYamlScriptEnv> => {
382+
const isFile1 = fileName === 'file1.yml';
383+
const mockPlayer = {
384+
status: 'done' as ScriptPlayerStatusValue, // Always 'done' with continueOnError
385+
output: '/test/output/file.json',
386+
reportFile: '/test/report.html',
387+
result: { test: 'data' },
388+
errorInSetup: null,
389+
taskStatusList: isFile1
390+
? [
391+
{ status: 'error', error: new Error('Assertion failed: this is not a search engine') },
392+
{ status: 'done' }
393+
]
394+
: [{ status: 'done' }],
395+
run: vi.fn().mockImplementation(async () => {
396+
return undefined;
397+
}),
398+
script: mockYamlScript,
399+
setupAgent: vi.fn(),
400+
unnamedResultIndex: 0,
401+
pageAgent: null,
402+
currentTaskIndex: undefined,
403+
agentStatusTip: '',
404+
};
405+
return mockPlayer as unknown as ScriptPlayer<MidsceneYamlScriptEnv>;
406+
};
407+
408+
vi.mocked(createYamlPlayer).mockImplementation(async (file) =>
409+
createMockPlayerWithFailedTasks(file),
410+
);
411+
412+
const config = { ...mockBatchConfig, continueOnError: true };
413+
const executor = new BatchRunner(config);
414+
await executor.run();
415+
416+
const summary = executor.getExecutionSummary();
417+
const success = executor.printExecutionSummary();
418+
419+
// This currently fails - demonstrates the bug
420+
// Should show 1 failed file, but currently shows 0
421+
expect(summary.failed).toBe(1); // This test will fail, showing the bug
422+
expect(success).toBe(false);
423+
expect(consoleSpy).toHaveBeenCalledWith(
424+
expect.stringContaining('❌ Failed files'),
425+
);
426+
427+
consoleSpy.mockRestore();
428+
});
372429
});
373430

374431
describe('BatchRunner output file existence check', () => {

0 commit comments

Comments
 (0)