1616 */
1717package io .github .bonigarcia .junit .selenium ;
1818
19- import java .util . concurrent . atomic . AtomicInteger ;
19+ import java .lang . reflect . Method ;
2020
2121import org .junit .jupiter .api .extension .ExtensionContext ;
2222import org .junit .jupiter .api .extension .TestExecutionExceptionHandler ;
@@ -25,43 +25,42 @@ public class RetryExtension implements TestExecutionExceptionHandler {
2525
2626 static final int DEFAULT_MAX_RETRIES = 3 ;
2727
28- final AtomicInteger retryCount = new AtomicInteger (1 );
29- final AtomicInteger maxRetries = new AtomicInteger (DEFAULT_MAX_RETRIES );
28+ private final int maxRetries ;
3029
3130 public RetryExtension () {
32- // Default constructor
31+ this . maxRetries = DEFAULT_MAX_RETRIES ;
3332 }
3433
3534 public RetryExtension (int maxRetries ) {
36- this .maxRetries . set ( maxRetries ) ;
35+ this .maxRetries = maxRetries ;
3736 }
3837
3938 @ Override
40- public void handleTestExecutionException (ExtensionContext extensionContext ,
41- Throwable throwable ) throws Throwable {
42- logError (throwable );
39+ public void handleTestExecutionException (ExtensionContext context ,
40+ Throwable firstFailure ) throws Throwable {
41+ logError (firstFailure , 1 ); // attempt #1 already failed
4342
44- extensionContext .getTestMethod ().ifPresent (method -> {
45- while (retryCount .incrementAndGet () <= maxRetries .get ()) {
46- try {
47- extensionContext .getExecutableInvoker ().invoke (method ,
48- extensionContext .getRequiredTestInstance ());
49- return ;
50- } catch (Throwable t ) {
51- logError (t );
52- if (retryCount .get () >= maxRetries .get ()) {
53- throw t ;
54- }
43+ Method method = context .getRequiredTestMethod ();
44+ Object instance = context .getRequiredTestInstance ();
45+ int attempt = 1 ;
46+ while (attempt < maxRetries ) {
47+ attempt ++;
48+ try {
49+ // Re-run test method (no @BeforeEach/@AfterEach)
50+ context .getExecutableInvoker ().invoke (method , instance );
51+ return ; // Success: swallow the original exception
52+ } catch (Throwable t ) {
53+ logError (t , attempt );
54+ if (attempt >= maxRetries ) {
55+ throw t ; // failure after last retry
5556 }
5657 }
57- });
58- throw throwable ;
58+ }
59+ throw firstFailure ; // throw original failure as a fallback
5960 }
6061
61- private void logError (Throwable e ) {
62- System .err .println ("Attempt test execution #" + retryCount .get ()
63- + " failed (" + e .getClass ().getName () + "thrown): "
64- + e .getMessage ());
62+ private void logError (Throwable e , int attempt ) {
63+ System .err .println ("Attempt #" + attempt + " failed ("
64+ + e .getClass ().getName () + " thrown): " + e .getMessage ());
6565 }
66-
6766}
0 commit comments