UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

258 lines (205 loc) 8.3 kB
import '@testing-library/jest-dom' import { axe, toHaveNoViolations } from 'jest-axe' import { createElementTest, BaseTestConfig } from '../../tests/test-framework' import { CustomElementFor } from '../../tests/component-registry' import { type IPktLoader } from './loader' import './loader' export interface LoaderTestConfig extends Partial<IPktLoader>, BaseTestConfig {} // Use shared framework export const createLoaderTest = async (config: LoaderTestConfig = {}) => { const { container, element } = await createElementTest< CustomElementFor<'pkt-loader'>, LoaderTestConfig >('pkt-loader', { ...config, isLoading: undefined }) // Set boolean properties directly on the element after creation if (config.isLoading !== undefined) { element.isLoading = config.isLoading await element.updateComplete } if (config.inline !== undefined) { element.inline = config.inline await element.updateComplete } return { container, loader: element, } } expect.extend(toHaveNoViolations) afterEach(() => { document.body.innerHTML = '' }) describe('PktLoader', () => { describe('Rendering and basic functionality', () => { test('renders without errors', async () => { const { loader } = await createLoaderTest() expect(loader).toBeInTheDocument() expect(loader).toBeTruthy() }) test('renders loading state by default', async () => { const { loader } = await createLoaderTest() expect(loader.isLoading).toBe(true) const spinner = loader.querySelector('.pkt-loader__spinner') expect(spinner).toBeInTheDocument() }) test('renders content when not loading', async () => { const { loader } = await createLoaderTest({ content: '<p>Content</p>', isLoading: false, }) expect(loader.isLoading).toBe(false) const content = loader.querySelector('.pkt-contents') expect(content).toBeInTheDocument() expect(content?.classList.contains('pkt-hide')).toBe(false) }) test('renders with slot content', async () => { const { loader } = await createLoaderTest({ content: '<p>Test content</p>', }) const content = loader.querySelector('p') expect(content).toBeInTheDocument() expect(content?.textContent).toBe('Test content') }) }) describe('Properties and attributes', () => { test('applies default properties correctly', async () => { const { loader } = await createLoaderTest() expect(loader.isLoading).toBe(true) expect(loader.inline).toBe(false) expect(loader.size).toBe('medium') expect(loader.variant).toBe('shapes') expect(loader.delay).toBe(0) }) test('sets properties correctly', async () => { const { loader } = await createLoaderTest({ size: 'small', variant: 'blue', delay: 100, isLoading: false, inline: true, }) expect(loader.isLoading).toBe(false) expect(loader.inline).toBe(true) expect(loader.size).toBe('small') expect(loader.variant).toBe('blue') expect(loader.delay).toBe(100) }) }) describe('Size variants', () => { test('applies small size correctly', async () => { const { loader } = await createLoaderTest({ size: 'small' }) const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.classList.contains('pkt-loader--small')).toBe(true) }) test('applies medium size correctly', async () => { const { loader } = await createLoaderTest({ size: 'medium' }) const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.classList.contains('pkt-loader--medium')).toBe(true) }) test('applies large size correctly', async () => { const { loader } = await createLoaderTest({ size: 'large' }) const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.classList.contains('pkt-loader--large')).toBe(true) }) }) describe('Loader variants', () => { test('applies shapes variant correctly', async () => { const { loader } = await createLoaderTest({ variant: 'shapes' }) const icon = loader.querySelector('pkt-icon') expect(icon?.getAttribute('name')).toBe('loader') }) test('applies blue variant correctly', async () => { const { loader } = await createLoaderTest({ variant: 'blue' }) const icon = loader.querySelector('pkt-icon') expect(icon?.getAttribute('name')).toBe('spinner-blue') }) test('applies rainbow variant correctly', async () => { const { loader } = await createLoaderTest({ variant: 'rainbow' }) const icon = loader.querySelector('pkt-icon') expect(icon?.getAttribute('name')).toBe('spinner') }) }) describe('Inline mode', () => { test('applies box class when inline is false', async () => { const { loader } = await createLoaderTest({ inline: false }) const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.classList.contains('pkt-loader--box')).toBe(true) }) test('applies inline class when inline is true', async () => { const { loader } = await createLoaderTest({ inline: true }) const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.classList.contains('pkt-loader--inline')).toBe(true) }) }) describe('Message functionality', () => { test('renders message when provided', async () => { const { loader } = await createLoaderTest({ message: 'Loading data...' }) const message = loader.querySelector('p') expect(message).toBeInTheDocument() expect(message?.textContent).toBe('Loading data...') }) test('does not render message when not provided', async () => { const { loader } = await createLoaderTest() const message = loader.querySelector('p') expect(message).not.toBeInTheDocument() }) }) describe('Delay functionality', () => { test('handles delay correctly', async () => { const { loader } = await createLoaderTest({ delay: 100 }) // Initially should not show spinner due to delay let spinner = loader.querySelector('.pkt-loader__spinner') expect(spinner).not.toBeInTheDocument() // Wait for delay to pass await new Promise((resolve) => setTimeout(resolve, 150)) await loader.updateComplete // Now spinner should be visible spinner = loader.querySelector('.pkt-loader__spinner') expect(spinner).toBeInTheDocument() }, 300) }) describe('Content visibility', () => { test('hides content when loading', async () => { const { loader } = await createLoaderTest({ isLoading: true, content: '<p>Content</p>', }) const content = loader.querySelector('.pkt-contents') expect(content?.classList.contains('pkt-hide')).toBe(true) }) test('shows content when not loading', async () => { const { loader } = await createLoaderTest({ isLoading: false, content: '<p>Content</p>', }) const content = loader.querySelector('.pkt-contents') expect(content?.classList.contains('pkt-hide')).toBe(false) }) }) describe('ARIA and accessibility', () => { test('has correct ARIA attributes', async () => { const { loader } = await createLoaderTest() const loaderDiv = loader.querySelector('.pkt-loader') expect(loaderDiv?.getAttribute('role')).toBe('status') expect(loaderDiv?.getAttribute('aria-live')).toBe('polite') // Check the aria-busy attribute expect(loaderDiv?.getAttribute('aria-busy')).toBe('true') }) test('updates aria-busy when loading state changes', async () => { const { loader } = await createLoaderTest({ isLoading: false }) const loaderDiv = loader.querySelector('.pkt-loader') // Check the aria-busy attribute expect(loaderDiv?.getAttribute('aria-busy')).toBe('false') }) }) describe('Accessibility', () => { test('loader is accessible', async () => { const { container } = await createLoaderTest({ message: 'Loading content', content: '<p>Content</p>', }) const results = await axe(container) expect(results).toHaveNoViolations() }) }) })