import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import ContextualMenu from '../ContextualMenu.vue'
describe('ContextualMenu', () => {
it('renders correctly with items', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
},
{
text: 'Titre 2',
hash: '#example-2',
},
],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('renders correctly without items', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('emit an update:modelValue event when an item is updated', async () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
},
{
text: 'Titre 2',
hash: '#example-2',
},
],
},
})
await wrapper.find('a').trigger('click')
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['#example-1'])
})
it('update the highlighted item when the modelValue is updated', async () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
},
{
text: 'Titre 2',
hash: '#example-2',
},
],
modelValue: '#example-2',
},
})
expect(wrapper.find('[href="#example-2"]').classes()).toContain('active')
})
it('initialize with the content of location.href', async () => {
window.location.hash = '#example-2'
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
},
{
text: 'Titre 2',
hash: '#example-2',
},
],
},
})
await wrapper.vm.$nextTick()
expect(wrapper.find('[href="#example-2"]').classes()).toContain('active')
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['#example-2'])
})
describe('layout', () => {
it('render correctly with a deepth', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
level: 2,
},
{
text: 'Titre 2',
hash: '#example-2',
level: 4,
},
{
text: 'Titre 3',
hash: '#example-3',
level: 2,
},
],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('render correctly with a deepth', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
level: 3,
},
{
text: 'Titre 2',
hash: '#example-2',
level: 2,
},
{
text: 'Titre 3',
hash: '#example-3',
level: 1,
},
{
text: 'Titre 4',
hash: '#example-4',
level: 2,
},
{
text: 'Titre 5',
hash: '#example-5',
level: 3,
},
],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('render correctly with a deepth', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
level: 1,
},
{
text: 'Titre 2',
hash: '#example-2',
level: 3,
},
{
text: 'Titre 3',
hash: '#example-3',
},
{
text: 'Titre 4',
hash: '#example-4',
level: 3,
},
{
text: 'Titre 5',
hash: '#example-5',
level: 1,
},
],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
it('render correctly with a deepth', () => {
const wrapper = mount(ContextualMenu, {
props: {
ariaLabel: 'menu contextuel',
items: [
{
text: 'Titre 1',
hash: '#example-1',
},
{
text: 'Titre 2',
hash: '#example-2',
},
{
text: 'Titre 3',
hash: '#example-3',
level: 3,
},
{
text: 'Titre 4',
hash: '#example-4',
level: 3,
},
{
text: 'Titre 5',
hash: '#example-5',
level: 1,
},
],
},
})
expect(wrapper.html()).toMatchSnapshot()
})
})
})
// Le ring de focus est scopé (jsdom ne calcule pas :focus-visible) : on vérifie le
// prérequis — des liens natifs focusables.
describe('ContextualMenu - focus', () => {
const items = [
{ text: 'Accueil', hash: '#accueil' },
{ text: 'Compte', hash: '#compte' },
]
it('renders native links so the focus ring applies', () => {
const wrapper = mount(ContextualMenu, { props: { ariaLabel: 'Menu', items } })
expect(wrapper.get('.vd-contextual-menu a').element.tagName).toBe('A')
wrapper.unmount()
})
it('is focusable', () => {
const wrapper = mount(ContextualMenu, {
props: { ariaLabel: 'Menu', items },
attachTo: document.body,
})
const link = wrapper.get('.vd-contextual-menu a').element as HTMLAnchorElement
link.focus()
expect(document.activeElement).toBe(link)
wrapper.unmount()
})
})