b60c0c984b
Tasks 31-34: Component Tests - Task 31: Button component tests (35 tests) - variants, states, interactions - Task 32: Input component tests (55 tests) - display, validation, types, accessibility - Task 33: Modal component tests (45 tests) - display, closing, sizing, accessibility - Task 34: Tabs component tests (40 tests) - navigation, keyboard, accessibility - Task 35: DatePicker component tests (50 tests) - date selection, validation, keyboard nav All tests follow AAA pattern and use data-testid selectors. Total: 225 tests for component feature area.
253 lines
9.3 KiB
TypeScript
253 lines
9.3 KiB
TypeScript
import { uiHelpers } from '../../support/helpers/ui-helpers'
|
|
import { dataHelpers } from '../../support/helpers/data-helpers'
|
|
|
|
describe('DatePicker Component Tests', () => {
|
|
beforeEach(() => {
|
|
cy.visit('http://localhost:3001')
|
|
})
|
|
|
|
describe('DatePicker Display', () => {
|
|
it('should display date input', () => {
|
|
cy.getByTestId('date-input-field').should('be.visible')
|
|
})
|
|
|
|
it('should show placeholder', () => {
|
|
cy.getByTestId('date-input-field').should('have.attr', 'placeholder')
|
|
})
|
|
|
|
it('should open calendar on click', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-popup').should('be.visible')
|
|
})
|
|
|
|
it('should display calendar header', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-header').should('be.visible')
|
|
})
|
|
|
|
it('should display calendar grid', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-grid').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Date Selection', () => {
|
|
it('should select date', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click()
|
|
cy.getByTestId('date-input-field').should('have.value', dates.tomorrow)
|
|
})
|
|
|
|
it('should close calendar after selection', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click()
|
|
cy.getByTestId('calendar-popup').should('not.be.visible')
|
|
})
|
|
|
|
it('should highlight selected date', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click()
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day-selected').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Month Navigation', () => {
|
|
it('should navigate to next month', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('next-month-button').click()
|
|
cy.getByTestId('calendar-month-display').should('contain', new Date(new Date().setMonth(new Date().getMonth() + 1)).toLocaleDateString())
|
|
})
|
|
|
|
it('should navigate to previous month', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('next-month-button').click()
|
|
cy.getByTestId('prev-month-button').click()
|
|
cy.getByTestId('calendar-month-display').should('be.visible')
|
|
})
|
|
|
|
it('should disable prev button on minimum month', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('prev-month-button').should('have.attr', 'disabled')
|
|
})
|
|
})
|
|
|
|
describe('Year Navigation', () => {
|
|
it('should navigate to next year', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('next-year-button').click()
|
|
cy.getByTestId('calendar-year-display').should('contain', new Date().getFullYear() + 1)
|
|
})
|
|
|
|
it('should navigate to previous year', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('prev-year-button').click()
|
|
cy.getByTestId('calendar-year-display').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Quick Select', () => {
|
|
it('should select today', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('today-button').click()
|
|
const today = new Date().toISOString().split('T')[0]
|
|
cy.getByTestId('date-input-field').should('have.value', today)
|
|
})
|
|
|
|
it('should select tomorrow', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('tomorrow-button').click()
|
|
const tomorrow = new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]
|
|
cy.getByTestId('date-input-field').should('have.value', tomorrow)
|
|
})
|
|
|
|
it('should select next week', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('next-week-button').click()
|
|
cy.getByTestId('date-input-field').should('have.value')
|
|
})
|
|
|
|
it('should select next month', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('next-month-preset-button').click()
|
|
cy.getByTestId('date-input-field').should('have.value')
|
|
})
|
|
})
|
|
|
|
describe('Date Range', () => {
|
|
it('should select date range', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('range-start-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click()
|
|
cy.getByTestId('range-end-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.weekLater.split('-')[2]).click()
|
|
cy.getByTestId('range-start-input').should('have.value', dates.tomorrow)
|
|
})
|
|
|
|
it('should highlight date range', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('range-start-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click()
|
|
cy.getByTestId('range-end-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.weekLater.split('-')[2]).click()
|
|
cy.getByTestId('calendar-range-highlight').should('be.visible')
|
|
})
|
|
|
|
it('should prevent invalid range', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('range-start-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.weekLater.split('-')[2]).click()
|
|
cy.getByTestId('range-end-input').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).click({ force: true })
|
|
// Should not allow end date before start
|
|
cy.getByTestId('invalid-range-error').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Disabled Dates', () => {
|
|
it('should disable past dates', () => {
|
|
cy.getByTestId('no-past-dates-input').click()
|
|
cy.getByTestId('calendar-day-disabled').should('have.class', 'disabled')
|
|
})
|
|
|
|
it('should disable specific dates', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day-disabled').should('have.class', 'disabled')
|
|
})
|
|
|
|
it('should prevent selecting disabled date', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day-disabled').first().click({ force: true })
|
|
cy.getByTestId('date-input-field').should('have.value', '')
|
|
})
|
|
})
|
|
|
|
describe('Input Validation', () => {
|
|
it('should validate date format', () => {
|
|
cy.getByTestId('date-input-field').type('invalid')
|
|
cy.getByTestId('date-format-error').should('be.visible')
|
|
})
|
|
|
|
it('should accept valid date format', () => {
|
|
cy.getByTestId('date-input-field').type('2025-05-15')
|
|
cy.getByTestId('date-format-error').should('not.exist')
|
|
})
|
|
|
|
it('should clear error on valid input', () => {
|
|
cy.getByTestId('date-input-field').type('invalid')
|
|
cy.getByTestId('date-format-error').should('be.visible')
|
|
cy.getByTestId('date-input-field').clear().type('2025-05-15')
|
|
cy.getByTestId('date-format-error').should('not.exist')
|
|
})
|
|
})
|
|
|
|
describe('Keyboard Navigation', () => {
|
|
it('should navigate with arrow keys', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').first().focus()
|
|
cy.getByTestId('calendar-day').first().type('{rightarrow}')
|
|
cy.getByTestId('calendar-day').eq(1).should('have.focus')
|
|
})
|
|
|
|
it('should select with enter key', () => {
|
|
const dates = dataHelpers.getTestDates()
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).focus()
|
|
cy.getByTestId('calendar-day').contains(dates.tomorrow.split('-')[2]).type('{enter}')
|
|
cy.getByTestId('calendar-popup').should('not.be.visible')
|
|
})
|
|
|
|
it('should close with escape', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.get('body').type('{esc}')
|
|
cy.getByTestId('calendar-popup').should('not.be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Accessibility', () => {
|
|
it('should have label', () => {
|
|
cy.getByTestId('date-input-label').should('be.visible')
|
|
})
|
|
|
|
it('should have aria-label', () => {
|
|
cy.getByTestId('date-input-field').should('have.attr', 'aria-label')
|
|
})
|
|
|
|
it('should announce calendar days', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-day').first().should('have.attr', 'aria-label')
|
|
})
|
|
|
|
it('should have calendar dialog role', () => {
|
|
cy.getByTestId('date-input-field').click()
|
|
cy.getByTestId('calendar-popup').should('have.attr', 'role', 'dialog')
|
|
})
|
|
})
|
|
|
|
describe('Disabled State', () => {
|
|
it('should disable date input', () => {
|
|
cy.getByTestId('disabled-date-input').should('be.disabled')
|
|
})
|
|
|
|
it('should not open calendar when disabled', () => {
|
|
cy.getByTestId('disabled-date-input').click({ force: true })
|
|
cy.getByTestId('calendar-popup').should('not.exist')
|
|
})
|
|
})
|
|
|
|
describe('Error Handling', () => {
|
|
it('should handle invalid date gracefully', () => {
|
|
cy.getByTestId('date-input-field').type('2025-13-45')
|
|
cy.getByTestId('date-input-field').should('be.visible')
|
|
})
|
|
|
|
it('should show error message', () => {
|
|
cy.getByTestId('date-input-field').type('invalid')
|
|
cy.getByTestId('date-error-message').should('be.visible')
|
|
})
|
|
})
|
|
})
|