@@ -77,7 +77,7 @@ const defaultConfig = {
7777 * ```
7878 *
7979 */
80- export default function ( config ) {
80+ export default function ( config ) {
8181 config = Object . assign ( defaultConfig , config )
8282 config . ignoredSteps = config . ignoredSteps . concat ( config . defaultIgnoredSteps )
8383 const customWhen = config . when
@@ -93,6 +93,11 @@ export default function(config) {
9393 }
9494 config . when = when
9595
96+ // Ensure retry options are available before any steps run
97+ if ( ! recorder . retries . find ( r => r === config ) ) {
98+ recorder . retries . push ( config )
99+ }
100+
96101 event . dispatcher . on ( event . step . started , step => {
97102 // if a step is ignored - return
98103 for ( const ignored of config . ignoredSteps ) {
@@ -104,7 +109,8 @@ export default function(config) {
104109 enableRetry = true // enable retry for a step
105110 } )
106111
107- event . dispatcher . on ( event . step . finished , ( ) => {
112+ // Disable retry only after a successful step; keep it enabled for failure so retry logic can act
113+ event . dispatcher . on ( event . step . passed , ( ) => {
108114 enableRetry = false
109115 } )
110116
@@ -115,9 +121,38 @@ export default function(config) {
115121 store . autoRetries = false
116122 return // disable retry when a test is not active
117123 }
124+
125+ // Don't apply plugin retry logic if there are already manual retries configured
126+ // Check if any retry configs exist that aren't from this plugin
127+ const hasManualRetries = recorder . retries . some ( retry => retry !== config )
128+ if ( hasManualRetries ) {
129+ store . autoRetries = false
130+ return
131+ }
132+
118133 // this option is used to set the retries inside _before() block of helpers
119134 store . autoRetries = true
120135 test . opts . conditionalRetries = config . retries
136+ // debug: record applied retries value for tests
137+ if ( process . env . DEBUG_RETRY_PLUGIN ) {
138+ // eslint-disable-next-line no-console
139+ console . log ( '[retryFailedStep] applying retries =' , config . retries , 'for test' , test . title )
140+ }
121141 recorder . retry ( config )
122142 } )
143+
144+ // Fallback for environments where event.test.before wasn't emitted (runner scenarios)
145+ event . dispatcher . on ( event . test . started , test => {
146+ if ( test . opts ?. disableRetryFailedStep || test . disableRetryFailedStep ) return
147+
148+ // Don't apply plugin retry logic if there are already manual retries configured
149+ // Check if any retry configs exist that aren't from this plugin
150+ const hasManualRetries = recorder . retries . some ( retry => retry !== config )
151+ if ( hasManualRetries ) return
152+
153+ if ( ! store . autoRetries ) {
154+ store . autoRetries = true
155+ test . opts . conditionalRetries = test . opts . conditionalRetries || config . retries
156+ }
157+ } )
123158}
0 commit comments