diff --git a/src/components/ui/FieldRenderer.test.tsx b/src/components/ui/FieldRenderer.test.tsx
index be5d6b2..6c8c232 100644
--- a/src/components/ui/FieldRenderer.test.tsx
+++ b/src/components/ui/FieldRenderer.test.tsx
@@ -1,6 +1,6 @@
// @vitest-environment jsdom
import { describe, it, expect, vi } from 'vitest';
-import { render, screen } from '@testing-library/react';
+import { render, screen, fireEvent } from '@testing-library/react';
import { FieldRenderer } from './FieldRenderer';
import type { UseFormRegister } from 'react-hook-form';
@@ -31,6 +31,60 @@ const selectFieldWithTooltip = {
],
};
+describe('FieldRenderer - tooltip hover behavior', () => {
+ it('hovering tooltip button shows tooltip text', () => {
+ render(
+
+ );
+ const tooltipBtn = screen.getByRole('button', { name: /more info about bucket name/i });
+ fireEvent.mouseEnter(tooltipBtn);
+ expect(screen.getByText('The name of your storage bucket')).toBeDefined();
+ });
+
+ it('mouse-leaving tooltip button hides tooltip text', () => {
+ render(
+
+ );
+ const tooltipBtn = screen.getByRole('button', { name: /more info about bucket name/i });
+ fireEvent.mouseEnter(tooltipBtn);
+ expect(screen.getByText('The name of your storage bucket')).toBeDefined();
+ fireEvent.mouseLeave(tooltipBtn);
+ expect(screen.queryByText('The name of your storage bucket')).toBeNull();
+ });
+
+ it('clicking tooltip button pins it open through mouseLeave', () => {
+ render(
+
+ );
+ const tooltipBtn = screen.getByRole('button', { name: /more info about bucket name/i });
+ fireEvent.click(tooltipBtn);
+ fireEvent.mouseLeave(tooltipBtn);
+ expect(screen.getByText('The name of your storage bucket')).toBeDefined();
+ });
+
+ it('clicking pinned tooltip button again dismisses it', () => {
+ render(
+
+ );
+ const tooltipBtn = screen.getByRole('button', { name: /more info about bucket name/i });
+ fireEvent.click(tooltipBtn);
+ fireEvent.click(tooltipBtn);
+ expect(screen.queryByText('The name of your storage bucket')).toBeNull();
+ });
+});
+
describe('FieldRenderer - DEBT-01 aria-label consistency', () => {
it('Test 1: text-branch tooltip button has aria-label="More info about {field.label}"', () => {
render(
diff --git a/src/components/ui/TextFieldMD3.test.tsx b/src/components/ui/TextFieldMD3.test.tsx
index f13c291..c0f8ab4 100644
--- a/src/components/ui/TextFieldMD3.test.tsx
+++ b/src/components/ui/TextFieldMD3.test.tsx
@@ -134,4 +134,42 @@ describe('TextFieldMD3', () => {
const input = screen.getByLabelText('Field');
expect(input.getAttribute('placeholder')).toBe(' ');
});
+
+ it('Test 9: renders helpTextPrefix inline with helpText', () => {
+ render(
+ icon}
+ />
+ );
+ expect(screen.getByTestId('prefix')).toBeDefined();
+ expect(screen.getByText('Some help')).toBeDefined();
+ });
+
+ it('Test 10: renders helpText without wrapper issues when helpTextPrefix is undefined', () => {
+ render(
+
+ );
+ expect(screen.getByText('Some help')).toBeDefined();
+ });
+
+ it('Test 11: renders helpTextPrefix alone when helpText is absent (tooltip-only field)', () => {
+ render(
+ icon}
+ />
+ );
+ expect(screen.getByTestId('prefix-only')).toBeDefined();
+ });
});