import '@testing-library/jest-dom'; import { act, fireEvent, render, screen, waitFor, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { PhoneInput } from '../src/phone-input'; import { ReactHookFormAndZod } from './phone-input.stories'; describe('ReactHookFormAndZod', () => { test('renders form inputs and submit button', () => { render(); expect(screen.getByPlaceholderText('Name')).toBeInTheDocument(); expect(screen.getByPlaceholderText('Phone')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Submit' })).toBeInTheDocument(); }); test('displays error message when name is empty and form is submitted', async () => { render(); fireEvent.click(screen.getByRole('button', { name: 'Submit' })); await waitFor(() => expect(screen.getByText('Name is required')).toBeInTheDocument() ); }); test('updates submit state and resets form on valid submission', async () => { render(); fireEvent.input(screen.getByPlaceholderText('Name'), { target: { value: 'John Doe' }, }); const phoneInput = screen.getByPlaceholderText('Phone'); fireEvent.input(phoneInput, { target: { value: '+34 800 000 312' }, }); expect(screen.getByAltText('ES')).toBeInTheDocument(); await act(() => fireEvent.submit(screen.getByRole('button', { name: 'Submit' })) ); // Проверка, что состояние submit обновилось expect(screen.getByText(/John Doe/)).toBeInTheDocument(); expect(screen.getByText(/\+34 800 000 312/)).toBeInTheDocument(); // Проверка сброса формы expect(screen.getByPlaceholderText('Name').textContent).toBe(''); expect(phoneInput.value).toBe('+1'); expect(screen.getByAltText('US')).toBeInTheDocument(); const countrySelectorButton = screen.getByRole('button'); await act(() => fireEvent.click(countrySelectorButton)); // Предположим, что по клику открывается dropdown с li // Эмулируем выбор страны (например, выбор UK) const liOption = screen.getByText( 'United Kingdom of Great Britain and Northern Ireland' ); await act(() => fireEvent.click(liOption)); // Проверяем, что код страны обновился (пример для UK) expect(screen.getByDisplayValue('+44')).toBeInTheDocument(); // Проверяем, что флаг страны обновился expect(screen.getByAltText('GB')).toBeInTheDocument(); fireEvent.input(phoneInput, { target: { value: '+348' }, }); expect(phoneInput.value).toBe('+34 8'); }); test('updates country code and phone mask on country change', async () => { render(); const countrySelectorButton = screen.getByRole('button'); await act(() => fireEvent.click(countrySelectorButton)); // Предположим, что по клику открывается dropdown с li // Эмулируем выбор страны (например, выбор UK) const liOption = screen.getByText( 'United Kingdom of Great Britain and Northern Ireland' ); await act(() => fireEvent.click(liOption)); // Проверяем, что код страны обновился (пример для UK) expect(screen.getByDisplayValue('+44')).toBeInTheDocument(); // Проверяем, что флаг страны обновился expect(screen.getByAltText('GB')).toBeInTheDocument(); }); const setup = () => render( ); it('maintains cursor position when adding a digit', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; await act(async () => { await userEvent.type(input, '+7912'); }); expect(input).toHaveValue('+7 912'); expect(input.selectionStart).toBe(6); expect(input.selectionEnd).toBe(6); }); it('maintains cursor position when removing a digit', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; await act(async () => { await userEvent.type(input, '+79123'); }); expect(input).toHaveValue('+7 912 3'); await act(async () => { await userEvent.type(input, '{backspace}'); }); expect(input).toHaveValue('+7 912'); expect(input.selectionStart).toBe(6); expect(input.selectionEnd).toBe(6); }); it('handles cursor position when removing a space', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; await act(async () => { await userEvent.type(input, '+7912 5'); }); expect(input).toHaveValue('+7 912 5'); await act(async () => { await userEvent.type(input, '{backspace}'); }); expect(input).toHaveValue('+7 912'); expect(input.selectionStart).toBe(6); expect(input.selectionEnd).toBe(6); }); it('handles cursor position when pasting a number', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; input.focus(); await act(async () => { await userEvent.paste('+79123456789'); }); expect(input).toHaveValue('+7 912 345 67 89'); expect(input.selectionStart).toBe(16); expect(input.selectionEnd).toBe(16); }); it('maintains cursor position when typing in the middle', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; await act(async () => { await userEvent.type(input, '+7912345'); }); expect(input).toHaveValue('+7 912 345'); await act(async () => { await userEvent.type(input, '6', { delay: 100, initialSelectionEnd: 5, initialSelectionStart: 4, }); }); expect(input).toHaveValue('+7 962 345'); expect(input.selectionStart).toBe(5); expect(input.selectionEnd).toBe(5); }); it('maintains cursor position when typing in the middle when there is a multiple backspace', async () => { setup(); const input = screen.getByRole('textbox') as HTMLInputElement; await act(async () => { await userEvent.type(input, '+7912345'); }); await act(async () => { await userEvent.type(input, '{backspace}{backspace}', { delay: 100, initialSelectionEnd: 5, initialSelectionStart: 5, }); }); expect(input).toHaveValue('+7 2345'); expect(input.selectionStart).toBe(3); expect(input.selectionEnd).toBe(3); await act(async () => { await userEvent.type(input, '6', { delay: 100, initialSelectionEnd: 3, initialSelectionStart: 3, }); }); expect(input).toHaveValue('+7 62345'); expect(input.selectionStart).toBe(4); expect(input.selectionEnd).toBe(4); }); });