+ {/* Label row */}
+
+
+ {retrySaveSuccess && (
+
+ ✓ saved
+
+ )}
+ {hasError && (
+
+ {retryIntervalError}
+
+ )}
+
+
+ {/* Suggestion chips */}
+
+ {SUGGESTIONS.map(({ label, value }) => {
+ const isActive = retryInterval === value;
+ return (
+
+ );
+ })}
+
+
+ {/* Number input + range slider + save button */}
+
+
+ {/* Numeric input */}
+
+
+
+ {retryInterval >= MIN && retryInterval <= MAX
+ ? formatSeconds(retryInterval)
+ : 'seconds'}
+
+
+
+ {/* Range slider */}
+
setRetryInterval(parseInt(e.target.value, 10))}
+ disabled={isDisabled}
+ aria-label="Retry interval slider"
+ className="w-full accent-blue-500 disabled:opacity-40 disabled:cursor-not-allowed"
+ />
+
+ {MIN}s
+ 1h
+
+
+
+ {/* Save button */}
+
+
+
+ {/* Accessible error description */}
+ {hasError && (
+
+ {retryIntervalError}
+
+ )}
+
+ );
+}
diff --git a/admin/app/webhook-tester/components/__tests__/RetryIntervalInput.test.tsx b/admin/app/webhook-tester/components/__tests__/RetryIntervalInput.test.tsx
new file mode 100644
index 00000000..45fda8af
--- /dev/null
+++ b/admin/app/webhook-tester/components/__tests__/RetryIntervalInput.test.tsx
@@ -0,0 +1,239 @@
+/**
+ * Tests for RetryIntervalInput component
+ *
+ * Covers:
+ * - Renders with current retryInterval value
+ * - Suggestion chips update the value
+ * - Range validation (below min, above max, valid)
+ * - Save button calls saveRetryInterval
+ * - Disabled state when no webhook selected
+ * - Success feedback after save
+ * - Error message display
+ */
+
+import React from 'react';
+import { describe, it, expect, vi, beforeEach } from 'vitest';
+import { render, screen, fireEvent, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { RetryIntervalInput } from '../RetryIntervalInput';
+import * as contextModule from '../../context';
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+function makeContextValue(overrides: Partial