import '@testing-library/jest-dom' import { fireEvent, render, screen } from '@testing-library/react' import { vi } from 'vitest' import { IPktDatepicker, PktDatepicker } from './Datepicker' const datePickerId = 'datepickerId' const label = 'Date Picker Label' const createDatepickerTest = (props: Partial = {}) => { const defaultProps: IPktDatepicker = { label, id: datePickerId, ...props, } return render() } describe('PktDatepicker', () => { describe('Input field behavior', () => { test('allows manual date entry via change event', () => { const handleValueChange = vi.fn() const { container } = createDatepickerTest({ onValueChange: handleValueChange, }) const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.change(input, { target: { value: '2024-06-15' } }) expect(handleValueChange).toHaveBeenCalledWith(['2024-06-15']) }) test('shows placeholder text correctly', () => { const { container } = createDatepickerTest({ placeholder: 'yyyy-mm-dd', }) const input = container.querySelector('input[type="date"]') as HTMLInputElement expect(input).toHaveAttribute('placeholder', 'yyyy-mm-dd') }) test('shows help text correctly', () => { createDatepickerTest({ helptext: 'Enter a valid date', }) expect(screen.getByText('Enter a valid date')).toBeInTheDocument() }) test('handles readonly state correctly', () => { const { container } = createDatepickerTest({ readOnly: true, }) const input = container.querySelector('input[type="date"]') as HTMLInputElement expect(input).toHaveAttribute('readonly') // Calendar button should still be interactive const button = container.querySelector('button[type="button"]') expect(button).not.toBeDisabled() }) test('clears value when empty string entered', () => { const handleValueChange = vi.fn() const { container } = createDatepickerTest({ value: '2024-06-15', onValueChange: handleValueChange, }) const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.change(input, { target: { value: '' } }) expect(handleValueChange).toHaveBeenCalledWith([]) }) test('input has correct id based on component id', () => { const { container } = createDatepickerTest() const input = container.querySelector('input[type="date"]') as HTMLInputElement expect(input).toHaveAttribute('id', `${datePickerId}-input`) }) test('range inputs have distinct ids', () => { const { container } = createDatepickerTest({ range: true, }) const fromInput = container.querySelector(`#${datePickerId}-input`) const toInput = container.querySelector(`#${datePickerId}-to`) expect(fromInput).toBeInTheDocument() expect(toInput).toBeInTheDocument() }) test('range inputs have distinct names', () => { const { container } = createDatepickerTest({ range: true, name: 'dates', }) const inputs = container.querySelectorAll('input[type="date"]') as NodeListOf expect(inputs[0]).toHaveAttribute('name', 'dates-from') expect(inputs[1]).toHaveAttribute('name', 'dates-to') }) }) describe('Keyboard navigation and interaction', () => { test('opens calendar with Space key on single input', () => { const { container } = createDatepickerTest() const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.keyDown(input, { key: ' ' }) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') }) test('opens calendar with Space key on range input', () => { const { container } = createDatepickerTest({ range: true, }) const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.keyDown(input, { key: ' ' }) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') }) test('opens calendar with Space key on multiple input', () => { const { container } = createDatepickerTest({ multiple: true, }) const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.keyDown(input, { key: ' ' }) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') }) test('closes calendar with Escape key', () => { const { container } = createDatepickerTest() // Open calendar first const button = container.querySelector('button[type="button"]') as HTMLButtonElement fireEvent.click(button) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') // Close with Escape fireEvent.keyDown(document, { key: 'Escape' }) expect(popup).toHaveAttribute('hidden') }) test('opens calendar when clicking input', () => { const { container } = createDatepickerTest() const input = container.querySelector('input[type="date"]') as HTMLInputElement fireEvent.click(input) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') }) test('does not open calendar when disabled', () => { const { container } = createDatepickerTest({ disabled: true, }) const button = container.querySelector('button[type="button"]') as HTMLButtonElement fireEvent.click(button) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).toHaveAttribute('hidden') }) test('opens calendar when clicking button', () => { const { container } = createDatepickerTest() const button = container.querySelector('button[type="button"]') as HTMLButtonElement fireEvent.click(button) const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') expect(popup).toHaveClass('show') }) test('closes calendar when clicking button again', () => { const { container } = createDatepickerTest() const button = container.querySelector('button[type="button"]') as HTMLButtonElement fireEvent.click(button) // open fireEvent.click(button) // close const popup = container.querySelector('.pkt-calendar-popup') expect(popup).toHaveAttribute('hidden') expect(popup).toHaveClass('hide') }) test('closes calendar when clicking outside', () => { const { container } = createDatepickerTest() const button = container.querySelector('button[type="button"]') as HTMLButtonElement fireEvent.click(button) // open const popup = container.querySelector('.pkt-calendar-popup') expect(popup).not.toHaveAttribute('hidden') // Click outside the datepicker fireEvent.click(document.body, { bubbles: true }) expect(popup).toHaveAttribute('hidden') }) }) })