Skip to content

Commit 2c89828

Browse files
gololdf1shDavertMikclaude
authored
Fix retryFailedStep ignoredSteps exact-name matching (#5571)
* Fix retryFailedStep ignoredSteps exact-name matching The wildcard check used `ignored.indexOf('*')` as a boolean. `-1` is truthy in JavaScript (only `0` is falsy), so entries without `*` were matched via `startsWith(slice(0, -1))` instead of exact compare, which also chops the last character — broadening the match further. `ignoredSteps: ['see']` silently ignored `seeElement`, `seeInField`, `selectOption`, `sendPostRequest` — anything starting with `se`. Compare against `-1` explicitly so exact-name entries only match themselves, as the docs describe. * fix(retryFailedStep): avoid mutating shared defaultConfig Each call to retryFailedStep mutated the module-level defaultConfig via Object.assign(defaultConfig, config), so config.when from a prior call leaked into the next as customWhen and chained recursively. In tests this made when() return undefined for closures that no longer had a live step.started listener (e.g. after event.cleanDispatcher), causing the new regression test to fail in the full unit suite even though it passed in isolation. Use Object.assign({}, defaultConfig, config) so each registration gets an independent config object. Rewrites the regression test to assert via retryConfig.when() directly, which is now sound. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Michael Bodnarchuk <davert.ua@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent c07b826 commit 2c89828

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

lib/plugin/retryFailedStep.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export default function (config) {
116116
if (step.title === ignored) return
117117
if (ignored instanceof RegExp) {
118118
if (step.title.match(ignored)) return
119-
} else if (ignored.indexOf('*') && step.title.startsWith(ignored.slice(0, -1))) return
119+
} else if (ignored.indexOf('*') !== -1 && step.title.startsWith(ignored.slice(0, -1))) return
120120
}
121121
enableRetry = true
122122
})

test/unit/plugin/retryFailedStep_test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,23 @@ describe('retryFailedStep', () => {
186186
// expects to retry only once
187187
})
188188

189+
it('should not treat exact-name ignoredSteps entries as wildcard prefixes', () => {
190+
// Regression: ignored.indexOf('*') was used as truthy check.
191+
// -1 is truthy, so entries without '*' were matched via startsWith(slice(0, -1)).
192+
// ignoredSteps: ['see'] would silently ignore seeElement, seeInField, selectOption, etc.
193+
retryFailedStep({ retries: 2, minTimeout: 1, ignoredSteps: ['see'] })
194+
store.autoRetries = true
195+
const retryConfig = recorder.retries[recorder.retries.length - 1]
196+
197+
event.dispatcher.emit(event.step.started, { title: 'seeElement' })
198+
expect(retryConfig.when(new Error()), "'seeElement' must not be ignored when only 'see' is configured").to.equal(true)
199+
200+
event.dispatcher.emit(event.step.passed, {})
201+
202+
event.dispatcher.emit(event.step.started, { title: 'see' })
203+
expect(retryConfig.when(new Error()), "exact match 'see' must still be ignored").to.not.equal(true)
204+
})
205+
189206
it('should add custom regexp steps to ignore', async () => {
190207
retryFailedStep({ retries: 2, minTimeout: 1, ignoredSteps: [/somethingNew/] })
191208
event.dispatcher.emit(event.test.before, createTest('test'))

0 commit comments

Comments
 (0)