@@ -443,13 +443,13 @@ describe('AutocompleteController', () => {
443
443
// wait for the MutationObserver to be able to flush
444
444
await shortDelay ( 10 ) ;
445
445
446
- // something external mutations the elements into a different order
447
- selectElement . children [ 1 ] . setAttribute ( 'value' , '2' ) ;
448
- selectElement . children [ 1 ] . innerHTML = 'dog2' ;
449
- selectElement . children [ 2 ] . setAttribute ( 'value' , '3' ) ;
450
- selectElement . children [ 2 ] . innerHTML = ' dog3' ;
451
- selectElement . children [ 3 ] . setAttribute ( 'value' , '1' ) ;
452
- selectElement . children [ 3 ] . innerHTML = 'dog1' ;
446
+ // something external sets new HTML, with a different order
447
+ selectElement . innerHTML = `
448
+ <option value="">Select a dog</option>
449
+ <option value="2">dog2</option>
450
+ <option value="3"> dog3</option>
451
+ <option value="1">dog1</option>
452
+ ` ;
453
453
454
454
// wait for the MutationObserver to flush these changes
455
455
await shortDelay ( 10 ) ;
@@ -488,26 +488,20 @@ describe('AutocompleteController', () => {
488
488
await shortDelay ( 10 ) ;
489
489
490
490
// TomSelect will move the "2" option out of its optgroup and onto the bottom
491
- // let's imitate an Ajax call reversing that
492
- const selectedOption2 = selectElement . children [ 3 ] ;
493
- if ( ! ( selectedOption2 instanceof HTMLOptionElement ) ) {
494
- throw new Error ( 'cannot find option 3' ) ;
495
- }
496
- const smallDogGroup = selectElement . children [ 1 ] ;
497
- if ( ! ( smallDogGroup instanceof HTMLOptGroupElement ) ) {
498
- throw new Error ( 'cannot find small dog group' ) ;
499
- }
500
-
501
- // add a new element, which is really just the old dog2
502
- const newOption2 = document . createElement ( 'option' ) ;
503
- newOption2 . setAttribute ( 'value' , '2' ) ;
504
- newOption2 . innerHTML = 'dog2' ;
505
- // but the new HTML will correctly mark this as selected
506
- newOption2 . setAttribute ( 'selected' , '' ) ;
507
- smallDogGroup . appendChild ( newOption2 ) ;
508
-
509
- // remove the dog2 element from the bottom
510
- selectElement . removeChild ( selectedOption2 ) ;
491
+ // let's imitate an Ajax call reversing that order
492
+ selectElement . innerHTML = `
493
+ <option value="">Select a dog</option>
494
+ <optgroup label="big dogs">
495
+ <option value="4">dog4</option>
496
+ <option value="5">dog5</option>
497
+ <option value="6">dog6</option>
498
+ </optgroup>
499
+ <optgroup label="small dogs">
500
+ <option value="1">dog1</option>
501
+ <option value="2" selected>dog2</option>
502
+ <option value="3">dog3</option>
503
+ </optgroup>
504
+ ` ;
511
505
512
506
// TomSelect will still have the correct value
513
507
expect ( tomSelect . getValue ( ) ) . toEqual ( '2' ) ;
@@ -529,44 +523,62 @@ describe('AutocompleteController', () => {
529
523
</select>
530
524
` ) ;
531
525
526
+ // select 3 to start
527
+ tomSelect . addItem ( '3' ) ;
532
528
const selectElement = getByTestId ( container , 'main-element' ) as HTMLSelectElement ;
529
+ expect ( selectElement . value ) . toBe ( '3' ) ;
533
530
534
531
// something external changes the set of options, including add a new one
535
- selectElement . children [ 1 ] . setAttribute ( 'value' , '4' ) ;
536
- selectElement . children [ 1 ] . innerHTML = 'dog4' ;
537
- selectElement . children [ 2 ] . setAttribute ( 'value' , '5' ) ;
538
- selectElement . children [ 2 ] . innerHTML = 'dog5' ;
539
- selectElement . children [ 3 ] . setAttribute ( 'value' , '6' ) ;
540
- selectElement . children [ 3 ] . innerHTML = 'dog6' ;
541
- const newOption7 = document . createElement ( 'option' ) ;
542
- newOption7 . setAttribute ( 'value' , '7' ) ;
543
- newOption7 . innerHTML = 'dog7' ;
544
- selectElement . appendChild ( newOption7 ) ;
545
- const newOption8 = document . createElement ( 'option' ) ;
546
- newOption8 . setAttribute ( 'value' , '8' ) ;
547
- newOption8 . innerHTML = 'dog8' ;
548
- selectElement . appendChild ( newOption8 ) ;
532
+ selectElement . innerHTML = `
533
+ <option value="">Select a dog</option>
534
+ <option value="4">dog4</option>
535
+ <option value="5">dog5</option>
536
+ <option value="6">dog6</option>
537
+ <option value="7">dog7</option>
538
+ <option value="8">dog8</option>
539
+ ` ;
540
+
541
+ let newTomSelect : TomSelect | null = null ;
542
+ container . addEventListener ( 'autocomplete:connect' , ( event : any ) => {
543
+ newTomSelect = ( event . detail as AutocompleteConnectOptions ) . tomSelect ;
544
+ } ) ;
549
545
550
546
// wait for the MutationObserver to flush these changes
551
547
await shortDelay ( 10 ) ;
552
548
553
- const controlInput = tomSelect . control_input ;
554
- userEvent . click ( controlInput ) ;
549
+ // the previously selected option is no longer there
550
+ expect ( selectElement . value ) . toBe ( '' ) ;
551
+ userEvent . click ( container . querySelector ( '.ts-control' ) as HTMLElement ) ;
555
552
await waitFor ( ( ) => {
556
553
// make sure all 5 new options are there
557
554
expect ( container . querySelectorAll ( '.option[data-selectable]' ) ) . toHaveLength ( 5 ) ;
558
555
} ) ;
559
556
560
- tomSelect . addItem ( '7' ) ;
557
+ if ( null === newTomSelect ) {
558
+ throw new Error ( 'Missing TomSelect instance' ) ;
559
+ }
560
+ // @ts -ignore
561
+ newTomSelect . addItem ( '7' ) ;
561
562
expect ( selectElement . value ) . toBe ( '7' ) ;
562
563
563
564
// remove an element, the control should update
564
565
selectElement . removeChild ( selectElement . children [ 1 ] ) ;
565
566
await shortDelay ( 10 ) ;
566
- userEvent . click ( controlInput ) ;
567
+ userEvent . click ( container . querySelector ( '.ts-control' ) as HTMLElement ) ;
567
568
await waitFor ( ( ) => {
568
569
expect ( container . querySelectorAll ( '.option[data-selectable]' ) ) . toHaveLength ( 4 ) ;
569
570
} ) ;
571
+
572
+ // change again, but the selected value is still there
573
+ selectElement . innerHTML = `
574
+ <option value="">Select a dog</option>
575
+ <option value="1">dog4</option>
576
+ <option value="2">dog5</option>
577
+ <option value="3">dog6</option>
578
+ <option value="7">dog7</option>
579
+ ` ;
580
+ await shortDelay ( 10 ) ;
581
+ expect ( selectElement . value ) . toBe ( '7' ) ;
570
582
} ) ;
571
583
572
584
it ( 'toggles correctly between disabled and enabled' , async ( ) => {
@@ -616,15 +628,25 @@ describe('AutocompleteController', () => {
616
628
const selectElement = getByTestId ( container , 'main-element' ) as HTMLSelectElement ;
617
629
expect ( tomSelect . control_input . placeholder ) . toBe ( 'Select a dog' ) ;
618
630
619
- selectElement . children [ 0 ] . innerHTML = 'Select a cat' ;
620
- // wait for the MutationObserver
621
- await shortDelay ( 10 ) ;
622
- expect ( tomSelect . control_input . placeholder ) . toBe ( 'Select a cat' ) ;
631
+ let newTomSelect : TomSelect | null = null ;
632
+ container . addEventListener ( 'autocomplete:connect' , ( event : any ) => {
633
+ newTomSelect = ( event . detail as AutocompleteConnectOptions ) . tomSelect ;
634
+ } ) ;
635
+
636
+ selectElement . innerHTML = `
637
+ <option value="">Select a cat</option>
638
+ <option value="1">dog1</option>
639
+ <option value="2">dog2</option>
640
+ <option value="3">dog3</option>
641
+ ` ;
623
642
624
- // a different way to change the placeholder
625
- selectElement . children [ 0 ] . childNodes [ 0 ] . nodeValue = 'Select a kangaroo' ;
643
+ // wait for the MutationObserver
626
644
await shortDelay ( 10 ) ;
627
- expect ( tomSelect . control_input . placeholder ) . toBe ( 'Select a kangaroo' ) ;
645
+ if ( null === newTomSelect ) {
646
+ throw new Error ( 'Missing TomSelect instance' ) ;
647
+ }
648
+ // @ts -ignore
649
+ expect ( newTomSelect . control_input . placeholder ) . toBe ( 'Select a cat' ) ;
628
650
} ) ;
629
651
630
652
it ( 'group related options' , async ( ) => {
0 commit comments