Skip to content

Commit 70a73dc

Browse files
committed
List and Table updates to consumer-driven-contract-testing-pact-internal-apis article
1 parent f7f1801 commit 70a73dc

7 files changed

Lines changed: 790 additions & 70 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import { beforeEach, describe, expect, test } from 'vitest'
2+
import { experimental_AstroContainer as AstroContainer } from 'astro/container'
3+
import FileExplorerAstro from '@components/FileExplorer/index.astro'
4+
import type { FileExplorerComponent } from '../index'
5+
import type { WebComponentModule } from '@components/scripts/@types/webComponentModule'
6+
import { executeRender } from '@test/unit/helpers/litRuntime'
7+
8+
const pressKey = (element: HTMLElement, key: string): void => {
9+
const keyboardEvent = new element.ownerDocument.defaultView!.KeyboardEvent('keydown', {
10+
key,
11+
bubbles: true,
12+
})
13+
14+
element.dispatchEvent(keyboardEvent)
15+
}
16+
17+
type FileExplorerModule = WebComponentModule<FileExplorerComponent>
18+
19+
describe('FileExplorer class behavior', () => {
20+
let container: AstroContainer
21+
22+
beforeEach(async () => {
23+
container = await AstroContainer.create()
24+
})
25+
26+
const mockData = [
27+
{
28+
type: 'folder',
29+
name: 'src',
30+
note: 'Application source files and test fixtures.',
31+
children: [
32+
{ type: 'file', name: 'index.ts', comment: 'Main entry', note: 'Primary FileExplorer implementation.' },
33+
],
34+
},
35+
{ type: 'file', name: 'package.json' },
36+
]
37+
38+
const renderArgs = {
39+
props: {
40+
data: mockData,
41+
figure: 'Figure <strong>caption</strong>',
42+
},
43+
}
44+
45+
const runComponentRender = async (
46+
assertion: (_context: { element: FileExplorerComponent }) => Promise<void> | void
47+
): Promise<void> => {
48+
await executeRender<FileExplorerModule>({
49+
container,
50+
component: FileExplorerAstro,
51+
moduleSpecifier: '@components/FileExplorer/client/index',
52+
args: renderArgs,
53+
waitForReady: async (element: FileExplorerComponent) => {
54+
await element.updateComplete
55+
},
56+
assert: async ({
57+
element,
58+
module,
59+
renderResult,
60+
}: {
61+
element: FileExplorerComponent
62+
module: FileExplorerModule
63+
renderResult: string
64+
}) => {
65+
expect(renderResult).toContain(`<${module.registeredName}`)
66+
await assertion({ element })
67+
},
68+
})
69+
}
70+
71+
test('renders hierarchical file systems based on data prop', async () => {
72+
await runComponentRender(async ({ element }) => {
73+
const root = element
74+
75+
const nodes = root.querySelectorAll('.node-name')
76+
expect(nodes.length).toBe(3)
77+
78+
const folderNames = Array.from(nodes).map(n => n.textContent?.trim())
79+
expect(folderNames).toContain('src')
80+
expect(folderNames).toContain('index.ts')
81+
expect(folderNames).toContain('package.json')
82+
83+
const comments = root.querySelectorAll('.comment')
84+
expect(comments.length).toBe(1)
85+
const firstComment = comments.item(0)
86+
expect(firstComment).toBeTruthy()
87+
expect(firstComment?.textContent?.trim()).toBe('# Main entry')
88+
89+
const tooltips = root.querySelectorAll('[role="tooltip"]')
90+
expect(tooltips.length).toBe(2)
91+
const tooltipTexts = Array.from(tooltips).map((tooltip) => tooltip.textContent?.trim())
92+
expect(tooltipTexts).toContain('Application source files and test fixtures.')
93+
expect(tooltipTexts).toContain('Primary FileExplorer implementation.')
94+
95+
const figure = root.querySelector('figure')
96+
expect(figure).toBeTruthy()
97+
98+
const figcaption = root.querySelector('figcaption')
99+
expect(figcaption).toBeTruthy()
100+
expect(figcaption?.textContent?.trim()).toBe('Figure caption')
101+
expect(figcaption?.querySelector('strong')?.textContent).toBe('caption')
102+
103+
const tree = root.querySelector('[role="tree"]')
104+
expect(tree).toBeTruthy()
105+
106+
const folderTreeItem = root.querySelector<HTMLElement>('[data-treeitem-path="0"]')
107+
expect(folderTreeItem?.getAttribute('role')).toBe('treeitem')
108+
expect(folderTreeItem?.getAttribute('aria-controls')).toBeTruthy()
109+
expect(folderTreeItem?.getAttribute('aria-level')).toBe('1')
110+
111+
const childGroup = root.querySelector('[role="group"]')
112+
expect(childGroup).toBeTruthy()
113+
114+
const decorativeIcons = root.querySelectorAll('svg[aria-hidden="true"]')
115+
expect(decorativeIcons.length).toBeGreaterThan(0)
116+
})
117+
})
118+
119+
test('collapses and expands directories when the folder row is clicked', async () => {
120+
await runComponentRender(async ({ element }) => {
121+
const toggle = element.querySelector<HTMLButtonElement>('button[data-node-path="0"]')
122+
const indicator = toggle?.querySelector('[data-toggle-indicator]')
123+
124+
expect(toggle).toBeTruthy()
125+
expect(indicator).toBeTruthy()
126+
expect(toggle?.getAttribute('aria-expanded')).toBe('true')
127+
expect(element.textContent).toContain('index.ts')
128+
129+
toggle?.click()
130+
await element.updateComplete
131+
132+
expect(toggle?.getAttribute('aria-expanded')).toBe('false')
133+
expect(element.textContent).not.toContain('index.ts')
134+
135+
toggle?.click()
136+
await element.updateComplete
137+
138+
expect(toggle?.getAttribute('aria-expanded')).toBe('true')
139+
expect(element.textContent).toContain('index.ts')
140+
})
141+
})
142+
143+
test('supports tree keyboard navigation and roving tabindex', async () => {
144+
await runComponentRender(async ({ element }) => {
145+
const rootTreeItem = element.querySelector<HTMLElement>('[data-treeitem-path="0"]')
146+
const childTreeItem = element.querySelector<HTMLElement>('[data-treeitem-path="0/0"]')
147+
148+
expect(rootTreeItem).toBeTruthy()
149+
expect(childTreeItem).toBeTruthy()
150+
expect(rootTreeItem?.getAttribute('tabindex')).toBe('0')
151+
expect(childTreeItem?.getAttribute('tabindex')).toBe('-1')
152+
153+
rootTreeItem?.focus()
154+
pressKey(rootTreeItem!, 'ArrowDown')
155+
await element.updateComplete
156+
157+
expect(childTreeItem?.getAttribute('tabindex')).toBe('0')
158+
159+
pressKey(rootTreeItem!, 'ArrowLeft')
160+
await element.updateComplete
161+
expect(rootTreeItem?.getAttribute('aria-expanded')).toBe('false')
162+
163+
pressKey(rootTreeItem!, 'ArrowRight')
164+
await element.updateComplete
165+
expect(rootTreeItem?.getAttribute('aria-expanded')).toBe('true')
166+
})
167+
})
168+
})

0 commit comments

Comments
 (0)