UNPKG

@mozaic-ds/vue

Version:

Mozaic-Vue is the Vue.js implementation of ADEO Design system

210 lines (179 loc) 6.94 kB
import { mount } from '@vue/test-utils'; import { describe, it, expect } from 'vitest'; import MNavigationIndicator from './MNavigationIndicator.vue'; const PauseCircle24 = { name: 'PauseCircle24', template: '<span data-testid="pause-icon"></span>', }; const PlayCircle24 = { name: 'PlayCircle24', template: '<span data-testid="play-icon"></span>', }; const MButton = { name: 'MButton', props: ['size', 'iconPosition', 'ghost'], template: ` <button data-testid="m-button"> <slot /> <slot name="icon" /> <slot /> </button> `, }; const MIconButton = { name: 'MIconButton', props: ['size', 'ghost'], template: `<button data-testid="m-icon-button"><slot name="icon" /></button>`, }; describe('MNavigationIndicator.vue', () => { it('renders the correct number of steps', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 4, modelValue: 0 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const items = wrapper.findAll('.mc-navigation-indicator__item'); expect(items).toHaveLength(4); }); it('applies active class to the current step', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 5, modelValue: 2 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const stepButtons = wrapper.findAll( '.mc-navigation-indicator__list .mc-navigation-indicator__button', ); expect(stepButtons[2].classes()).toContain( 'mc-navigation-indicator__button--active', ); }); it('emits update:modelValue when a step is clicked', async () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 3, modelValue: 0 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const stepButtons = wrapper.findAll( '.mc-navigation-indicator__list .mc-navigation-indicator__button', ); await stepButtons[1].trigger('click'); const emitted = wrapper.emitted('update:modelValue'); expect(emitted).toBeTruthy(); expect(emitted![0][0]).toBe(1); }); it('does not emit update:modelValue when a wrong key is pressed', async () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 3, modelValue: 0 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const stepButtons = wrapper.findAll( '.mc-navigation-indicator__list .mc-navigation-indicator__button', ); await stepButtons[2].trigger('keydown', { key: 'Esc' }); const emitted = wrapper.emitted('update:modelValue'); expect(emitted).toBeFalsy(); }); it('does not render action button when player is false', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, player: false }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); expect(wrapper.find('[data-testid="m-button"]').exists()).toBe(false); expect(wrapper.find('[data-testid="m-icon-button"]').exists()).toBe(false); }); it('renders icon-only button when no label is defined', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, action: 'resume' }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); expect(wrapper.find('[data-testid="m-icon-button"]').exists()).toBe(true); expect(wrapper.find('[data-testid="play-icon"]').exists()).toBe(true); }); it('renders labeled button with correct label and pause icon when action is pause', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, label: 'Pause', action: 'pause' }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const button = wrapper.find('[data-testid="m-button"]'); expect(button.exists()).toBe(true); expect(button.text()).toContain('Pause'); expect(wrapper.find('[data-testid="pause-icon"]').exists()).toBe(true); }); it('renders a navigation landmark with an aria-label', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 3, modelValue: 0 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const navigation = wrapper.find('nav[aria-label="Navigation steps"]'); expect(navigation.exists()).toBe(true); expect(navigation.attributes('aria-label')).toBe('Navigation steps'); }); it('player icon button has aria-label reflecting action state', () => { const wrapperPause = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, action: 'pause' }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 } }, }); expect( wrapperPause .find('[data-testid="m-icon-button"]') .attributes('aria-label'), ).toBe('Pause'); const wrapperResume = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, action: 'resume' }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 } }, }); expect( wrapperResume .find('[data-testid="m-icon-button"]') .attributes('aria-label'), ).toBe('Resume'); }); it('gives each step button an action-oriented aria-label', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 3, modelValue: 1 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const buttons = wrapper.findAll('.mc-navigation-indicator__button'); expect(buttons[0].attributes('aria-label')).toBe('Go to step 1 of 3'); expect(buttons[1].attributes('aria-label')).toBe('Current step, 2 of 3'); expect(buttons[2].attributes('aria-label')).toBe('Go to step 3 of 3'); }); it('sets aria-current="step" only on the active step button', () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 3, modelValue: 1 }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); const buttons = wrapper.findAll('.mc-navigation-indicator__button'); expect(buttons[1].attributes('aria-current')).toBe('step'); expect(buttons[0].attributes('aria-current')).not.toBe('step'); expect(buttons[2].attributes('aria-current')).not.toBe('step'); }); it('emits "action" when the player button is clicked', async () => { const wrapper = mount(MNavigationIndicator, { props: { steps: 2, modelValue: 0, action: 'resume' }, global: { stubs: { MButton, MIconButton, PauseCircle24, PlayCircle24 }, }, }); await wrapper.find('[data-testid="m-icon-button"]').trigger('click'); expect(wrapper.emitted('action')).toBeTruthy(); }); });