Skip to content

Commit ddaa9a8

Browse files
committed
test(ui): visual regression artifact component
1 parent 5f71eb7 commit ddaa9a8

File tree

3 files changed

+414
-0
lines changed

3 files changed

+414
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { faker } from '@faker-js/faker'
2+
import { describe, expect, it } from 'vitest'
3+
import { userEvent } from 'vitest/browser'
4+
import { defineComponent, h } from 'vue'
5+
import { page, render } from '~/test'
6+
import SmallTabs from './SmallTabs.vue'
7+
import SmallTabsPane from './SmallTabsPane.vue'
8+
9+
function createSmallTabs(children: number) {
10+
return defineComponent({
11+
setup: () =>
12+
() =>
13+
h(
14+
SmallTabs,
15+
null,
16+
{
17+
default: () => Array.from({ length: children }, () => h(
18+
SmallTabsPane,
19+
{ title: faker.lorem.word() },
20+
() => faker.lorem.words(2),
21+
)),
22+
},
23+
),
24+
})
25+
}
26+
27+
describe('SmallTabs', () => {
28+
it('has accessible elements', async () => {
29+
render(createSmallTabs(2))
30+
31+
// a tablist with two elements inside
32+
const tablist = page.getByRole('tablist')
33+
const tabs = tablist.getByRole('tab')
34+
const firstTab = tabs.first()
35+
const secondTab = tabs.last()
36+
37+
await expect.element(tablist).toBeInTheDocument()
38+
expect(tabs.all()).toHaveLength(2)
39+
40+
await expect.element(firstTab).toHaveAttribute('aria-selected', 'true')
41+
await expect.element(secondTab).toHaveAttribute('aria-selected', 'false')
42+
43+
// two tab panels, with one hidden
44+
const panels = page.getByRole('tabpanel', { includeHidden: true })
45+
const firstPanel = panels.first()
46+
const secondPanel = panels.last()
47+
48+
expect(panels.all()).toHaveLength(2)
49+
50+
await expect.element(firstPanel).not.toHaveAttribute('hidden')
51+
await expect.element(secondPanel).toHaveAttribute('hidden')
52+
53+
// panels should be labelled by their tab button
54+
await expect.element(firstPanel).toHaveAttribute(
55+
'aria-labelledby',
56+
firstTab.element().getAttribute('id'),
57+
)
58+
await expect.element(secondPanel).toHaveAttribute(
59+
'aria-labelledby',
60+
secondTab.element().getAttribute('id'),
61+
)
62+
63+
await expect.element(firstTab).toHaveAttribute(
64+
'aria-controls',
65+
firstPanel.element().getAttribute('id'),
66+
)
67+
await expect.element(secondTab).toHaveAttribute(
68+
'aria-controls',
69+
secondPanel.element().getAttribute('id'),
70+
)
71+
})
72+
73+
it('opens one panel at a time', async () => {
74+
const tabsLimit = 5
75+
76+
render(createSmallTabs(tabsLimit))
77+
78+
const tabs = page.getByRole('tablist').getByRole('tab')
79+
const panels = page.getByRole('tabpanel', { includeHidden: true })
80+
81+
for (let tabIndex = 0; tabIndex < tabsLimit; tabIndex += 1) {
82+
const activeTab = tabs.nth(tabIndex)
83+
const activePanel = panels.nth(tabIndex)
84+
85+
await userEvent.click(activeTab)
86+
await expect.element(
87+
tabs.and(page.getByRole('tab', { selected: true })),
88+
).toBe(activeTab.element())
89+
await expect.element(
90+
page.getByRole('tabpanel'),
91+
).toBe(activePanel.element())
92+
}
93+
})
94+
})
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import type { VisualRegressionArtifact } from '@vitest/runner'
2+
import { faker } from '@faker-js/faker'
3+
import { describe, expect, it } from 'vitest'
4+
import { userEvent } from 'vitest/browser'
5+
import { page, render } from '~/test'
6+
import VisualRegression from './VisualRegression.vue'
7+
8+
const diff = {
9+
name: 'diff',
10+
path: '/__diff.png',
11+
} as const
12+
13+
const reference = {
14+
name: 'reference',
15+
path: '/__reference.png',
16+
width: 500,
17+
height: 200,
18+
} as const
19+
20+
const actual = {
21+
name: 'actual',
22+
path: '/__actual.png',
23+
width: 500,
24+
height: 200,
25+
} as const
26+
27+
describe('VisualRegression', () => {
28+
it('renders content with no attachments', async () => {
29+
const messageContent = faker.lorem.words(5)
30+
31+
render(VisualRegression, {
32+
props: {
33+
regression: {
34+
type: 'internal:toMatchScreenshot',
35+
kind: 'visual-regression',
36+
message: messageContent,
37+
attachments: [],
38+
} satisfies VisualRegressionArtifact,
39+
},
40+
})
41+
42+
const article = page.getByRole('article')
43+
44+
await expect.element(article).toBeInTheDocument()
45+
await expect.element(article.getByRole('heading'))
46+
.toHaveTextContent('Visual Regression')
47+
await expect.element(article.getByRole('paragraph'))
48+
.toHaveTextContent(messageContent)
49+
await expect.element(article.getByRole('tablist')).toHaveTextContent('')
50+
})
51+
52+
it('renders diff tab', async () => {
53+
render(VisualRegression, {
54+
props: {
55+
regression: {
56+
type: 'internal:toMatchScreenshot',
57+
kind: 'visual-regression',
58+
message: faker.lorem.words(5),
59+
attachments: [diff],
60+
} satisfies VisualRegressionArtifact,
61+
},
62+
})
63+
64+
await expect.element(page.getByRole('tablist').getByRole('tab'))
65+
.toHaveTextContent('Diff')
66+
await expect.element(page.getByRole('tabpanel').getByRole('img'))
67+
.toBeInTheDocument()
68+
})
69+
70+
it('renders reference tab', async () => {
71+
render(VisualRegression, {
72+
props: {
73+
regression: {
74+
type: 'internal:toMatchScreenshot',
75+
kind: 'visual-regression',
76+
message: faker.lorem.words(5),
77+
attachments: [reference],
78+
} satisfies VisualRegressionArtifact,
79+
},
80+
})
81+
82+
await expect.element(page.getByRole('tablist').getByRole('tab'))
83+
.toHaveTextContent('Reference')
84+
await expect.element(page.getByRole('tabpanel').getByRole('img'))
85+
.toBeInTheDocument()
86+
})
87+
88+
it('renders actual tab', async () => {
89+
render(VisualRegression, {
90+
props: {
91+
regression: {
92+
type: 'internal:toMatchScreenshot',
93+
kind: 'visual-regression',
94+
message: faker.lorem.words(5),
95+
attachments: [actual],
96+
} satisfies VisualRegressionArtifact,
97+
},
98+
})
99+
100+
await expect.element(page.getByRole('tablist').getByRole('tab'))
101+
.toHaveTextContent('Actual')
102+
await expect.element(page.getByRole('tabpanel').getByRole('img'))
103+
.toBeInTheDocument()
104+
})
105+
106+
it('renders reference, actual, and slider tabs', async () => {
107+
render(VisualRegression, {
108+
props: {
109+
regression: {
110+
type: 'internal:toMatchScreenshot',
111+
kind: 'visual-regression',
112+
message: faker.lorem.words(5),
113+
attachments: [reference, actual],
114+
} satisfies VisualRegressionArtifact,
115+
},
116+
})
117+
118+
const tablist = page.getByRole('tablist')
119+
const tabs = tablist.getByRole('tab')
120+
121+
await expect.element(tablist).toBeInTheDocument()
122+
123+
expect(tabs.all()).toHaveLength(3)
124+
await expect.element(tabs.nth(0)).toHaveTextContent('Reference')
125+
await expect.element(tabs.nth(1)).toHaveTextContent('Actual')
126+
await expect.element(tabs.nth(2)).toHaveTextContent('Slider')
127+
128+
await userEvent.click(tabs.nth(2))
129+
130+
await expect.element(
131+
page.getByLabelText(
132+
'Image comparison slider showing reference and actual screenshots',
133+
),
134+
).toBeInTheDocument()
135+
})
136+
137+
it('renders diff, reference, actual, and slider tabs', async () => {
138+
render(VisualRegression, {
139+
props: {
140+
regression: {
141+
type: 'internal:toMatchScreenshot',
142+
kind: 'visual-regression',
143+
message: faker.lorem.words(5),
144+
attachments: [diff, reference, actual],
145+
} satisfies VisualRegressionArtifact,
146+
},
147+
})
148+
149+
const tablist = page.getByRole('tablist')
150+
const tabs = tablist.getByRole('tab')
151+
152+
await expect.element(tablist).toBeInTheDocument()
153+
154+
expect(tabs.all()).toHaveLength(4)
155+
await expect.element(tabs.nth(0)).toHaveTextContent('Diff')
156+
await expect.element(tabs.nth(1)).toHaveTextContent('Reference')
157+
await expect.element(tabs.nth(2)).toHaveTextContent('Actual')
158+
await expect.element(tabs.nth(3)).toHaveTextContent('Slider')
159+
})
160+
})

0 commit comments

Comments
 (0)