bard-tag_field 0.5.1 → 0.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.
@@ -0,0 +1,615 @@
1
+ import { expect } from '@esm-bundle/chai'
2
+ import '../src/input-tag.js'
3
+ import {
4
+ setupGlobalTestHooks,
5
+ setupInputTag,
6
+ waitForElement,
7
+ waitForBasicInitialization,
8
+ waitForUpdate,
9
+ simulateInput,
10
+ getTagElements,
11
+ getTagValues
12
+ } from './lib/test-utils.js'
13
+
14
+ describe('Autocomplete', () => {
15
+ setupGlobalTestHooks()
16
+
17
+ describe('Datalist Integration', () => {
18
+ it('should read options from associated datalist', async () => {
19
+ document.body.innerHTML = `
20
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
21
+ <datalist id="suggestions">
22
+ <option value="react">React</option>
23
+ <option value="vue">Vue</option>
24
+ <option value="angular">Angular</option>
25
+ <option value="svelte">Svelte</option>
26
+ </datalist>
27
+ `
28
+ const inputTag = document.querySelector('input-tag')
29
+
30
+ await waitForBasicInitialization(inputTag)
31
+
32
+ expect(inputTag.options).to.deep.equal(['react', 'vue', 'angular', 'svelte'])
33
+ })
34
+
35
+ it('should return empty array when no datalist is associated', async () => {
36
+ const inputTag = await setupInputTag('<input-tag name="tags" multiple></input-tag>')
37
+
38
+ expect(inputTag.options).to.deep.equal([])
39
+ })
40
+
41
+ it('should return empty array when datalist does not exist', async () => {
42
+ const inputTag = await setupInputTag('<input-tag name="tags" list="nonexistent" multiple></input-tag>')
43
+
44
+ expect(inputTag.options).to.deep.equal([])
45
+ })
46
+
47
+ it('should handle empty datalist', async () => {
48
+ document.body.innerHTML = `
49
+ <input-tag name="tags" list="empty" multiple></input-tag>
50
+ <datalist id="empty"></datalist>
51
+ `
52
+ const inputTag = document.querySelector('input-tag')
53
+
54
+ await waitForBasicInitialization(inputTag)
55
+
56
+ expect(inputTag.options).to.deep.equal([])
57
+ })
58
+
59
+ it('should update options when datalist changes', async () => {
60
+ document.body.innerHTML = `
61
+ <input-tag name="frameworks" list="dynamic" multiple></input-tag>
62
+ <datalist id="dynamic">
63
+ <option value="initial">Initial</option>
64
+ </datalist>
65
+ `
66
+ const inputTag = document.querySelector('input-tag')
67
+ const datalist = document.querySelector('#dynamic')
68
+
69
+ await waitForBasicInitialization(inputTag)
70
+
71
+ expect(inputTag.options).to.deep.equal(['initial'])
72
+
73
+ // Add option to datalist
74
+ const newOption = document.createElement('option')
75
+ newOption.value = 'added'
76
+ datalist.appendChild(newOption)
77
+
78
+ expect(inputTag.options).to.deep.equal(['initial', 'added'])
79
+ })
80
+
81
+ it('should handle datalist with option text different from value', async () => {
82
+ document.body.innerHTML = `
83
+ <input-tag name="languages" list="lang-list" multiple></input-tag>
84
+ <datalist id="lang-list">
85
+ <option value="js">JavaScript</option>
86
+ <option value="ts">TypeScript</option>
87
+ <option value="py">Python</option>
88
+ </datalist>
89
+ `
90
+ const inputTag = document.querySelector('input-tag')
91
+
92
+ await waitForBasicInitialization(inputTag)
93
+
94
+ expect(inputTag.options).to.deep.equal(['js', 'ts', 'py'])
95
+ })
96
+ })
97
+
98
+ describe('Autocomplete Suggestions Filtering', () => {
99
+ async function setupAutocompleteTest() {
100
+ document.body.innerHTML = `
101
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
102
+ <datalist id="suggestions">
103
+ <option value="react">React</option>
104
+ <option value="vue">Vue</option>
105
+ <option value="angular">Angular</option>
106
+ <option value="svelte">Svelte</option>
107
+ <option value="backbone">Backbone</option>
108
+ </datalist>
109
+ `
110
+ const inputTag = document.querySelector('input-tag')
111
+ await waitForBasicInitialization(inputTag)
112
+ return inputTag
113
+ }
114
+
115
+ it('should filter suggestions based on input text', async () => {
116
+ const inputTag = await setupAutocompleteTest()
117
+ const input = inputTag._taggleInputTarget
118
+
119
+ // Test 're' shows only 'React' (label)
120
+ await simulateInput(input, 're')
121
+ expect(inputTag._autocompleteSuggestions).to.deep.equal(['React'])
122
+
123
+ // Test 'e' shows multiple matches (labels)
124
+ await simulateInput(input, 'e')
125
+ expect(inputTag._autocompleteSuggestions).to.include.members(['React', 'Vue', 'Svelte', 'Backbone'])
126
+
127
+ // Test 'ang' shows only 'Angular' (label)
128
+ await simulateInput(input, 'ang')
129
+ expect(inputTag._autocompleteSuggestions).to.deep.equal(['Angular'])
130
+
131
+ // Test 'xyz' shows no matches
132
+ await simulateInput(input, 'xyz')
133
+ expect(inputTag._autocompleteSuggestions).to.have.length(0)
134
+ })
135
+
136
+ it('should handle case-insensitive filtering', async () => {
137
+ const inputTag = await setupAutocompleteTest()
138
+ const input = inputTag._taggleInputTarget
139
+
140
+ // Test uppercase 'REACT' shows 'React' (label)
141
+ await simulateInput(input, 'REACT')
142
+ expect(inputTag._autocompleteSuggestions).to.deep.equal(['React'])
143
+
144
+ // Test mixed case 'VuE' shows 'Vue' (label)
145
+ await simulateInput(input, 'VuE')
146
+ expect(inputTag._autocompleteSuggestions).to.deep.equal(['Vue'])
147
+ })
148
+
149
+ it('should filter with partial matches', async () => {
150
+ const inputTag = await setupAutocompleteTest()
151
+ const input = inputTag._taggleInputTarget
152
+
153
+ // Test 'a' shows tags containing 'a' (labels)
154
+ await simulateInput(input, 'a')
155
+ expect(inputTag._autocompleteSuggestions).to.include.members(['React', 'Angular', 'Backbone'])
156
+
157
+ // Test 'ck' shows only 'Backbone' (label)
158
+ await simulateInput(input, 'ck')
159
+ expect(inputTag._autocompleteSuggestions).to.deep.equal(['Backbone'])
160
+ })
161
+
162
+ it('should exclude already-entered tags from autocomplete suggestions', async () => {
163
+ const inputTag = await setupAutocompleteTest()
164
+ const input = inputTag._taggleInputTarget
165
+
166
+ // Add some existing tags
167
+ inputTag.add('react')
168
+ inputTag.add('vue')
169
+ await waitForUpdate()
170
+
171
+ expect(getTagValues(inputTag)).to.deep.equal(['react', 'vue'])
172
+
173
+ // Type 'e' which should trigger autocomplete
174
+ await simulateInput(input, 'e')
175
+
176
+ // Should show 'Svelte' and 'Backbone' (labels) but NOT 'React' or 'Vue'
177
+ expect(inputTag._autocompleteSuggestions).to.include('Svelte')
178
+ expect(inputTag._autocompleteSuggestions).to.include('Backbone')
179
+ expect(inputTag._autocompleteSuggestions).to.not.include('React')
180
+ expect(inputTag._autocompleteSuggestions).to.not.include('Vue')
181
+ })
182
+ })
183
+
184
+ describe('Autocomplete Selection Behavior', () => {
185
+ it('should add selected suggestion as tag', async () => {
186
+ document.body.innerHTML = `
187
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
188
+ <datalist id="suggestions">
189
+ <option value="react">React</option>
190
+ <option value="vue">Vue</option>
191
+ </datalist>
192
+ `
193
+ const inputTag = document.querySelector('input-tag')
194
+
195
+ await waitForElement(inputTag, '_taggle')
196
+
197
+ // Simulate selecting a suggestion (direct taggle.add simulates the autocomplete selection)
198
+ inputTag.add('react')
199
+ await waitForUpdate()
200
+
201
+ expect(getTagElements(inputTag)).to.have.length(1)
202
+ expect(getTagValues(inputTag)).to.deep.equal(['react'])
203
+ })
204
+
205
+ it('should clear input after selection', async () => {
206
+ document.body.innerHTML = `
207
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
208
+ <datalist id="suggestions">
209
+ <option value="react">React</option>
210
+ </datalist>
211
+ `
212
+ const inputTag = document.querySelector('input-tag')
213
+
214
+ await waitForElement(inputTag, '_taggle')
215
+
216
+ const input = inputTag._taggleInputTarget
217
+ await simulateInput(input, 'react')
218
+
219
+ // Simulate autocomplete selection
220
+ inputTag.add('react')
221
+ await waitForUpdate()
222
+
223
+ expect(input.value).to.equal('')
224
+ })
225
+
226
+ it('should handle multiple autocomplete selections', async () => {
227
+ document.body.innerHTML = `
228
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
229
+ <datalist id="suggestions">
230
+ <option value="react">React</option>
231
+ <option value="vue">Vue</option>
232
+ <option value="angular">Angular</option>
233
+ </datalist>
234
+ `
235
+ const inputTag = document.querySelector('input-tag')
236
+
237
+ await waitForElement(inputTag, '_taggle')
238
+
239
+ // Simulate multiple selections
240
+ inputTag.add('react')
241
+ await waitForUpdate()
242
+ inputTag.add('vue')
243
+ await waitForUpdate()
244
+ inputTag.add('angular')
245
+ await waitForUpdate()
246
+
247
+ expect(getTagElements(inputTag)).to.have.length(3)
248
+ expect(getTagValues(inputTag)).to.deep.equal(['react', 'vue', 'angular'])
249
+ })
250
+ })
251
+
252
+ describe('Multiple Datalist Scenarios', () => {
253
+ it('should handle switching datalist association', async () => {
254
+ document.body.innerHTML = `
255
+ <input-tag name="items" list="list1" multiple></input-tag>
256
+ <datalist id="list1">
257
+ <option value="item1">Item 1</option>
258
+ <option value="item2">Item 2</option>
259
+ </datalist>
260
+ <datalist id="list2">
261
+ <option value="item3">Item 3</option>
262
+ <option value="item4">Item 4</option>
263
+ </datalist>
264
+ `
265
+ const inputTag = document.querySelector('input-tag')
266
+
267
+ await waitForBasicInitialization(inputTag)
268
+
269
+ expect(inputTag.options).to.deep.equal(['item1', 'item2'])
270
+
271
+ // Switch to different datalist
272
+ inputTag.setAttribute('list', 'list2')
273
+
274
+ expect(inputTag.options).to.deep.equal(['item3', 'item4'])
275
+ })
276
+
277
+ it('should handle removing datalist association', async () => {
278
+ document.body.innerHTML = `
279
+ <input-tag name="items" list="suggestions" multiple></input-tag>
280
+ <datalist id="suggestions">
281
+ <option value="item1">Item 1</option>
282
+ </datalist>
283
+ `
284
+ const inputTag = document.querySelector('input-tag')
285
+
286
+ await waitForBasicInitialization(inputTag)
287
+
288
+ expect(inputTag.options).to.deep.equal(['item1'])
289
+
290
+ // Remove list attribute
291
+ inputTag.removeAttribute('list')
292
+
293
+ expect(inputTag.options).to.deep.equal([])
294
+ })
295
+
296
+ it('should handle multiple input-tags sharing same datalist', async () => {
297
+ document.body.innerHTML = `
298
+ <input-tag name="tags1" list="shared" multiple></input-tag>
299
+ <input-tag name="tags2" list="shared" multiple></input-tag>
300
+ <datalist id="shared">
301
+ <option value="shared1">Shared 1</option>
302
+ <option value="shared2">Shared 2</option>
303
+ </datalist>
304
+ `
305
+ const inputTag1 = document.querySelector('input-tag[name="tags1"]')
306
+ const inputTag2 = document.querySelector('input-tag[name="tags2"]')
307
+
308
+ await waitForElement(inputTag1, '_taggle')
309
+ await waitForElement(inputTag2, '_taggle')
310
+
311
+ expect(inputTag1.options).to.deep.equal(['shared1', 'shared2'])
312
+ expect(inputTag2.options).to.deep.equal(['shared1', 'shared2'])
313
+
314
+ // They should work independently
315
+ inputTag1.add('shared1')
316
+ await waitForUpdate()
317
+
318
+ expect(getTagValues(inputTag1)).to.deep.equal(['shared1'])
319
+ expect(getTagValues(inputTag2)).to.deep.equal([])
320
+ })
321
+ })
322
+
323
+ describe('Autocomplete UI Interaction', () => {
324
+ it('should have autocomplete container in DOM', async () => {
325
+ const inputTag = await setupInputTag('<input-tag name="tags" multiple></input-tag>')
326
+
327
+ expect(inputTag.autocompleteContainerTarget).to.not.be.null
328
+ expect(inputTag.autocompleteContainerTarget.tagName.toLowerCase()).to.equal('ul')
329
+ })
330
+
331
+ it('should position autocomplete correctly when input-tag wraps to multiple lines', async () => {
332
+ document.body.innerHTML = `
333
+ <div style="width: 200px;">
334
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
335
+ <datalist id="suggestions">
336
+ <option value="react">React</option>
337
+ <option value="vue">Vue</option>
338
+ <option value="angular">Angular</option>
339
+ </datalist>
340
+ </div>
341
+ `
342
+ const inputTag = document.querySelector('input-tag')
343
+ await waitForBasicInitialization(inputTag)
344
+ const input = inputTag._taggleInputTarget
345
+
346
+ // Add enough tags to force wrapping
347
+ inputTag.add('very-long-tag-name-that-will-wrap')
348
+ inputTag.add('another-very-long-tag-name')
349
+ inputTag.add('yet-another-long-tag')
350
+ await waitForUpdate()
351
+
352
+ // Get the container height after tags are added
353
+ const containerHeight = inputTag.containerTarget.getBoundingClientRect().height
354
+
355
+ // Trigger autocomplete
356
+ await simulateInput(input, 'r')
357
+
358
+ // Check that autocomplete container is positioned correctly
359
+ const autocompleteContainer = inputTag.autocompleteContainerTarget
360
+ const computedStyle = window.getComputedStyle(autocompleteContainer)
361
+
362
+ expect(computedStyle.position).to.equal('absolute')
363
+ expect(computedStyle.top).to.equal(`${containerHeight}px`)
364
+ expect(computedStyle.zIndex).to.equal('1000')
365
+ })
366
+
367
+ it('should dynamically reposition autocomplete when tags are added while open', async () => {
368
+ document.body.innerHTML = `
369
+ <div style="width: 200px;">
370
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
371
+ <datalist id="suggestions">
372
+ <option value="react">React</option>
373
+ <option value="vue">Vue</option>
374
+ <option value="angular">Angular</option>
375
+ </datalist>
376
+ </div>
377
+ `
378
+ const inputTag = document.querySelector('input-tag')
379
+ await waitForBasicInitialization(inputTag)
380
+ const input = inputTag._taggleInputTarget
381
+
382
+ // Get initial container height
383
+ const initialHeight = inputTag.containerTarget.getBoundingClientRect().height
384
+
385
+ // Open autocomplete
386
+ await simulateInput(input, 'r')
387
+
388
+ // Get initial autocomplete position
389
+ const autocompleteContainer = inputTag.autocompleteContainerTarget
390
+ let computedStyle = window.getComputedStyle(autocompleteContainer)
391
+ expect(computedStyle.top).to.equal(`${initialHeight}px`)
392
+
393
+ // Add a tag while autocomplete is open
394
+ inputTag.add('very-long-tag-name-that-will-cause-wrapping')
395
+ await waitForUpdate()
396
+
397
+ // Wait for position update
398
+ await new Promise(resolve => setTimeout(resolve, 10))
399
+
400
+ // Get new container height and verify autocomplete repositioned
401
+ const newHeight = inputTag.containerTarget.getBoundingClientRect().height
402
+ computedStyle = window.getComputedStyle(autocompleteContainer)
403
+
404
+ expect(newHeight).to.be.greaterThan(initialHeight)
405
+ expect(computedStyle.top).to.equal(`${newHeight}px`)
406
+ })
407
+
408
+ xit('should position autocomplete container after button', async () => {
409
+ const inputTag = await setupInputTag('<input-tag name="tags" multiple></input-tag>')
410
+
411
+ const button = inputTag.buttonTarget
412
+ const autocompleteContainer = inputTag.autocompleteContainerTarget
413
+
414
+ expect(button.nextElementSibling).to.equal(autocompleteContainer)
415
+ })
416
+
417
+ it('should have correct CSS classes on autocomplete elements', async () => {
418
+ document.body.innerHTML = `
419
+ <input-tag name="frameworks" list="suggestions" multiple></input-tag>
420
+ <datalist id="suggestions">
421
+ <option value="react">React</option>
422
+ </datalist>
423
+ `
424
+ const inputTag = document.querySelector('input-tag')
425
+
426
+ await waitForElement(inputTag, '_taggle')
427
+
428
+ const container = inputTag.autocompleteContainerTarget
429
+
430
+ // Check if the autocomplete setup has the right className
431
+ // (This is set in the autocomplete configuration)
432
+ expect(container.tagName.toLowerCase()).to.equal('ul')
433
+ })
434
+ })
435
+
436
+ describe('Missing Datalist Handling', () => {
437
+ it('should gracefully handle missing datalist element', async () => {
438
+ const inputTag = await setupInputTag('<input-tag name="tags" list="missing" multiple></input-tag>')
439
+
440
+ expect(inputTag.options).to.deep.equal([])
441
+
442
+ // Should still work for adding tags manually
443
+ inputTag.add('manual-tag')
444
+ await waitForUpdate()
445
+
446
+ expect(getTagElements(inputTag)).to.have.length(1)
447
+ expect(getTagValues(inputTag)).to.deep.equal(['manual-tag'])
448
+ })
449
+
450
+ it('should handle datalist that gets removed from DOM', async () => {
451
+ document.body.innerHTML = `
452
+ <input-tag name="tags" list="temporary" multiple></input-tag>
453
+ <datalist id="temporary">
454
+ <option value="temp">Temporary</option>
455
+ </datalist>
456
+ `
457
+ const inputTag = document.querySelector('input-tag')
458
+ const datalist = document.querySelector('#temporary')
459
+
460
+ await waitForBasicInitialization(inputTag)
461
+
462
+ expect(inputTag.options).to.deep.equal(['temp'])
463
+
464
+ // Remove datalist from DOM
465
+ datalist.remove()
466
+
467
+ expect(inputTag.options).to.deep.equal([])
468
+ })
469
+
470
+ it('should handle datalist that gets added to DOM after initialization', async () => {
471
+ const inputTag = await setupInputTag('<input-tag name="tags" list="future" multiple></input-tag>')
472
+
473
+ expect(inputTag.options).to.deep.equal([])
474
+
475
+ // Add datalist to DOM
476
+ const datalist = document.createElement('datalist')
477
+ datalist.id = 'future'
478
+ const option = document.createElement('option')
479
+ option.value = 'future-option'
480
+ datalist.appendChild(option)
481
+ document.body.appendChild(datalist)
482
+
483
+ expect(inputTag.options).to.deep.equal(['future-option'])
484
+ })
485
+ })
486
+
487
+ describe('Autocomplete with Pre-existing Tags', () => {
488
+ it('should work with pre-existing tags and autocomplete', async () => {
489
+ document.body.innerHTML = `
490
+ <input-tag name="frameworks" list="suggestions" multiple>
491
+ <tag-option value="react">React</tag-option>
492
+ </input-tag>
493
+ <datalist id="suggestions">
494
+ <option value="react">React</option>
495
+ <option value="vue">Vue</option>
496
+ <option value="angular">Angular</option>
497
+ </datalist>
498
+ `
499
+ const inputTag = document.querySelector('input-tag')
500
+
501
+ await waitForElement(inputTag, '_taggle')
502
+
503
+ expect(getTagValues(inputTag)).to.deep.equal(['react'])
504
+ expect(inputTag.options).to.deep.equal(['react', 'vue', 'angular'])
505
+
506
+ // Should be able to add more from autocomplete
507
+ inputTag.add('vue')
508
+ await waitForUpdate()
509
+
510
+ expect(getTagValues(inputTag)).to.deep.equal(['react', 'vue'])
511
+ })
512
+
513
+ it('should identify existing options correctly for isNew flag', async () => {
514
+ document.body.innerHTML = `
515
+ <input-tag name="frameworks" list="suggestions" multiple>
516
+ <tag-option value="existing">Existing</tag-option>
517
+ </input-tag>
518
+ <datalist id="suggestions">
519
+ <option value="existing">Existing</option>
520
+ <option value="from-list">From List</option>
521
+ </datalist>
522
+ `
523
+ const inputTag = document.querySelector('input-tag')
524
+
525
+ await waitForElement(inputTag, '_taggle')
526
+
527
+ let updateEvent = null
528
+ inputTag.addEventListener('update', (e) => {
529
+ updateEvent = e
530
+ })
531
+
532
+ // Add from datalist - should not be new
533
+ inputTag.add('from-list')
534
+ await waitForUpdate()
535
+
536
+ expect(updateEvent.detail.isNew).to.be.false
537
+
538
+ // Add custom tag - should be new
539
+ inputTag.add('custom-tag')
540
+ await waitForUpdate()
541
+
542
+ expect(updateEvent.detail.isNew).to.be.true
543
+ })
544
+ })
545
+
546
+ describe('Autocomplete in Single Mode', () => {
547
+ // Helper to simulate autocomplete selection behavior
548
+ function simulateAutocompleteSelection(inputTag, value, label) {
549
+ // Autocomplete onSelect directly creates and appends tag-option element
550
+ const tagOption = document.createElement('tag-option')
551
+ tagOption.setAttribute('value', value)
552
+ tagOption.textContent = label
553
+ inputTag.appendChild(tagOption)
554
+ inputTag._taggleInputTarget.value = ''
555
+ }
556
+
557
+ it('should hide input after selecting first autocomplete option in single mode', async () => {
558
+ document.body.innerHTML = `
559
+ <input-tag name="status" list="suggestions"></input-tag>
560
+ <datalist id="suggestions">
561
+ <option value="option1">Option 1</option>
562
+ <option value="option2">Option 2</option>
563
+ <option value="option3">Option 3</option>
564
+ </datalist>
565
+ `
566
+ const inputTag = document.querySelector('input-tag')
567
+ await waitForBasicInitialization(inputTag)
568
+
569
+ // Initially, input should be visible (no tags)
570
+ const input = inputTag._taggleInputTarget
571
+ const button = inputTag.buttonTarget
572
+
573
+ expect(input.style.display).to.not.equal('none')
574
+ expect(button.style.display).to.not.equal('none')
575
+
576
+ // Select first option from autocomplete (simulating actual autocomplete behavior)
577
+ simulateAutocompleteSelection(inputTag, 'option1', 'Option 1')
578
+ await waitForUpdate()
579
+
580
+ // Input should now be hidden (single mode with one tag)
581
+ expect(input.style.display).to.equal('none')
582
+ expect(button.style.display).to.equal('none')
583
+ expect(getTagElements(inputTag)).to.have.length(1)
584
+ expect(getTagValues(inputTag)).to.deep.equal(['option1'])
585
+ })
586
+
587
+ it('should prevent adding multiple tags via autocomplete in single mode', async () => {
588
+ document.body.innerHTML = `
589
+ <input-tag name="status" list="suggestions"></input-tag>
590
+ <datalist id="suggestions">
591
+ <option value="option1">Option 1</option>
592
+ <option value="option2">Option 2</option>
593
+ <option value="option3">Option 3</option>
594
+ </datalist>
595
+ `
596
+ const inputTag = document.querySelector('input-tag')
597
+ await waitForBasicInitialization(inputTag)
598
+
599
+ // Select first option (simulating actual autocomplete behavior)
600
+ simulateAutocompleteSelection(inputTag, 'option1', 'Option 1')
601
+ await waitForUpdate()
602
+
603
+ expect(getTagElements(inputTag)).to.have.length(1)
604
+ expect(getTagValues(inputTag)).to.deep.equal(['option1'])
605
+
606
+ // Try to select second option - should fail in single mode
607
+ simulateAutocompleteSelection(inputTag, 'option2', 'Option 2')
608
+ await waitForUpdate()
609
+
610
+ // Should still only have one tag (the first one)
611
+ expect(getTagElements(inputTag)).to.have.length(1)
612
+ expect(getTagValues(inputTag)).to.deep.equal(['option1'])
613
+ })
614
+ })
615
+ })