@oslokommune/punkt-elements 13.3.1 → 13.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,640 @@
1
+ import '@testing-library/jest-dom'
2
+ import { axe, toHaveNoViolations } from 'jest-axe'
3
+
4
+ expect.extend(toHaveNoViolations)
5
+
6
+ // Import the components
7
+ import './accordion'
8
+ import './accordionitem'
9
+
10
+ // Import the component classes for type checking
11
+ import { PktAccordion } from './accordion'
12
+ import { PktAccordionItem } from './accordionitem'
13
+
14
+ const waitForCustomElements = async () => {
15
+ await Promise.all([
16
+ customElements.whenDefined('pkt-accordion'),
17
+ customElements.whenDefined('pkt-accordion-item'),
18
+ ])
19
+ }
20
+
21
+ // Helper function to create accordion markup
22
+ const createAccordion = async (
23
+ accordionProps = '',
24
+ accordionItemProps = '',
25
+ content = 'Test content',
26
+ ) => {
27
+ const container = document.createElement('div')
28
+ container.innerHTML = `
29
+ <pkt-accordion ${accordionProps}>
30
+ <pkt-accordion-item id="test-item" title="Test Title" ${accordionItemProps}>
31
+ ${content}
32
+ </pkt-accordion-item>
33
+ </pkt-accordion>
34
+ `
35
+ document.body.appendChild(container)
36
+ await waitForCustomElements()
37
+ return container
38
+ }
39
+
40
+ // Helper function to create multiple accordion items
41
+ const createAccordionWithMultipleItems = async (accordionProps = '') => {
42
+ const container = document.createElement('div')
43
+ container.innerHTML = `
44
+ <pkt-accordion ${accordionProps}>
45
+ <pkt-accordion-item id="item1" title="Title 1">
46
+ Content 1
47
+ </pkt-accordion-item>
48
+ <pkt-accordion-item id="item2" title="Title 2">
49
+ Content 2
50
+ </pkt-accordion-item>
51
+ <pkt-accordion-item id="item3" title="Title 3">
52
+ Content 3
53
+ </pkt-accordion-item>
54
+ </pkt-accordion>
55
+ `
56
+ document.body.appendChild(container)
57
+ await waitForCustomElements()
58
+ return container
59
+ }
60
+
61
+ // Cleanup after each test
62
+ afterEach(() => {
63
+ document.body.innerHTML = ''
64
+ })
65
+
66
+ describe('PktAccordion', () => {
67
+ describe('Rendering and basic functionality', () => {
68
+ test('renders without errors', async () => {
69
+ const container = await createAccordion()
70
+
71
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
72
+ expect(accordion).toBeInTheDocument()
73
+
74
+ await accordion.updateComplete
75
+ expect(accordion.shadowRoot).toBeTruthy()
76
+ })
77
+
78
+ test('renders children accordion items', async () => {
79
+ const container = await createAccordionWithMultipleItems()
80
+
81
+ const accordionItems = container.querySelectorAll('pkt-accordion-item')
82
+ expect(accordionItems).toHaveLength(3)
83
+
84
+ // Verify content is rendered
85
+ expect(container.textContent).toContain('Title 1')
86
+ expect(container.textContent).toContain('Content 1')
87
+ expect(container.textContent).toContain('Title 2')
88
+ expect(container.textContent).toContain('Content 2')
89
+ expect(container.textContent).toContain('Title 3')
90
+ expect(container.textContent).toContain('Content 3')
91
+ })
92
+
93
+ test('applies default properties correctly', async () => {
94
+ const container = await createAccordion()
95
+
96
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
97
+ await accordion.updateComplete
98
+
99
+ expect(accordion.compact).toBe(false)
100
+ expect(accordion.skin).toBe('borderless')
101
+ expect(accordion.name).toBe('')
102
+ expect(accordion.ariaLabelledBy).toBe('')
103
+
104
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
105
+ expect(accordionDiv).toHaveClass('pkt-accordion')
106
+ expect(accordionDiv).toHaveClass('pkt-accordion--borderless')
107
+ expect(accordionDiv).not.toHaveClass('pkt-accordion--compact')
108
+ })
109
+ })
110
+
111
+ describe('Properties and attributes', () => {
112
+ test('applies compact property correctly', async () => {
113
+ const container = await createAccordion('compact')
114
+
115
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
116
+ await accordion.updateComplete
117
+
118
+ expect(accordion.compact).toBe(true)
119
+ expect(accordion.hasAttribute('compact')).toBe(true)
120
+
121
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
122
+ expect(accordionDiv).toHaveClass('pkt-accordion--compact')
123
+ })
124
+
125
+ test('applies different skin properties correctly', async () => {
126
+ const skins = ['borderless', 'outlined', 'beige', 'blue']
127
+
128
+ for (const skin of skins) {
129
+ const container = await createAccordion(`skin="${skin}"`)
130
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
131
+ await accordion.updateComplete
132
+
133
+ expect(accordion.skin).toBe(skin)
134
+ expect(accordion.getAttribute('skin')).toBe(skin)
135
+
136
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
137
+ expect(accordionDiv).toHaveClass(`pkt-accordion--${skin}`)
138
+
139
+ // Cleanup for next iteration
140
+ container.remove()
141
+ }
142
+ })
143
+
144
+ test('applies aria-labelledby correctly', async () => {
145
+ const container = await createAccordion('aria-labelledby="test-heading"')
146
+
147
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
148
+ await accordion.updateComplete
149
+
150
+ expect(accordion.ariaLabelledBy).toBe('test-heading')
151
+ expect(accordion.getAttribute('aria-labelledby')).toBe('test-heading')
152
+
153
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
154
+ expect(accordionDiv?.getAttribute('aria-labelledby')).toBe('test-heading')
155
+ })
156
+
157
+ test('applies name property and updates accordion items', async () => {
158
+ const container = await createAccordionWithMultipleItems('name="test-group"')
159
+
160
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
161
+ const accordionItems = container.querySelectorAll('pkt-accordion-item')
162
+ await accordion.updateComplete
163
+
164
+ expect(accordion.name).toBe('test-group')
165
+ expect(accordion.getAttribute('name')).toBe('test-group')
166
+
167
+ // All accordion items should inherit the name
168
+ accordionItems.forEach((item) => {
169
+ expect(item.getAttribute('name')).toBe('test-group')
170
+ })
171
+ })
172
+
173
+ test('updates accordion item names when name property changes', async () => {
174
+ const container = await createAccordionWithMultipleItems()
175
+
176
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
177
+ const accordionItems = container.querySelectorAll('pkt-accordion-item')
178
+ await accordion.updateComplete
179
+
180
+ // Initially no name
181
+ expect(accordion.name).toBe('')
182
+ accordionItems.forEach((item) => {
183
+ expect(item.getAttribute('name')).toBe(null)
184
+ })
185
+
186
+ // Update name property
187
+ accordion.name = 'updated-group'
188
+ await accordion.updateComplete
189
+
190
+ // All accordion items should now have the updated name
191
+ accordionItems.forEach((item) => {
192
+ expect(item.getAttribute('name')).toBe('updated-group')
193
+ })
194
+ })
195
+
196
+ test('does not override existing name on accordion items', async () => {
197
+ const container = document.createElement('div')
198
+ container.innerHTML = `
199
+ <pkt-accordion name="group-name">
200
+ <pkt-accordion-item id="item1" title="Title 1" name="existing-name">
201
+ Content 1
202
+ </pkt-accordion-item>
203
+ <pkt-accordion-item id="item2" title="Title 2">
204
+ Content 2
205
+ </pkt-accordion-item>
206
+ </pkt-accordion>
207
+ `
208
+ document.body.appendChild(container)
209
+ await waitForCustomElements()
210
+
211
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
212
+ const accordionItems = container.querySelectorAll('pkt-accordion-item')
213
+ await accordion.updateComplete
214
+
215
+ // First item should keep its existing name
216
+ expect(accordionItems[0].getAttribute('name')).toBe('existing-name')
217
+ // Second item should get the accordion's name
218
+ expect(accordionItems[1].getAttribute('name')).toBe('group-name')
219
+ })
220
+ })
221
+
222
+ describe('Dynamic content handling', () => {
223
+ test('handles dynamically added accordion items', async () => {
224
+ const container = await createAccordion('name="dynamic-group"')
225
+
226
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
227
+ await accordion.updateComplete
228
+
229
+ // Add a new accordion item
230
+ const newItem = document.createElement('pkt-accordion-item') as PktAccordionItem
231
+ newItem.setAttribute('id', 'dynamic-item')
232
+ newItem.setAttribute('title', 'Dynamic Title')
233
+ newItem.textContent = 'Dynamic Content'
234
+ accordion.appendChild(newItem)
235
+
236
+ // Wait for the slot change to propagate
237
+ await new Promise((resolve) => setTimeout(resolve, 100))
238
+ await accordion.updateComplete
239
+
240
+ expect(newItem.getAttribute('name')).toBe('dynamic-group')
241
+ })
242
+ })
243
+ })
244
+
245
+ describe('PktAccordionItem', () => {
246
+ describe('Rendering and basic functionality', () => {
247
+ test('renders without errors', async () => {
248
+ const container = await createAccordion()
249
+
250
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
251
+ expect(accordionItem).toBeInTheDocument()
252
+
253
+ await accordionItem.updateComplete
254
+ expect(accordionItem).toBeTruthy()
255
+
256
+ const details = accordionItem.querySelector('details')
257
+ expect(details).toBeInTheDocument()
258
+ })
259
+
260
+ test('renders with correct structure', async () => {
261
+ const container = await createAccordion('', '', 'Test accordion content')
262
+
263
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
264
+ await accordionItem.updateComplete
265
+
266
+ const details = accordionItem.querySelector('details')
267
+ const summary = details?.querySelector('summary')
268
+ const content = details?.querySelector('.pkt-accordion-item__content')
269
+ const contentInner = content?.querySelector('.pkt-accordion-item__content-inner')
270
+
271
+ expect(summary).toHaveClass('pkt-accordion-item__title')
272
+ expect(summary?.textContent).toContain('Test Title')
273
+ expect(content?.getAttribute('role')).toBe('region')
274
+ expect(contentInner?.textContent).toContain('Test accordion content')
275
+ expect(contentInner).toBeInTheDocument()
276
+ })
277
+
278
+ test('renders icon correctly', async () => {
279
+ const container = await createAccordion()
280
+
281
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
282
+ await accordionItem.updateComplete
283
+
284
+ const icon = accordionItem.querySelector('pkt-icon')
285
+ expect(icon).toBeInTheDocument()
286
+ expect(icon?.getAttribute('name')).toBe('chevron-thin-down')
287
+ expect(icon).toHaveClass('pkt-accordion-item__icon')
288
+ expect(icon?.getAttribute('aria-hidden')).toBe('true')
289
+ })
290
+ })
291
+
292
+ describe('Properties and attributes', () => {
293
+ test('applies default properties correctly', async () => {
294
+ const container = await createAccordion()
295
+
296
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
297
+ await accordionItem.updateComplete
298
+
299
+ expect(accordionItem.defaultOpen).toBe(false)
300
+ expect(accordionItem.title).toBe('Test Title')
301
+ expect(accordionItem.skin).toBe(undefined)
302
+
303
+ const details = accordionItem.querySelector('details')
304
+ expect(details?.hasAttribute('open')).toBe(false)
305
+ })
306
+
307
+ test('applies different skin properties correctly', async () => {
308
+ const skins = ['borderless', 'outlined', 'beige', 'blue']
309
+
310
+ for (const skin of skins) {
311
+ const container = await createAccordion('', `skin="${skin}"`)
312
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
313
+ await accordionItem.updateComplete
314
+
315
+ expect(accordionItem.skin).toBe(skin)
316
+ expect(accordionItem.getAttribute('skin')).toBe(skin)
317
+
318
+ const details = accordionItem.querySelector('details')
319
+ expect(details).toHaveClass(`pkt-accordion-item--${skin}`)
320
+
321
+ // Cleanup for next iteration
322
+ container.remove()
323
+ }
324
+ })
325
+
326
+ test('handles defaultOpen property', async () => {
327
+ const container = await createAccordion('', '')
328
+
329
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
330
+
331
+ // Test that setting defaultOpen to true sets isOpen to true
332
+ accordionItem.defaultOpen = true
333
+ await accordionItem.updateComplete
334
+
335
+ // Manually trigger what firstUpdated should do
336
+ if (accordionItem.defaultOpen) {
337
+ accordionItem.isOpen = true
338
+ }
339
+ await accordionItem.updateComplete
340
+
341
+ expect(accordionItem.defaultOpen).toBe(true)
342
+ // When defaultOpen is true, isOpen should be set to true
343
+ expect(accordionItem.isOpen).toBe(true)
344
+
345
+ const details = accordionItem.querySelector('details')
346
+ expect(details?.hasAttribute('open')).toBe(true)
347
+ })
348
+
349
+ test('handles title property updates', async () => {
350
+ const container = await createAccordion()
351
+
352
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
353
+ await accordionItem.updateComplete
354
+
355
+ const summary = accordionItem.querySelector('summary')
356
+ expect(summary?.textContent).toContain('Test Title')
357
+
358
+ // Update title
359
+ accordionItem.title = 'Updated Title'
360
+ await accordionItem.updateComplete
361
+
362
+ expect(summary?.textContent).toContain('Updated Title')
363
+ })
364
+ })
365
+
366
+ describe('Interaction and state management', () => {
367
+ test('toggles open state when isOpen property changes', async () => {
368
+ const container = await createAccordion()
369
+
370
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
371
+ await accordionItem.updateComplete
372
+
373
+ const details = accordionItem.querySelector('details')
374
+ expect(details?.hasAttribute('open')).toBe(false)
375
+
376
+ // Set isOpen to true
377
+ accordionItem.isOpen = true
378
+ await accordionItem.updateComplete
379
+
380
+ expect(details?.hasAttribute('open')).toBe(true)
381
+
382
+ // Set isOpen to false
383
+ accordionItem.isOpen = false
384
+ await accordionItem.updateComplete
385
+
386
+ expect(details?.hasAttribute('open')).toBe(false)
387
+ })
388
+
389
+ test('respects name attribute for grouped behavior', async () => {
390
+ const container = await createAccordionWithMultipleItems('name="test-group"')
391
+
392
+ const accordionItems = container.querySelectorAll(
393
+ 'pkt-accordion-item',
394
+ ) as NodeListOf<PktAccordionItem>
395
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
396
+
397
+ const details = Array.from(accordionItems)
398
+ .map((item) => item.querySelector('details'))
399
+ .filter(Boolean) as HTMLDetailsElement[]
400
+
401
+ // Open first item programmatically
402
+ accordionItems[0].isOpen = true
403
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
404
+
405
+ expect(details[0].hasAttribute('open')).toBe(true)
406
+ expect(details[1].hasAttribute('open')).toBe(false)
407
+ expect(details[2].hasAttribute('open')).toBe(false)
408
+
409
+ // Open second item (should close first due to grouping)
410
+ accordionItems[1].isOpen = true
411
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
412
+
413
+ // Note: If grouping behavior is implemented, first item should close
414
+ // For now, let's test basic functionality
415
+ expect(details[1].hasAttribute('open')).toBe(true)
416
+ })
417
+
418
+ test('allows multiple items open when no name grouping', async () => {
419
+ const container = await createAccordionWithMultipleItems()
420
+
421
+ const accordionItems = container.querySelectorAll(
422
+ 'pkt-accordion-item',
423
+ ) as NodeListOf<PktAccordionItem>
424
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
425
+
426
+ const details = Array.from(accordionItems)
427
+ .map((item) => item.querySelector('details'))
428
+ .filter(Boolean) as HTMLDetailsElement[]
429
+
430
+ // Open first and third items programmatically
431
+ accordionItems[0].isOpen = true
432
+ accordionItems[2].isOpen = true
433
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
434
+
435
+ // Both should remain open since there's no grouping
436
+ expect(details[0].hasAttribute('open')).toBe(true)
437
+ expect(details[1].hasAttribute('open')).toBe(false)
438
+ expect(details[2].hasAttribute('open')).toBe(true)
439
+ })
440
+ })
441
+ })
442
+
443
+ describe('Integration tests', () => {
444
+ test('accordion and accordion items work together correctly', async () => {
445
+ const container = await createAccordionWithMultipleItems(
446
+ 'skin="outlined" compact name="integration-test"',
447
+ )
448
+
449
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
450
+ const accordionItems = container.querySelectorAll(
451
+ 'pkt-accordion-item',
452
+ ) as NodeListOf<PktAccordionItem>
453
+ await accordion.updateComplete
454
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
455
+
456
+ // Verify accordion properties
457
+ expect(accordion.skin).toBe('outlined')
458
+ expect(accordion.compact).toBe(true)
459
+ expect(accordion.name).toBe('integration-test')
460
+
461
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
462
+ expect(accordionDiv).toHaveClass('pkt-accordion')
463
+ expect(accordionDiv).toHaveClass('pkt-accordion--outlined')
464
+ expect(accordionDiv).toHaveClass('pkt-accordion--compact')
465
+
466
+ // Verify all items have inherited name
467
+ accordionItems.forEach((item) => {
468
+ expect(item.getAttribute('name')).toBe('integration-test')
469
+ })
470
+
471
+ const details = Array.from(accordionItems)
472
+ .map((item) => item.querySelector('details'))
473
+ .filter(Boolean) as HTMLDetailsElement[]
474
+
475
+ // Open items programmatically to test functionality
476
+ accordionItems[0].isOpen = true
477
+ accordionItems[2].isOpen = true
478
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
479
+
480
+ // Test that properties are reflected to attributes
481
+ expect(details[0].hasAttribute('open')).toBe(true)
482
+ expect(details[2].hasAttribute('open')).toBe(true)
483
+ })
484
+
485
+ test('handles mixed open states correctly', async () => {
486
+ const container = document.createElement('div')
487
+ container.innerHTML = `
488
+ <pkt-accordion>
489
+ <pkt-accordion-item id="item1" title="Title 1" default-open>
490
+ Content 1
491
+ </pkt-accordion-item>
492
+ <pkt-accordion-item id="item2" title="Title 2">
493
+ Content 2
494
+ </pkt-accordion-item>
495
+ </pkt-accordion>
496
+ `
497
+ document.body.appendChild(container)
498
+ await waitForCustomElements()
499
+
500
+ const accordionItems = container.querySelectorAll(
501
+ 'pkt-accordion-item',
502
+ ) as NodeListOf<PktAccordionItem>
503
+
504
+ // Set defaultOpen and isOpen programmatically to test the functionality
505
+ accordionItems[0].defaultOpen = true
506
+ accordionItems[0].isOpen = true
507
+
508
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
509
+
510
+ const details = Array.from(accordionItems)
511
+ .map((item) => item.querySelector('details'))
512
+ .filter(Boolean) as HTMLDetailsElement[]
513
+
514
+ // Item 1 should be open due to defaultOpen
515
+ expect(details[0].hasAttribute('open')).toBe(true)
516
+ // Item 2 should be closed
517
+ expect(details[1].hasAttribute('open')).toBe(false)
518
+ })
519
+ })
520
+
521
+ describe('Accessibility', () => {
522
+ test('has correct ARIA attributes', async () => {
523
+ const container = document.createElement('div')
524
+ container.innerHTML = `
525
+ <h2 id="accordion-heading">Main Accordion</h2>
526
+ <pkt-accordion aria-labelledby="accordion-heading">
527
+ <pkt-accordion-item id="test-item" title="Test Title">
528
+ Test content
529
+ </pkt-accordion-item>
530
+ </pkt-accordion>
531
+ `
532
+ document.body.appendChild(container)
533
+ await waitForCustomElements()
534
+
535
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
536
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
537
+ await accordion.updateComplete
538
+ await accordionItem.updateComplete
539
+
540
+ const accordionDiv = accordion.shadowRoot?.querySelector('.pkt-accordion')
541
+ const content = accordionItem.querySelector('.pkt-accordion-item__content')
542
+ const icon = accordionItem.querySelector('pkt-icon')
543
+
544
+ expect(accordionDiv?.getAttribute('aria-labelledby')).toBe('accordion-heading')
545
+ expect(content?.getAttribute('role')).toBe('region')
546
+ expect(icon?.getAttribute('aria-hidden')).toBe('true')
547
+ })
548
+
549
+ test('renders with no WCAG errors with axe - simple accordion', async () => {
550
+ const container = await createAccordion()
551
+
552
+ // Wait for all components to be fully rendered
553
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
554
+ const accordionItem = container.querySelector('pkt-accordion-item') as PktAccordionItem
555
+ await accordion.updateComplete
556
+ await accordionItem.updateComplete
557
+
558
+ const results = await axe(container)
559
+ expect(results).toHaveNoViolations()
560
+ })
561
+
562
+ test('renders with no WCAG errors with axe - complex accordion', async () => {
563
+ const container = document.createElement('div')
564
+ container.innerHTML = `
565
+ <h2 id="accordion-heading">Test Accordion Heading</h2>
566
+ <pkt-accordion skin="outlined" compact aria-labelledby="accordion-heading" name="test-group">
567
+ <pkt-accordion-item id="item1" title="First Item" default-open>
568
+ <p>This is the first accordion item content with <a href="#">a link</a>.</p>
569
+ </pkt-accordion-item>
570
+ <pkt-accordion-item id="item2" title="Second Item">
571
+ <div>
572
+ <h3>Nested content</h3>
573
+ <ul>
574
+ <li>List item 1</li>
575
+ <li>List item 2</li>
576
+ </ul>
577
+ </div>
578
+ </pkt-accordion-item>
579
+ <pkt-accordion-item id="item3" title="Third Item" skin="blue">
580
+ <form>
581
+ <label for="test-input">Test Input:</label>
582
+ <input type="text" id="test-input" name="test" />
583
+ <button type="submit">Submit</button>
584
+ </form>
585
+ </pkt-accordion-item>
586
+ </pkt-accordion>
587
+ `
588
+ document.body.appendChild(container)
589
+ await waitForCustomElements()
590
+
591
+ const accordion = container.querySelector('pkt-accordion') as PktAccordion
592
+ const accordionItems = container.querySelectorAll(
593
+ 'pkt-accordion-item',
594
+ ) as NodeListOf<PktAccordionItem>
595
+ await accordion.updateComplete
596
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
597
+
598
+ const results = await axe(container)
599
+ expect(results).toHaveNoViolations()
600
+ })
601
+
602
+ test('renders with no WCAG errors with axe - multiple accordions', async () => {
603
+ const container = document.createElement('div')
604
+ container.innerHTML = `
605
+ <div>
606
+ <h2 id="first-accordion-heading">First Accordion</h2>
607
+ <pkt-accordion aria-labelledby="first-accordion-heading" name="first-group">
608
+ <pkt-accordion-item id="first-item1" title="First Group Item 1">
609
+ Content for first group
610
+ </pkt-accordion-item>
611
+ <pkt-accordion-item id="first-item2" title="First Group Item 2">
612
+ More content for first group
613
+ </pkt-accordion-item>
614
+ </pkt-accordion>
615
+
616
+ <h2 id="second-accordion-heading">Second Accordion</h2>
617
+ <pkt-accordion aria-labelledby="second-accordion-heading" name="second-group" skin="beige">
618
+ <pkt-accordion-item id="second-item1" title="Second Group Item 1">
619
+ Content for second group
620
+ </pkt-accordion-item>
621
+ <pkt-accordion-item id="second-item2" title="Second Group Item 2">
622
+ More content for second group
623
+ </pkt-accordion-item>
624
+ </pkt-accordion>
625
+ </div>
626
+ `
627
+ document.body.appendChild(container)
628
+ await waitForCustomElements()
629
+
630
+ const accordions = container.querySelectorAll('pkt-accordion') as NodeListOf<PktAccordion>
631
+ const accordionItems = container.querySelectorAll(
632
+ 'pkt-accordion-item',
633
+ ) as NodeListOf<PktAccordionItem>
634
+ await Promise.all(Array.from(accordions).map((acc) => acc.updateComplete))
635
+ await Promise.all(Array.from(accordionItems).map((item) => item.updateComplete))
636
+
637
+ const results = await axe(container)
638
+ expect(results).toHaveNoViolations()
639
+ })
640
+ })