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.
247 lines
8.3 KiB
TypeScript
247 lines
8.3 KiB
TypeScript
import { uiHelpers } from '../../support/helpers/ui-helpers'
|
|
|
|
describe('Modal Component Tests', () => {
|
|
beforeEach(() => {
|
|
cy.visit('http://localhost:3001')
|
|
})
|
|
|
|
describe('Modal Display', () => {
|
|
it('should display modal when opened', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('be.visible')
|
|
})
|
|
|
|
it('should have modal header', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-header').should('be.visible')
|
|
})
|
|
|
|
it('should have modal body', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-body').should('be.visible')
|
|
})
|
|
|
|
it('should have modal footer', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-footer').should('be.visible')
|
|
})
|
|
|
|
it('should have close button', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').should('be.visible')
|
|
})
|
|
|
|
it('should display modal title', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-title').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Closing', () => {
|
|
it('should close on close button click', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').click()
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
|
|
it('should close on escape key', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.get('body').type('{esc}')
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
|
|
it('should close on backdrop click', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-backdrop').click({ force: true })
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
|
|
it('should close on confirm button', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').click()
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Sizes', () => {
|
|
it('should render small modal', () => {
|
|
cy.getByTestId('small-modal-trigger').click()
|
|
cy.getByTestId('modal-container').should('have.class', 'small')
|
|
})
|
|
|
|
it('should render medium modal', () => {
|
|
cy.getByTestId('medium-modal-trigger').click()
|
|
cy.getByTestId('modal-container').should('have.class', 'medium')
|
|
})
|
|
|
|
it('should render large modal', () => {
|
|
cy.getByTestId('large-modal-trigger').click()
|
|
cy.getByTestId('modal-container').should('have.class', 'large')
|
|
})
|
|
|
|
it('should render full width modal', () => {
|
|
cy.getByTestId('fullwidth-modal-trigger').click()
|
|
cy.getByTestId('modal-container').should('have.class', 'fullwidth')
|
|
})
|
|
})
|
|
|
|
describe('Modal Content', () => {
|
|
it('should accept custom content', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-body').should('contain', 'Modal content')
|
|
})
|
|
|
|
it('should support scrollable content', () => {
|
|
cy.getByTestId('scrollable-modal-trigger').click()
|
|
cy.getByTestId('modal-body').scrollTo('bottom')
|
|
cy.getByTestId('modal-body').should('be.visible')
|
|
})
|
|
|
|
it('should display custom actions', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').should('be.visible')
|
|
cy.getByTestId('modal-cancel-button').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Buttons', () => {
|
|
it('should have confirm button', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').should('be.visible')
|
|
})
|
|
|
|
it('should have cancel button', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-cancel-button').should('be.visible')
|
|
})
|
|
|
|
it('should handle button click', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').click()
|
|
cy.getByTestId('modal-action-result').should('contain', 'confirmed')
|
|
})
|
|
|
|
it('should disable button when loading', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').click()
|
|
cy.getByTestId('modal-loading-state').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Animations', () => {
|
|
it('should animate modal open', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('have.css', 'animation')
|
|
})
|
|
|
|
it('should animate modal close', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').click()
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Stacking', () => {
|
|
it('should stack multiple modals', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('nested-modal-trigger').click()
|
|
cy.getByTestId('nested-modal-container').should('be.visible')
|
|
})
|
|
|
|
it('should close top modal first', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('nested-modal-trigger').click()
|
|
cy.getByTestId('nested-modal-close-button').click()
|
|
cy.getByTestId('nested-modal-container').should('not.be.visible')
|
|
cy.getByTestId('modal-container').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Backdrop', () => {
|
|
it('should show backdrop', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-backdrop').should('be.visible')
|
|
})
|
|
|
|
it('should prevent background scroll', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.get('body').should('have.css', 'overflow', 'hidden')
|
|
})
|
|
|
|
it('should restore scroll on close', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').click()
|
|
cy.get('body').should('not.have.css', 'overflow', 'hidden')
|
|
})
|
|
})
|
|
|
|
describe('Modal Focus Management', () => {
|
|
it('should focus close button on open', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').should('have.focus')
|
|
})
|
|
|
|
it('should trap focus inside modal', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-confirm-button').focus()
|
|
cy.getByTestId('modal-confirm-button').type('{tab}')
|
|
cy.getByTestId('modal-close-button').should('have.focus')
|
|
})
|
|
|
|
it('should return focus to trigger on close', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-close-button').click()
|
|
cy.getByTestId('modal-trigger-button').should('have.focus')
|
|
})
|
|
})
|
|
|
|
describe('Accessibility', () => {
|
|
it('should have role dialog', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('have.attr', 'role', 'dialog')
|
|
})
|
|
|
|
it('should have aria-labelledby', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('have.attr', 'aria-labelledby')
|
|
})
|
|
|
|
it('should announce title to screen readers', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-title').should('have.attr', 'id')
|
|
})
|
|
|
|
it('should support keyboard commands', () => {
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.get('body').type('{esc}')
|
|
cy.getByTestId('modal-container').should('not.be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Modal Responsive', () => {
|
|
it('should be responsive on mobile', () => {
|
|
cy.viewport('iphone-x')
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('be.visible')
|
|
})
|
|
|
|
it('should adjust size on tablet', () => {
|
|
cy.viewport('ipad-2')
|
|
cy.getByTestId('modal-trigger-button').click()
|
|
cy.getByTestId('modal-container').should('be.visible')
|
|
})
|
|
})
|
|
|
|
describe('Error Handling', () => {
|
|
it('should handle missing content gracefully', () => {
|
|
cy.getByTestId('empty-modal-trigger').click()
|
|
cy.getByTestId('modal-container').should('be.visible')
|
|
})
|
|
|
|
it('should display error message', () => {
|
|
cy.getByTestId('error-modal-trigger').click()
|
|
cy.getByTestId('modal-error-message').should('be.visible')
|
|
})
|
|
})
|
|
})
|