UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

194 lines (145 loc) 6.2 kB
import '@testing-library/jest-dom' import { axe, toHaveNoViolations } from 'jest-axe' import { fireEvent } from '@testing-library/dom' expect.extend(toHaveNoViolations) import './datepicker' import '../calendar/calendar' import { PktDatepicker } from './datepicker' const waitForCustomElements = async () => { await customElements.whenDefined('pkt-datepicker') await customElements.whenDefined('pkt-calendar') } // Helper function to create datepicker markup const createDatepicker = async (datepickerProps = '') => { const container = document.createElement('div') container.innerHTML = ` <pkt-datepicker ${datepickerProps}></pkt-datepicker> ` document.body.appendChild(container) await waitForCustomElements() return container } // Cleanup after each test afterEach(() => { document.body.innerHTML = '' }) describe('PktDatepicker', () => { describe('Event handling', () => { test('dispatches change event when value changes', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete let changeEventFired = false datepicker.addEventListener('change', () => { changeEventFired = true }) const input = datepicker.querySelector('input') as HTMLInputElement fireEvent.change(input, { target: { value: '2024-06-15' } }) fireEvent.blur(input) await datepicker.updateComplete expect(changeEventFired).toBe(true) }) test('dispatches input event during typing', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete let inputEventFired = false datepicker.addEventListener('input', () => { inputEventFired = true }) const input = datepicker.querySelector('input') as HTMLInputElement fireEvent.input(input, { target: { value: '2024-06-15' } }) await datepicker.updateComplete expect(inputEventFired).toBe(true) }) test('dispatches focus and blur events', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete let focusEventFired = false let blurEventFired = false datepicker.addEventListener('focus', () => { focusEventFired = true }) datepicker.addEventListener('blur', () => { blurEventFired = true }) const input = datepicker.querySelector('input') as HTMLInputElement fireEvent.focus(input) await datepicker.updateComplete fireEvent.blur(input) await datepicker.updateComplete expect(focusEventFired).toBe(true) expect(blurEventFired).toBe(true) }) }) describe('Accessibility', () => { test('has no accessibility violations', async () => { const container = await createDatepicker( 'label="Test Datepicker" helptext="Select your date"', ) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const results = await axe(datepicker) expect(results).toHaveNoViolations() }) test('associates label with input correctly', async () => { const container = await createDatepicker('id="test-datepicker" label="Test Label"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const label = datepicker.querySelector('label') const input = datepicker.querySelector('input') expect(label).toHaveAttribute('for') expect(input).toHaveAttribute('id') expect(label?.getAttribute('for')).toBe(input?.getAttribute('id')) }) test('has proper ARIA attributes for calendar button', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const calendarButton = datepicker.querySelector('button[type="button"]') expect(calendarButton).toBeInTheDocument() // Check initial state expect(datepicker.calendarOpen).toBe(false) // Open calendar fireEvent.click(calendarButton!) await datepicker.updateComplete expect(datepicker.calendarOpen).toBe(true) }) test('provides proper screen reader announcements', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const input = datepicker.querySelector('input') expect(input).toHaveAttribute('aria-describedby') }) test('handles focus management correctly', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLElement // Focus should be manageable if (calendarButton) { calendarButton.focus() expect(document.activeElement).toBe(calendarButton) } }) test('supports keyboard-only interaction', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLElement // Should open with keyboard if (calendarButton) { calendarButton.focus() fireEvent.keyDown(calendarButton, { key: 'Enter' }) await datepicker.updateComplete expect(datepicker.calendarOpen).toBe(true) } // Should close with keyboard fireEvent.keyDown(datepicker, { key: 'Escape' }) await datepicker.updateComplete expect(datepicker.calendarOpen).toBe(false) }) }) })