diff --git a/lib/plugin/retryFailedStep.js b/lib/plugin/retryFailedStep.js index 6d43bf8da..1bf29641c 100644 --- a/lib/plugin/retryFailedStep.js +++ b/lib/plugin/retryFailedStep.js @@ -108,6 +108,7 @@ module.exports = config => { event.dispatcher.on(event.test.before, test => { // pass disableRetryFailedStep is a preferred way to disable retries // test.disableRetryFailedStep is used for backward compatibility + if (!test.opts) test.opts = {} if (test.opts.disableRetryFailedStep || test.disableRetryFailedStep) { store.autoRetries = false return // disable retry when a test is not active diff --git a/test/unit/plugin/retryFailedStep_interactive_shell_test.js b/test/unit/plugin/retryFailedStep_interactive_shell_test.js new file mode 100644 index 000000000..a0b284412 --- /dev/null +++ b/test/unit/plugin/retryFailedStep_interactive_shell_test.js @@ -0,0 +1,25 @@ +const assert = require('assert') +const event = require('../../../lib/event') +const retryFailedStep = require('../../../lib/plugin/retryFailedStep') + +describe('retryFailedStep plugin (interactive shell regression)', () => { + beforeEach(() => { + // Remove all listeners to avoid side effects + event.cleanDispatcher() + // Re-register plugin + retryFailedStep({ enabled: true }) + }) + + it('should not throw when test.before is emitted without opts (interactive shell)', () => { + // Simulate the event as emitted by the interactive shell (no opts) + assert.doesNotThrow(() => { + event.dispatcher.emit(event.test.before, { title: 'Interactive', artifacts: {} }) + }) + }) + + it('should not throw when test.before is emitted with opts', () => { + assert.doesNotThrow(() => { + event.dispatcher.emit(event.test.before, { title: 'Normal', artifacts: {}, opts: {} }) + }) + }) +})