UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

226 lines (189 loc) 6.57 kB
import '@testing-library/jest-dom' import { axe, toHaveNoViolations } from 'jest-axe' import { fireEvent } from '@testing-library/dom' import { vi } from 'vitest' import { createElementTest, BaseTestConfig } from '../../tests/test-framework' import { CustomElementFor } from '../../tests/component-registry' import './link' expect.extend(toHaveNoViolations) export interface LinkTestConfig extends BaseTestConfig { href?: string target?: string skin?: string variant?: string iconName?: string iconPosition?: string openInNewTab?: boolean external?: boolean } // Use shared framework export const createLinkTest = async (config: LinkTestConfig = {}) => { const { container, element } = await createElementTest< CustomElementFor<'pkt-link'>, LinkTestConfig >('pkt-link', config) return { container, link: element, } } describe('PktLink', () => { describe('Rendering and basic functionality', () => { test('renders without errors', async () => { const { link } = await createLinkTest() expect(link).toBeInTheDocument() await link.updateComplete expect(link).toBeTruthy() }) test('renders with correct structure', async () => { const { link } = await createLinkTest({ href: 'https://example.com', content: 'Click me', }) await link.updateComplete expect(link).toBeInTheDocument() const anchor = link.querySelector('a') expect(anchor).toBeInTheDocument() expect(anchor?.href).toBe('https://example.com/') expect(anchor?.textContent).toContain('Click me') }) }) describe('Properties and attributes', () => { test('applies default properties correctly', async () => { const { link } = await createLinkTest() await link.updateComplete expect(link.href).toBe('#') expect(link.external).toBe(false) expect(link.iconName).toBeUndefined() expect(link.target).toBe('_self') }) test('sets href property correctly', async () => { const { link } = await createLinkTest({ href: 'https://example.com', }) await link.updateComplete expect(link.href).toBe('https://example.com') const anchor = link.querySelector('a') expect(anchor?.href).toBe('https://example.com/') }) test('sets external property correctly', async () => { const { link } = await createLinkTest({ href: 'https://example.com', external: true, }) await link.updateComplete expect(link.external).toBe(true) }) }) describe('Icon functionality', () => { test('renders icon when iconName is provided', async () => { const { link } = await createLinkTest({ href: '#', iconName: 'arrow-right', }) await link.updateComplete const icon = link.querySelector('pkt-icon') expect(icon).toBeInTheDocument() expect(icon?.getAttribute('name')).toBe('arrow-right') }) test('positions icon correctly', async () => { const { link } = await createLinkTest({ href: '#', iconName: 'arrow-right', iconPosition: 'right', }) await link.updateComplete const anchor = link.querySelector('a') expect(anchor?.classList.contains('pkt-link--icon-right')).toBe(true) }) }) describe('External link functionality', () => { test('applies external class and rel attribute', async () => { const { link } = await createLinkTest({ href: 'https://example.com', external: true, }) await link.updateComplete const anchor = link.querySelector('a') expect(anchor?.classList.contains('pkt-link--external')).toBe(true) expect(anchor?.rel).toBe('noopener noreferrer') }) test('does not set rel attribute for internal links', async () => { const { link } = await createLinkTest({ href: '/internal-page', }) await link.updateComplete const anchor = link.querySelector('a') expect(anchor?.rel).toBe('') }) }) describe('Event handling', () => { test('handles click events', async () => { const { link } = await createLinkTest({ href: '#test', }) await link.updateComplete const anchor = link.querySelector('a') const clickHandler = vi.fn() anchor?.addEventListener('click', clickHandler) fireEvent.click(anchor!) expect(clickHandler).toHaveBeenCalled() }) }) describe('Dynamic updates', () => { test('updates href dynamically', async () => { const { link } = await createLinkTest({ href: 'https://example.com', }) await link.updateComplete link.href = 'https://updated.com' await link.updateComplete expect(link.href).toBe('https://updated.com') const anchor = link.querySelector('a') expect(anchor?.href).toBe('https://updated.com/') }) test('updates external property dynamically', async () => { const { link } = await createLinkTest({ href: 'https://example.com', }) await link.updateComplete link.external = true await link.updateComplete expect(link.external).toBe(true) const anchor = link.querySelector('a') expect(anchor?.classList.contains('pkt-link--external')).toBe(true) expect(anchor?.rel).toBe('noopener noreferrer') }) }) describe('Accessibility', () => { test('basic link is accessible', async () => { const { container } = await createLinkTest({ href: 'https://example.com', content: 'Accessible Link', }) await new Promise((resolve) => setTimeout(resolve, 100)) const results = await axe(container) expect(results).toHaveNoViolations() }) }) describe('Integration scenarios', () => { test('works with complex configurations', async () => { const { link } = await createLinkTest({ href: 'https://external-site.com', iconName: 'external', iconPosition: 'right', external: true, target: '_blank', content: 'Complex External Link', }) await link.updateComplete expect(link.href).toBe('https://external-site.com') expect(link.iconName).toBe('external') expect(link.external).toBe(true) expect(link.target).toBe('_blank') const anchor = link.querySelector('a') expect(anchor?.classList.contains('pkt-link--external')).toBe(true) expect(anchor?.classList.contains('pkt-link--icon-right')).toBe(true) }) }) })