Files

110 lines
3.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { userEvent } from 'vitest/browser'
import { defineComponent, h } from 'vue'
import { page, render } from '~/test'
import SmallTabs from './SmallTabs.vue'
import SmallTabsPane from './SmallTabsPane.vue'
function createSmallTabs(children: number) {
return defineComponent({
setup: () =>
() =>
h(
SmallTabs,
null,
{
default: () => Array.from({ length: children }, (_, i) => h(
SmallTabsPane,
{ title: `title-${i}` },
() => `content-${i}`,
)),
},
),
})
}
describe('SmallTabs', () => {
it('has accessible elements', async () => {
const result = await render(createSmallTabs(2))
// a tablist with two elements inside
const tablist = page.getByRole('tablist')
const tabs = tablist.getByRole('tab')
const firstTab = tabs.first()
const secondTab = tabs.last()
await expect.element(tablist).toBeInTheDocument()
await expect.element(result.locator).toMatchAriaInlineSnapshot(`
- tablist:
- tab "title-0" [selected]
- tab "title-1"
- tabpanel "title-0": content-0
`)
expect(tabs.all()).toHaveLength(2)
await expect.element(firstTab).toHaveAttribute('aria-selected', 'true')
await expect.element(secondTab).toHaveAttribute('aria-selected', 'false')
// two tab panels, with one hidden
const panels = page.getByRole('tabpanel', { includeHidden: true })
const firstPanel = panels.first()
const secondPanel = panels.last()
expect(panels.all()).toHaveLength(2)
await expect.element(firstPanel).not.toHaveAttribute('hidden')
await expect.element(secondPanel).toHaveAttribute('hidden')
// panels should be labelled by their tab button
await expect.element(firstPanel).toHaveAttribute(
'aria-labelledby',
firstTab.element().getAttribute('id'),
)
await expect.element(secondPanel).toHaveAttribute(
'aria-labelledby',
secondTab.element().getAttribute('id'),
)
await expect.element(firstTab).toHaveAttribute(
'aria-controls',
firstPanel.element().getAttribute('id'),
)
await expect.element(secondTab).toHaveAttribute(
'aria-controls',
secondPanel.element().getAttribute('id'),
)
})
it('opens one panel at a time', async () => {
const tabsLimit = 5
const result = await render(createSmallTabs(tabsLimit))
const tabs = page.getByRole('tablist').getByRole('tab')
const panels = page.getByRole('tabpanel', { includeHidden: true })
for (let tabIndex = 0; tabIndex < tabsLimit; tabIndex += 1) {
const activeTab = tabs.nth(tabIndex)
const activePanel = panels.nth(tabIndex)
await userEvent.click(activeTab)
await expect.element(
tabs.and(page.getByRole('tab', { selected: true })),
).toBe(activeTab.element())
await expect.element(
page.getByRole('tabpanel'),
).toBe(activePanel.element())
}
expect(result.container).toMatchAriaInlineSnapshot(`
- tablist:
- tab "title-0"
- tab "title-1"
- tab "title-2"
- tab "title-3"
- tab "title-4" [selected]
- tabpanel "title-4": content-4
`)
})
})