@oslokommune/punkt-elements 13.5.1 → 13.5.3

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.
@@ -1,30 +1,39 @@
1
1
  import '@testing-library/jest-dom'
2
2
  import { axe, toHaveNoViolations } from 'jest-axe'
3
3
  import { fireEvent } from '@testing-library/dom'
4
+ import { createElementTest, BaseTestConfig } from '../../tests/test-framework'
5
+ import { CustomElementFor } from '../../tests/component-registry'
6
+ import './button'
4
7
 
5
8
  expect.extend(toHaveNoViolations)
6
9
 
7
- import './button'
8
- import { PktButton } from './button' // For type checking
9
-
10
- const waitForCustomElements = async () => {
11
- await Promise.all([
12
- customElements.whenDefined('pkt-button'),
13
- customElements.whenDefined('pkt-icon'),
14
- ])
10
+ export interface ButtonTestConfig extends BaseTestConfig {
11
+ size?: string
12
+ skin?: string
13
+ variant?: string
14
+ color?: string
15
+ type?: string
16
+ disabled?: boolean
17
+ isLoading?: boolean
18
+ iconName?: string
19
+ iconNameSecond?: string
20
+ iconPosition?: string
21
+ mode?: string
22
+ form?: string
23
+ content?: string
15
24
  }
16
25
 
17
- // Helper function to create button markup
18
- const createButton = async (buttonProps = '', content = 'Test Button') => {
19
- const container = document.createElement('div')
20
- container.innerHTML = `
21
- <pkt-button ${buttonProps}>
22
- ${content}
23
- </pkt-button>
24
- `
25
- document.body.appendChild(container)
26
- await waitForCustomElements()
27
- return container
26
+ // Use shared framework
27
+ export const createButtonTest = async (config: ButtonTestConfig = {}) => {
28
+ const { container, element } = await createElementTest<
29
+ CustomElementFor<'pkt-button'>,
30
+ ButtonTestConfig
31
+ >('pkt-button', config)
32
+
33
+ return {
34
+ container,
35
+ button: element,
36
+ }
28
37
  }
29
38
 
30
39
  // Cleanup after each test
@@ -35,41 +44,36 @@ afterEach(() => {
35
44
  describe('PktButton', () => {
36
45
  describe('Rendering and basic functionality', () => {
37
46
  test('renders without errors', async () => {
38
- const container = await createButton()
39
-
40
- const pktButton = container.querySelector('pkt-button') as PktButton
41
- expect(pktButton).toBeInTheDocument()
47
+ const { button } = await createButtonTest({ content: 'Test Button' })
42
48
 
43
- await pktButton.updateComplete
44
- expect(pktButton).toBeTruthy()
45
-
46
- const button = pktButton.querySelector('button')
47
49
  expect(button).toBeInTheDocument()
50
+ expect(button).toBeTruthy()
51
+
52
+ const nativeButton = button.querySelector('button')
53
+ expect(nativeButton).toBeInTheDocument()
48
54
  })
49
55
 
50
56
  test('renders with correct structure', async () => {
51
- const container = await createButton('variant="icon-left" icon-name="user"', 'Click Me')
52
-
53
- const pktButton = container.querySelector('pkt-button') as PktButton
54
- await pktButton.updateComplete
57
+ const { button } = await createButtonTest({
58
+ variant: 'icon-left',
59
+ iconName: 'user',
60
+ content: 'Click Me',
61
+ })
55
62
 
56
- const button = pktButton.querySelector('button')
57
- const icon = button?.querySelector('pkt-icon')
58
- const textSpan = button?.querySelector('.pkt-btn__text')
63
+ const nativeButton = button.querySelector('button')
64
+ const icon = nativeButton?.querySelector('pkt-icon')
65
+ const textSpan = nativeButton?.querySelector('.pkt-btn__text')
59
66
 
60
- expect(button).toHaveClass('pkt-btn')
67
+ expect(nativeButton).toHaveClass('pkt-btn')
61
68
  expect(icon).toHaveClass('pkt-btn__icon')
62
69
  expect(textSpan).toHaveClass('pkt-btn__text')
63
70
  expect(textSpan?.textContent?.trim()).toContain('Click Me')
64
71
  })
65
72
 
66
73
  test('renders text correctly', async () => {
67
- const container = await createButton('', 'Button Text Content')
74
+ const { button } = await createButtonTest({ content: 'Button Text Content' })
68
75
 
69
- const pktButton = container.querySelector('pkt-button') as PktButton
70
- await pktButton.updateComplete
71
-
72
- const textSpan = pktButton.querySelector('.pkt-btn__text')
76
+ const textSpan = button.querySelector('.pkt-btn__text')
73
77
  expect(textSpan).toBeInTheDocument()
74
78
  expect(textSpan?.textContent?.trim()).toContain('Button Text Content')
75
79
  })
@@ -77,41 +81,35 @@ describe('PktButton', () => {
77
81
 
78
82
  describe('Properties and attributes', () => {
79
83
  test('applies default properties correctly', async () => {
80
- const container = await createButton()
81
-
82
- const pktButton = container.querySelector('pkt-button') as PktButton
83
- await pktButton.updateComplete
84
-
85
- expect(pktButton.size).toBe('medium')
86
- expect(pktButton.skin).toBe('primary')
87
- expect(pktButton.variant).toBe('label-only')
88
- expect(pktButton.type).toBe('button')
89
- expect(pktButton.mode).toBe('light')
90
- expect(pktButton.disabled).toBe(false)
91
- expect(pktButton.isLoading).toBe(false)
92
-
93
- const button = pktButton.querySelector('button')
94
- expect(button).toHaveClass('pkt-btn')
95
- expect(button).toHaveClass('pkt-btn--medium')
96
- expect(button).toHaveClass('pkt-btn--primary')
97
- expect(button).toHaveClass('pkt-btn--label-only')
84
+ const { button } = await createButtonTest({ content: 'Test Button' })
85
+ await button.updateComplete
86
+
87
+ expect(button.size).toBe('medium')
88
+ expect(button.skin).toBe('primary')
89
+ expect(button.variant).toBe('label-only')
90
+ expect(button.type).toBe('button')
91
+ expect(button.mode).toBe('light')
92
+ expect(button.disabled).toBe(false)
93
+ expect(button.isLoading).toBe(false)
94
+
95
+ const buttonEl = button.querySelector('button')
96
+ expect(buttonEl).toHaveClass('pkt-btn')
97
+ expect(buttonEl).toHaveClass('pkt-btn--medium')
98
+ expect(buttonEl).toHaveClass('pkt-btn--primary')
99
+ expect(buttonEl).toHaveClass('pkt-btn--label-only')
98
100
  })
99
101
 
100
102
  test('applies different size properties correctly', async () => {
101
103
  const sizes = ['small', 'medium', 'large'] as const
102
104
 
103
105
  for (const size of sizes) {
104
- const container = await createButton(`size="${size}"`)
105
- const pktButton = container.querySelector('pkt-button') as PktButton
106
- await pktButton.updateComplete
107
-
108
- expect(pktButton.size).toBe(size)
106
+ const { button } = await createButtonTest({ size, content: 'Test Button' })
107
+ await button.updateComplete
109
108
 
110
- const button = pktButton.querySelector('button')
111
- expect(button).toHaveClass(`pkt-btn--${size}`)
109
+ expect(button.size).toBe(size)
112
110
 
113
- // Cleanup for next iteration
114
- container.remove()
111
+ const buttonEl = button.querySelector('button')
112
+ expect(buttonEl).toHaveClass(`pkt-btn--${size}`)
115
113
  }
116
114
  })
117
115
 
@@ -119,17 +117,13 @@ describe('PktButton', () => {
119
117
  const skins = ['primary', 'secondary', 'tertiary'] as const
120
118
 
121
119
  for (const skin of skins) {
122
- const container = await createButton(`skin="${skin}"`)
123
- const pktButton = container.querySelector('pkt-button') as PktButton
124
- await pktButton.updateComplete
120
+ const { button } = await createButtonTest({ skin, content: 'Test Button' })
121
+ await button.updateComplete
125
122
 
126
- expect(pktButton.skin).toBe(skin)
123
+ expect(button.skin).toBe(skin)
127
124
 
128
- const button = pktButton.querySelector('button')
129
- expect(button).toHaveClass(`pkt-btn--${skin}`)
130
-
131
- // Cleanup for next iteration
132
- container.remove()
125
+ const buttonEl = button.querySelector('button')
126
+ expect(buttonEl).toHaveClass(`pkt-btn--${skin}`)
133
127
  }
134
128
  })
135
129
 
@@ -143,19 +137,21 @@ describe('PktButton', () => {
143
137
  ] as const
144
138
 
145
139
  for (const variant of variants) {
146
- const container = await createButton(
147
- `variant="${variant}" icon-name="user" second-icon-name="star"`,
148
- )
149
- const pktButton = container.querySelector('pkt-button') as PktButton
150
- await pktButton.updateComplete
140
+ const { button } = await createButtonTest({
141
+ variant,
142
+ iconName: 'user',
143
+ iconNameSecond: 'star',
144
+ content: 'Test Button',
145
+ })
146
+ await button.updateComplete
151
147
 
152
- expect(pktButton.variant).toBe(variant)
148
+ expect(button.variant).toBe(variant)
153
149
 
154
- const button = pktButton.querySelector('button')
155
- expect(button).toHaveClass(`pkt-btn--${variant}`)
150
+ const buttonEl = button.querySelector('button')
151
+ expect(buttonEl).toHaveClass(`pkt-btn--${variant}`)
156
152
 
157
153
  // Check icon rendering based on variant
158
- const icons = button?.querySelectorAll('pkt-icon:not(.pkt-btn__spinner)')
154
+ const icons = buttonEl?.querySelectorAll('pkt-icon:not(.pkt-btn__spinner)')
159
155
  if (variant === 'label-only') {
160
156
  expect(icons).toHaveLength(0)
161
157
  } else if (variant === 'icons-right-and-left') {
@@ -163,9 +159,6 @@ describe('PktButton', () => {
163
159
  } else {
164
160
  expect(icons).toHaveLength(1)
165
161
  }
166
-
167
- // Cleanup for next iteration
168
- container.remove()
169
162
  }
170
163
  })
171
164
 
@@ -173,17 +166,13 @@ describe('PktButton', () => {
173
166
  const colors = ['blue', 'green', 'red', 'yellow'] as const
174
167
 
175
168
  for (const color of colors) {
176
- const container = await createButton(`color="${color}"`)
177
- const pktButton = container.querySelector('pkt-button') as PktButton
178
- await pktButton.updateComplete
169
+ const { button } = await createButtonTest({ color, content: 'Test Button' })
170
+ await button.updateComplete
179
171
 
180
- expect(pktButton.color).toBe(color)
172
+ expect(button.color).toBe(color)
181
173
 
182
- const button = pktButton.querySelector('button')
183
- expect(button).toHaveClass(`pkt-btn--${color}`)
184
-
185
- // Cleanup for next iteration
186
- container.remove()
174
+ const buttonEl = button.querySelector('button')
175
+ expect(buttonEl).toHaveClass(`pkt-btn--${color}`)
187
176
  }
188
177
  })
189
178
 
@@ -191,46 +180,46 @@ describe('PktButton', () => {
191
180
  const types = ['button', 'submit', 'reset'] as const
192
181
 
193
182
  for (const type of types) {
194
- const container = await createButton(`type="${type}"`)
195
- const pktButton = container.querySelector('pkt-button') as PktButton
196
- await pktButton.updateComplete
197
-
198
- expect(pktButton.type).toBe(type)
183
+ const { button } = await createButtonTest({ type, content: 'Test Button' })
184
+ await button.updateComplete
199
185
 
200
- const button = pktButton.querySelector('button')
201
- expect(button?.getAttribute('type')).toBe(type)
186
+ expect(button.type).toBe(type)
202
187
 
203
- // Cleanup for next iteration
204
- container.remove()
188
+ const buttonEl = button.querySelector('button')
189
+ expect(buttonEl?.getAttribute('type')).toBe(type)
205
190
  }
206
191
  })
207
192
 
208
193
  test('handles icon properties correctly', async () => {
209
- const container = await createButton('variant="icon-left" icon-name="user"')
210
-
211
- const pktButton = container.querySelector('pkt-button') as PktButton
212
- await pktButton.updateComplete
194
+ const { button } = await createButtonTest({
195
+ variant: 'icon-left',
196
+ iconName: 'user',
197
+ content: 'Test Button',
198
+ })
199
+ await button.updateComplete
213
200
 
214
- expect(pktButton.iconName).toBe('user')
201
+ expect(button.iconName).toBe('user')
215
202
 
216
- const icon = pktButton.querySelector('pkt-icon:not(.pkt-btn__spinner)')
203
+ const icon = button.querySelector('pkt-icon:not(.pkt-btn__spinner)')
217
204
  expect(icon?.getAttribute('name')).toBe('user')
218
205
  expect(icon).toHaveClass('pkt-btn__icon')
219
206
  })
220
207
 
221
208
  test('handles second icon for icons-right-and-left variant', async () => {
222
- const container = await createButton('variant="icons-right-and-left"')
223
- const pktButton = container.querySelector('pkt-button') as PktButton
209
+ const { button } = await createButtonTest({
210
+ variant: 'icons-right-and-left',
211
+ content: 'Test Button',
212
+ })
224
213
 
225
214
  // Set both icon names as properties
226
- pktButton.iconName = 'home'
227
- pktButton.secondIconName = 'star'
228
- await pktButton.updateComplete
215
+ button.iconName = 'home'
216
+ button.secondIconName = 'star'
217
+ await button.updateComplete
229
218
 
230
- expect(pktButton.iconName).toBe('home')
231
- expect(pktButton.secondIconName).toBe('star')
219
+ expect(button.iconName).toBe('home')
220
+ expect(button.secondIconName).toBe('star')
232
221
 
233
- const icons = pktButton.querySelectorAll('pkt-icon:not(.pkt-btn__spinner)')
222
+ const icons = button.querySelectorAll('pkt-icon:not(.pkt-btn__spinner)')
234
223
  expect(icons).toHaveLength(2)
235
224
  expect(icons[0]?.getAttribute('name')).toBe('home')
236
225
  expect(icons[1]?.getAttribute('name')).toBe('star')
@@ -239,190 +228,175 @@ describe('PktButton', () => {
239
228
 
240
229
  describe('Disabled state', () => {
241
230
  test('handles disabled property correctly', async () => {
242
- const container = await createButton('disabled')
231
+ const { button } = await createButtonTest({ disabled: true, content: 'Test Button' })
232
+ await button.updateComplete
243
233
 
244
- const pktButton = container.querySelector('pkt-button') as PktButton
245
- await pktButton.updateComplete
234
+ expect(button.disabled).toBe(true)
246
235
 
247
- expect(pktButton.disabled).toBe(true)
248
-
249
- const button = pktButton.querySelector('button')
250
- expect(button).toHaveClass('pkt-btn--disabled')
251
- expect(button?.hasAttribute('disabled')).toBe(true)
252
- expect(button?.getAttribute('aria-disabled')).toBe('true')
236
+ const buttonEl = button.querySelector('button')
237
+ expect(buttonEl).toHaveClass('pkt-btn--disabled')
238
+ expect(buttonEl?.hasAttribute('disabled')).toBe(true)
239
+ expect(buttonEl?.getAttribute('aria-disabled')).toBe('true')
253
240
  })
254
241
 
255
242
  test('prevents click events when disabled', async () => {
256
- const container = await createButton('disabled')
243
+ const { button } = await createButtonTest({ disabled: true, content: 'Test Button' })
257
244
  const clickSpy = jest.fn()
258
245
 
259
- const pktButton = container.querySelector('pkt-button') as PktButton
260
- await pktButton.updateComplete
246
+ await button.updateComplete
261
247
 
262
- pktButton.addEventListener('click', clickSpy)
248
+ button.addEventListener('click', clickSpy)
263
249
 
264
- const button = pktButton.querySelector('button')
265
- fireEvent.click(button!)
250
+ const buttonEl = button.querySelector('button')
251
+ fireEvent.click(buttonEl!)
266
252
 
267
253
  expect(clickSpy).not.toHaveBeenCalled()
268
254
  })
269
255
 
270
256
  test('prevents keyboard events when disabled', async () => {
271
- const container = await createButton('disabled')
257
+ const { button } = await createButtonTest({ disabled: true, content: 'Test Button' })
272
258
  const clickSpy = jest.fn()
273
259
 
274
- const pktButton = container.querySelector('pkt-button') as PktButton
275
- await pktButton.updateComplete
260
+ await button.updateComplete
276
261
 
277
- pktButton.addEventListener('click', clickSpy)
262
+ button.addEventListener('click', clickSpy)
278
263
 
279
- const button = pktButton.querySelector('button')
280
- fireEvent.keyDown(button!, { key: 'Enter' })
281
- fireEvent.keyDown(button!, { key: ' ' })
264
+ const buttonEl = button.querySelector('button')
265
+ fireEvent.keyDown(buttonEl!, { key: 'Enter' })
266
+ fireEvent.keyDown(buttonEl!, { key: ' ' })
282
267
 
283
268
  expect(clickSpy).not.toHaveBeenCalled()
284
269
  })
285
270
 
286
271
  test('converts string "false" to boolean false for disabled', async () => {
287
- const container = await createButton('disabled="false"')
288
-
289
- const pktButton = container.querySelector('pkt-button') as PktButton
290
- await pktButton.updateComplete
272
+ const { button } = await createButtonTest({ disabled: false, content: 'Test Button' })
273
+ await button.updateComplete
291
274
 
292
- expect(pktButton.disabled).toBe(false)
275
+ expect(button.disabled).toBe(false)
293
276
 
294
- const button = pktButton.querySelector('button')
295
- expect(button).not.toHaveClass('pkt-btn--disabled')
296
- expect(button?.hasAttribute('disabled')).toBe(false)
277
+ const buttonEl = button.querySelector('button')
278
+ expect(buttonEl).not.toHaveClass('pkt-btn--disabled')
279
+ expect(buttonEl?.hasAttribute('disabled')).toBe(false)
297
280
  })
298
281
  })
299
282
 
300
283
  describe('Loading state', () => {
301
284
  test('handles isLoading property correctly', async () => {
302
- const container = await createButton()
303
- const pktButton = container.querySelector('pkt-button') as PktButton
285
+ const { button } = await createButtonTest({ content: 'Test Button' })
304
286
 
305
287
  // Set isLoading as a property
306
- pktButton.isLoading = true
307
- await pktButton.updateComplete
288
+ button.isLoading = true
289
+ await button.updateComplete
308
290
 
309
- expect(pktButton.isLoading).toBe(true)
291
+ expect(button.isLoading).toBe(true)
310
292
 
311
- const button = pktButton.querySelector('button')
312
- expect(button).toHaveClass('pkt-btn--isLoading')
313
- expect(button?.getAttribute('aria-busy')).toBe('true')
314
- expect(button?.getAttribute('aria-disabled')).toBe('true')
293
+ const buttonEl = button.querySelector('button')
294
+ expect(buttonEl).toHaveClass('pkt-btn--isLoading')
295
+ expect(buttonEl?.getAttribute('aria-busy')).toBe('true')
296
+ expect(buttonEl?.getAttribute('aria-disabled')).toBe('true')
315
297
  })
316
298
 
317
299
  test('renders loading spinner when isLoading is true', async () => {
318
- const container = await createButton()
319
- const pktButton = container.querySelector('pkt-button') as PktButton
300
+ const { button } = await createButtonTest({ content: 'Test Button' })
320
301
 
321
302
  // Set isLoading as a property
322
- pktButton.isLoading = true
323
- await pktButton.updateComplete
303
+ button.isLoading = true
304
+ await button.updateComplete
324
305
 
325
- const spinner = pktButton.querySelector('.pkt-btn__spinner')
306
+ const spinner = button.querySelector('.pkt-btn__spinner')
326
307
  expect(spinner).toBeInTheDocument()
327
308
  expect(spinner?.getAttribute('name')).toBe('spinner-blue')
328
309
  })
329
310
 
330
311
  test('prevents click events when loading', async () => {
331
- const container = await createButton()
312
+ const { button } = await createButtonTest({ content: 'Test Button' })
332
313
  const clickSpy = jest.fn()
333
314
 
334
- const pktButton = container.querySelector('pkt-button') as PktButton
335
-
336
315
  // Set isLoading as a property
337
- pktButton.isLoading = true
338
- await pktButton.updateComplete
316
+ button.isLoading = true
317
+ await button.updateComplete
339
318
 
340
- pktButton.addEventListener('click', clickSpy)
319
+ button.addEventListener('click', clickSpy)
341
320
 
342
- const button = pktButton.querySelector('button')
343
- fireEvent.click(button!)
321
+ const buttonEl = button.querySelector('button')
322
+ fireEvent.click(buttonEl!)
344
323
 
345
324
  expect(clickSpy).not.toHaveBeenCalled()
346
325
  })
347
326
 
348
327
  test('uses custom loading animation path', async () => {
349
328
  const customPath = 'https://custom.example.com/animations/'
350
- const container = await createButton('isLoading')
351
- const pktButton = container.querySelector('pkt-button') as PktButton
329
+ const { button } = await createButtonTest({ isLoading: true, content: 'Test Button' })
352
330
 
353
- pktButton.loadingAnimationPath = customPath
354
- await pktButton.updateComplete
331
+ button.loadingAnimationPath = customPath
332
+ await button.updateComplete
355
333
 
356
- expect(pktButton.loadingAnimationPath).toBe(customPath)
334
+ expect(button.loadingAnimationPath).toBe(customPath)
357
335
 
358
- const spinner = pktButton.querySelector('.pkt-btn__spinner')
336
+ const spinner = button.querySelector('.pkt-btn__spinner')
359
337
  expect(spinner?.getAttribute('path')).toBe(customPath)
360
338
  })
361
339
 
362
340
  test('converts string "false" to boolean false for isLoading', async () => {
363
- const container = await createButton('isLoading="false"')
364
-
365
- const pktButton = container.querySelector('pkt-button') as PktButton
366
- await pktButton.updateComplete
341
+ const { button } = await createButtonTest({ isLoading: false, content: 'Test Button' })
342
+ await button.updateComplete
367
343
 
368
- expect(pktButton.isLoading).toBe(false)
344
+ expect(button.isLoading).toBe(false)
369
345
 
370
- const button = pktButton.querySelector('button')
371
- expect(button).not.toHaveClass('pkt-btn--isLoading')
346
+ const buttonEl = button.querySelector('button')
347
+ expect(buttonEl).not.toHaveClass('pkt-btn--isLoading')
372
348
  })
373
349
  })
374
350
 
375
351
  describe('Form integration', () => {
376
352
  test('handles form attribute correctly', async () => {
377
- const container = await createButton('form="test-form" type="submit"')
353
+ const { button } = await createButtonTest({
354
+ form: 'test-form',
355
+ type: 'submit',
356
+ content: 'Test Button',
357
+ })
358
+ await button.updateComplete
378
359
 
379
- const pktButton = container.querySelector('pkt-button') as PktButton
380
- await pktButton.updateComplete
360
+ expect(button.form).toBe('test-form')
381
361
 
382
- expect(pktButton.form).toBe('test-form')
383
-
384
- const button = pktButton.querySelector('button')
385
- expect(button?.getAttribute('form')).toBe('test-form')
362
+ const buttonEl = button.querySelector('button')
363
+ expect(buttonEl?.getAttribute('form')).toBe('test-form')
386
364
  })
387
365
 
388
366
  test('works as submit button', async () => {
389
- const container = await createButton('type="submit"')
390
-
391
- const pktButton = container.querySelector('pkt-button') as PktButton
392
- await pktButton.updateComplete
367
+ const { button } = await createButtonTest({ type: 'submit', content: 'Test Button' })
368
+ await button.updateComplete
393
369
 
394
- const button = pktButton.querySelector('button')
395
- expect(button?.getAttribute('type')).toBe('submit')
370
+ const buttonEl = button.querySelector('button')
371
+ expect(buttonEl?.getAttribute('type')).toBe('submit')
396
372
  })
397
373
  })
398
374
 
399
375
  describe('Click functionality', () => {
400
376
  test('allows click events when not disabled or loading', async () => {
401
- const container = await createButton()
377
+ const { button } = await createButtonTest({ content: 'Test Button' })
402
378
  const clickSpy = jest.fn()
403
379
 
404
- const pktButton = container.querySelector('pkt-button') as PktButton
405
- await pktButton.updateComplete
380
+ await button.updateComplete
406
381
 
407
- pktButton.addEventListener('click', clickSpy)
382
+ button.addEventListener('click', clickSpy)
408
383
 
409
- const button = pktButton.querySelector('button')
410
- fireEvent.click(button!)
384
+ const buttonEl = button.querySelector('button')
385
+ fireEvent.click(buttonEl!)
411
386
 
412
387
  expect(clickSpy).toHaveBeenCalledTimes(1)
413
388
  })
414
389
 
415
390
  test('allows keyboard activation when not disabled or loading', async () => {
416
- const container = await createButton()
391
+ const { button } = await createButtonTest({ content: 'Test Button' })
417
392
  const clickSpy = jest.fn()
418
393
 
419
- const pktButton = container.querySelector('pkt-button') as PktButton
420
- await pktButton.updateComplete
394
+ await button.updateComplete
421
395
 
422
- pktButton.addEventListener('click', clickSpy)
396
+ button.addEventListener('click', clickSpy)
423
397
 
424
- const button = pktButton.querySelector('button')
425
- fireEvent.keyDown(button!, { key: 'Enter' })
398
+ const buttonEl = button.querySelector('button')
399
+ fireEvent.keyDown(buttonEl!, { key: 'Enter' })
426
400
 
427
401
  // Note: Native button handles Enter key, so we just test that events aren't prevented
428
402
  // The actual click event would be triggered by the browser
@@ -431,81 +405,69 @@ describe('PktButton', () => {
431
405
 
432
406
  describe('Accessibility', () => {
433
407
  test('has correct ARIA attributes', async () => {
434
- const container = await createButton('disabled')
435
- const pktButton = container.querySelector('pkt-button') as PktButton
408
+ const { button } = await createButtonTest({ disabled: true, content: 'Test Button' })
436
409
 
437
410
  // Set isLoading as a property
438
- pktButton.isLoading = true
439
- await pktButton.updateComplete
411
+ button.isLoading = true
412
+ await button.updateComplete
440
413
 
441
- const button = pktButton.querySelector('button')
414
+ const buttonEl = button.querySelector('button')
442
415
 
443
- expect(button?.getAttribute('aria-disabled')).toBe('true')
444
- expect(button?.getAttribute('aria-busy')).toBe('true')
445
- expect(button?.hasAttribute('disabled')).toBe(true)
416
+ expect(buttonEl?.getAttribute('aria-disabled')).toBe('true')
417
+ expect(buttonEl?.getAttribute('aria-busy')).toBe('true')
418
+ expect(buttonEl?.hasAttribute('disabled')).toBe(true)
446
419
  })
447
420
 
448
421
  test('provides semantic button structure', async () => {
449
- const container = await createButton()
450
-
451
- const pktButton = container.querySelector('pkt-button') as PktButton
452
- await pktButton.updateComplete
422
+ const { button } = await createButtonTest({ content: 'Test Button' })
423
+ await button.updateComplete
453
424
 
454
- const button = pktButton.querySelector('button')
425
+ const buttonEl = button.querySelector('button')
455
426
 
456
- expect(button).toBeInTheDocument()
457
- expect(button?.tagName.toLowerCase()).toBe('button')
458
- expect(button?.getAttribute('type')).toBe('button')
427
+ expect(buttonEl).toBeInTheDocument()
428
+ expect(buttonEl?.tagName.toLowerCase()).toBe('button')
429
+ expect(buttonEl?.getAttribute('type')).toBe('button')
459
430
  })
460
431
 
461
432
  test('renders with no WCAG errors with axe - default button', async () => {
462
- const container = await createButton('', 'Click me')
463
-
464
- const pktButton = container.querySelector('pkt-button') as PktButton
465
- await pktButton.updateComplete
433
+ const { container } = await createButtonTest({ content: 'Click me' })
466
434
 
467
435
  const results = await axe(container)
468
436
  expect(results).toHaveNoViolations()
469
437
  })
470
438
 
471
439
  test('renders with no WCAG errors with axe - icon button', async () => {
472
- const container = await createButton(
473
- 'variant="icon-left" icon-name="user" skin="secondary"',
474
- 'User Profile',
475
- )
476
-
477
- const pktButton = container.querySelector('pkt-button') as PktButton
478
- await pktButton.updateComplete
440
+ const { container } = await createButtonTest({
441
+ variant: 'icon-left',
442
+ iconName: 'user',
443
+ skin: 'secondary',
444
+ content: 'User Profile',
445
+ })
479
446
 
480
447
  const results = await axe(container)
481
448
  expect(results).toHaveNoViolations()
482
449
  })
483
450
 
484
451
  test('renders with no WCAG errors with axe - disabled button', async () => {
485
- const container = await createButton('disabled', 'Disabled Button')
486
-
487
- const pktButton = container.querySelector('pkt-button') as PktButton
488
- await pktButton.updateComplete
452
+ const { container } = await createButtonTest({ disabled: true, content: 'Disabled Button' })
489
453
 
490
454
  const results = await axe(container)
491
455
  expect(results).toHaveNoViolations()
492
456
  })
493
457
 
494
458
  test('renders with no WCAG errors with axe - loading button', async () => {
495
- const container = await createButton('isLoading', 'Loading...')
496
-
497
- const pktButton = container.querySelector('pkt-button') as PktButton
498
- await pktButton.updateComplete
459
+ const { container } = await createButtonTest({ isLoading: true, content: 'Loading...' })
499
460
 
500
461
  const results = await axe(container)
501
462
  expect(results).toHaveNoViolations()
502
463
  })
503
464
 
504
465
  test('renders with no WCAG errors with axe - submit button', async () => {
505
- const container = await createButton('type="submit" color="green"', 'Submit Form')
506
-
507
- const pktButton = container.querySelector('pkt-button') as PktButton
508
- await pktButton.updateComplete
466
+ const { container } = await createButtonTest({
467
+ type: 'submit',
468
+ color: 'green',
469
+ content: 'Submit Form',
470
+ })
509
471
 
510
472
  const results = await axe(container)
511
473
  expect(results).toHaveNoViolations()