@spectrum-web-components/picker 0.35.1-rc.43 → 0.36.0

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.
package/test/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  import {
3
- aTimeout,
4
3
  elementUpdated,
5
4
  expect,
6
5
  fixture,
@@ -16,6 +15,7 @@ import {
16
15
  arrowLeftEvent,
17
16
  arrowRightEvent,
18
17
  arrowUpEvent,
18
+ escapeEvent,
19
19
  testForLitDevWarnings,
20
20
  tEvent
21
21
  } from "../../../test/testing-helpers.js";
@@ -32,20 +32,21 @@ import {
32
32
  } from "../stories/picker.stories.js";
33
33
  import { sendMouse } from "../../../test/plugins/browser.js";
34
34
  import { ignoreResizeObserverLoopError } from "../../../test/testing-helpers.js";
35
- import { isFirefox } from "@spectrum-web-components/shared/src/platform.js";
36
- import "@spectrum-web-components/theme/sp-theme.js";
37
- import "@spectrum-web-components/theme/src/themes.js";
35
+ import {
36
+ isFirefox,
37
+ isWebKit
38
+ } from "@spectrum-web-components/shared/src/platform.js";
38
39
  ignoreResizeObserverLoopError(before, after);
39
- const isMenuActiveElement = function(el) {
40
+ const isMenuActiveElement = function() {
40
41
  var _a;
41
- return ((_a = el.shadowRoot.activeElement) == null ? void 0 : _a.localName) === "sp-menu";
42
+ return ((_a = document.activeElement) == null ? void 0 : _a.localName) === "sp-menu";
42
43
  };
43
44
  export function runPickerTests() {
44
45
  let el;
45
46
  const pickerFixture = async () => {
46
47
  const test = await fixture(
47
48
  html`
48
- <sp-theme scale="medium" color="light">
49
+ <div>
49
50
  <sp-field-label for="picker">
50
51
  Where do you live?
51
52
  </sp-field-label>
@@ -63,7 +64,7 @@ export function runPickerTests() {
63
64
  <sp-menu-item>Save Selection</sp-menu-item>
64
65
  <sp-menu-item disabled>Make Work Path</sp-menu-item>
65
66
  </sp-picker>
66
- </sp-theme>
67
+ </div>
67
68
  `
68
69
  );
69
70
  return test.querySelector("sp-picker");
@@ -90,8 +91,6 @@ export function runPickerTests() {
90
91
  ).to.not.be.null;
91
92
  el2.value = "option-2";
92
93
  await elementUpdated(el2);
93
- await nextFrame();
94
- await nextFrame();
95
94
  snapshot = await a11ySnapshot({});
96
95
  expect(
97
96
  findAccessibilityNode(
@@ -122,8 +121,6 @@ export function runPickerTests() {
122
121
  ).to.not.be.null;
123
122
  el2.value = "option-2";
124
123
  await elementUpdated(el2);
125
- await nextFrame();
126
- await nextFrame();
127
124
  snapshot = await a11ySnapshot({});
128
125
  expect(
129
126
  findAccessibilityNode(
@@ -154,8 +151,6 @@ export function runPickerTests() {
154
151
  ).to.not.be.null;
155
152
  el2.value = "option-2";
156
153
  await elementUpdated(el2);
157
- await nextFrame();
158
- await nextFrame();
159
154
  snapshot = await a11ySnapshot({});
160
155
  if (isFirefox()) {
161
156
  expect(
@@ -181,6 +176,13 @@ export function runPickerTests() {
181
176
  el = await pickerFixture();
182
177
  await elementUpdated(el);
183
178
  });
179
+ afterEach(async () => {
180
+ if (el.open) {
181
+ const closed = oneEvent(el, "sp-closed");
182
+ el.open = false;
183
+ await closed;
184
+ }
185
+ });
184
186
  it("loads accessibly", async () => {
185
187
  await expect(el).to.be.accessible();
186
188
  });
@@ -192,7 +194,7 @@ export function runPickerTests() {
192
194
  el.open = true;
193
195
  await opened;
194
196
  expect(el.open).to.be.true;
195
- const accessibleCloseButton = el.shadowRoot.querySelector(
197
+ const accessibleCloseButton = document.querySelector(
196
198
  ".visually-hidden button"
197
199
  );
198
200
  expect(accessibleCloseButton).to.have.attribute(
@@ -208,13 +210,10 @@ export function runPickerTests() {
208
210
  expect(document.activeElement).to.eq(el);
209
211
  });
210
212
  it("accepts new selected item content", async () => {
211
- await nextFrame();
212
- await nextFrame();
213
213
  const option2 = el.querySelector('[value="option-2"');
214
214
  el.value = "option-2";
215
215
  await elementUpdated(option2);
216
216
  await elementUpdated(el);
217
- await aTimeout(150);
218
217
  expect(el.value).to.equal("option-2");
219
218
  expect((el.button.textContent || "").trim()).to.include(
220
219
  "Select Inverse"
@@ -235,11 +234,9 @@ export function runPickerTests() {
235
234
  expect((el.button.textContent || "").trim()).to.include(newLabel2);
236
235
  });
237
236
  it("accepts new selected item content when open", async () => {
238
- await nextFrame();
239
237
  const option2 = el.querySelector('[value="option-2"');
240
238
  el.value = "option-2";
241
239
  await elementUpdated(el);
242
- await aTimeout(150);
243
240
  expect(el.value).to.equal("option-2");
244
241
  expect((el.button.textContent || "").trim()).to.include(
245
242
  "Select Inverse"
@@ -260,27 +257,21 @@ export function runPickerTests() {
260
257
  );
261
258
  });
262
259
  it("unsets value when children removed", async () => {
263
- await nextFrame();
264
260
  el.value = "option-2";
265
261
  await elementUpdated(el);
266
- await aTimeout(150);
267
262
  expect(el.value).to.equal("option-2");
268
263
  expect((el.button.textContent || "").trim()).to.include(
269
264
  "Select Inverse"
270
265
  );
271
266
  const items = el.querySelectorAll("sp-menu-item");
267
+ const removals = [];
272
268
  items.forEach((item) => {
269
+ const removal = oneEvent(el, "sp-menu-item-removed");
273
270
  item.remove();
271
+ removals.push(removal);
274
272
  });
273
+ await Promise.all(removals);
275
274
  await elementUpdated(el);
276
- await nextFrame();
277
- await aTimeout(150);
278
- expect(
279
- el.optionsMenu.childItems.length
280
- ).to.equal(0);
281
- if ("showPopover" in document.createElement("div")) {
282
- return;
283
- }
284
275
  expect(el.value).to.equal("");
285
276
  expect((el.button.textContent || "").trim()).to.not.include(
286
277
  "Select Inverse"
@@ -307,7 +298,7 @@ export function runPickerTests() {
307
298
  item.value = "option-new";
308
299
  item.textContent = "New Option";
309
300
  el.append(item);
310
- await nextFrame();
301
+ await elementUpdated(item);
311
302
  await elementUpdated(el);
312
303
  let opened = oneEvent(el, "sp-opened");
313
304
  el.open = true;
@@ -325,7 +316,6 @@ export function runPickerTests() {
325
316
  expect(el.value, "second time").to.equal("option-new");
326
317
  });
327
318
  it('manages its "name" value in the accessibility tree', async () => {
328
- await nextFrame();
329
319
  let snapshot = await a11ySnapshot({});
330
320
  expect(
331
321
  findAccessibilityNode(
@@ -336,8 +326,6 @@ export function runPickerTests() {
336
326
  ).to.not.be.null;
337
327
  el.value = "option-2";
338
328
  await elementUpdated(el);
339
- await nextFrame();
340
- await nextFrame();
341
329
  snapshot = await a11ySnapshot({});
342
330
  expect(
343
331
  findAccessibilityNode(
@@ -354,16 +342,12 @@ export function runPickerTests() {
354
342
  el.open = true;
355
343
  await opened;
356
344
  expect(
357
- el.optionsMenu.getAttribute(
358
- "aria-activedescendant"
359
- )
345
+ el.optionsMenu.getAttribute("aria-activedescendant")
360
346
  ).to.equal(firstItem == null ? void 0 : firstItem.id);
361
347
  await sendKeys({ press: "ArrowDown" });
362
348
  await elementUpdated(el);
363
349
  expect(
364
- el.optionsMenu.getAttribute(
365
- "aria-activedescendant"
366
- )
350
+ el.optionsMenu.getAttribute("aria-activedescendant")
367
351
  ).to.equal(secondItem == null ? void 0 : secondItem.id);
368
352
  });
369
353
  it("renders invalid accessibly", async () => {
@@ -378,7 +362,6 @@ export function runPickerTests() {
378
362
  await expect(el).to.be.accessible();
379
363
  });
380
364
  it("opens with visible focus on a menu item on `DownArrow`", async () => {
381
- var _a, _b;
382
365
  const firstItem = el.querySelector("sp-menu-item");
383
366
  await elementUpdated(el);
384
367
  expect(firstItem.focused, "should not visually focused").to.be.false;
@@ -397,24 +380,12 @@ export function runPickerTests() {
397
380
  });
398
381
  await closed;
399
382
  expect(el.open).to.be.false;
400
- expect(
401
- document.activeElement === el,
402
- `focused ${(_a = document.activeElement) == null ? void 0 : _a.localName} instead of back on Picker`
403
- ).to.be.true;
404
- expect(
405
- el.shadowRoot.activeElement === el.button,
406
- `focused ${(_b = el.shadowRoot.activeElement) == null ? void 0 : _b.localName} instead of back on button`
407
- ).to.be.true;
408
- await waitUntil(
409
- () => !firstItem.focused,
410
- "finally, not visually focused"
411
- );
383
+ await waitUntil(() => !firstItem.focused, "not visually focused");
412
384
  });
413
- it("opens, on click, without visible focus on a menu item", async () => {
414
- await nextFrame();
415
- await nextFrame();
385
+ it("opens without visible focus on a menu item on click", async () => {
416
386
  const firstItem = el.querySelector("sp-menu-item");
417
- const boundingRect = el.button.getBoundingClientRect();
387
+ await elementUpdated(el);
388
+ const boundingRect = el.getBoundingClientRect();
418
389
  expect(firstItem.focused, "not visually focused").to.be.false;
419
390
  const opened = oneEvent(el, "sp-opened");
420
391
  sendMouse({
@@ -429,69 +400,10 @@ export function runPickerTests() {
429
400
  ]
430
401
  });
431
402
  await opened;
403
+ await elementUpdated(el);
432
404
  expect(el.open).to.be.true;
433
405
  expect(firstItem.focused, "still not visually focused").to.be.false;
434
406
  });
435
- it("opens/closes multiple times", async () => {
436
- expect(el.open).to.be.false;
437
- const boundingRect = el.button.getBoundingClientRect();
438
- let opened = oneEvent(el, "sp-opened");
439
- sendMouse({
440
- steps: [
441
- {
442
- type: "click",
443
- position: [
444
- boundingRect.x + boundingRect.width / 2,
445
- boundingRect.y + boundingRect.height / 2
446
- ]
447
- }
448
- ]
449
- });
450
- await opened;
451
- expect(el.open).to.be.true;
452
- let closed = oneEvent(el, "sp-closed");
453
- sendMouse({
454
- steps: [
455
- {
456
- type: "click",
457
- position: [
458
- boundingRect.x + boundingRect.width / 2,
459
- boundingRect.y + boundingRect.height / 2
460
- ]
461
- }
462
- ]
463
- });
464
- await closed;
465
- expect(el.open).to.be.false;
466
- opened = oneEvent(el, "sp-opened");
467
- sendMouse({
468
- steps: [
469
- {
470
- type: "click",
471
- position: [
472
- boundingRect.x + boundingRect.width / 2,
473
- boundingRect.y + boundingRect.height / 2
474
- ]
475
- }
476
- ]
477
- });
478
- await opened;
479
- expect(el.open).to.be.true;
480
- closed = oneEvent(el, "sp-closed");
481
- sendMouse({
482
- steps: [
483
- {
484
- type: "click",
485
- position: [
486
- boundingRect.x + boundingRect.width / 2,
487
- boundingRect.y + boundingRect.height / 2
488
- ]
489
- }
490
- ]
491
- });
492
- await closed;
493
- expect(el.open).to.be.false;
494
- });
495
407
  it("closes when becoming disabled", async () => {
496
408
  expect(el.open).to.be.false;
497
409
  el.click();
@@ -507,15 +419,11 @@ export function runPickerTests() {
507
419
  document.body.append(other);
508
420
  await elementUpdated(el);
509
421
  expect(el.open).to.be.false;
510
- const opened = oneEvent(el, "sp-opened");
511
422
  el.click();
512
- await opened;
513
423
  await elementUpdated(el);
514
424
  expect(el.open).to.be.true;
515
- const closed = oneEvent(el, "sp-closed");
516
425
  other.click();
517
- closed;
518
- await elementUpdated(el);
426
+ await waitUntil(() => !el.open, "closed");
519
427
  other.remove();
520
428
  });
521
429
  it("selects", async () => {
@@ -527,6 +435,7 @@ export function runPickerTests() {
527
435
  const opened = oneEvent(el, "sp-opened");
528
436
  button.click();
529
437
  await opened;
438
+ await elementUpdated(el);
530
439
  expect(el.open).to.be.true;
531
440
  expect((_a = el.selectedItem) == null ? void 0 : _a.itemText).to.be.undefined;
532
441
  expect(el.value).to.equal("");
@@ -546,27 +455,31 @@ export function runPickerTests() {
546
455
  "sp-menu-item:nth-of-type(2)"
547
456
  );
548
457
  const button = el.button;
549
- let opened = oneEvent(el, "sp-opened");
458
+ const opened = oneEvent(el, "sp-opened");
550
459
  button.click();
551
460
  await opened;
461
+ await nextFrame();
552
462
  expect(el.open).to.be.true;
553
463
  expect((_a = el.selectedItem) == null ? void 0 : _a.itemText).to.be.undefined;
554
464
  expect(el.value).to.equal("");
555
- let closed = oneEvent(el, "sp-closed");
465
+ const closed = oneEvent(el, "sp-closed");
556
466
  secondItem.click();
557
467
  await closed;
468
+ await nextFrame();
558
469
  expect(el.open).to.be.false;
559
470
  expect((_b = el.selectedItem) == null ? void 0 : _b.itemText).to.equal("Select Inverse");
560
471
  expect(el.value).to.equal("option-2");
561
- opened = oneEvent(el, "sp-opened");
472
+ const opened2 = oneEvent(el, "sp-opened");
562
473
  button.click();
563
- await opened;
474
+ await opened2;
475
+ await nextFrame();
564
476
  expect(el.open).to.be.true;
565
477
  expect((_c = el.selectedItem) == null ? void 0 : _c.itemText).to.equal("Select Inverse");
566
478
  expect(el.value).to.equal("option-2");
567
- closed = oneEvent(el, "sp-closed");
479
+ const closed2 = oneEvent(el, "sp-closed");
568
480
  firstItem.click();
569
- await closed;
481
+ await closed2;
482
+ await nextFrame();
570
483
  expect(el.open).to.be.false;
571
484
  expect((_d = el.selectedItem) == null ? void 0 : _d.itemText).to.equal("Deselect");
572
485
  expect(el.value).to.equal("Deselect");
@@ -574,6 +487,7 @@ export function runPickerTests() {
574
487
  it("dispatches bubbling and composed events", async () => {
575
488
  const changeSpy = spy();
576
489
  const parent = el.parentElement;
490
+ parent.attachShadow({ mode: "open" });
577
491
  parent.shadowRoot.append(el);
578
492
  const secondItem = el.querySelector(
579
493
  "sp-menu-item:nth-of-type(2)"
@@ -583,9 +497,11 @@ export function runPickerTests() {
583
497
  const opened = oneEvent(el, "sp-opened");
584
498
  el.open = true;
585
499
  await opened;
500
+ await elementUpdated(el);
586
501
  const closed = oneEvent(el, "sp-closed");
587
502
  secondItem.click();
588
503
  await closed;
504
+ await elementUpdated(el);
589
505
  expect(el.value).to.equal(secondItem.value);
590
506
  expect(changeSpy.calledOnce).to.be.true;
591
507
  });
@@ -596,9 +512,10 @@ export function runPickerTests() {
596
512
  "sp-menu-item:nth-of-type(2)"
597
513
  );
598
514
  const button = el.button;
599
- const opened = oneEvent(el, "sp-opened");
515
+ let opened = oneEvent(el, "sp-opened");
600
516
  button.click();
601
517
  await opened;
518
+ await elementUpdated(el);
602
519
  expect(el.open).to.be.true;
603
520
  expect((_a = el.selectedItem) == null ? void 0 : _a.itemText).to.be.undefined;
604
521
  expect(el.value).to.equal("");
@@ -607,12 +524,14 @@ export function runPickerTests() {
607
524
  event.preventDefault();
608
525
  preventChangeSpy();
609
526
  });
527
+ const closed = oneEvent(el, "sp-closed");
528
+ opened = oneEvent(el, "sp-opened");
610
529
  secondItem.click();
611
- await nextFrame();
612
- await nextFrame();
530
+ await closed;
531
+ await opened;
532
+ await elementUpdated(el);
613
533
  expect(preventChangeSpy.calledOnce).to.be.true;
614
534
  expect(secondItem.selected, "selection prevented").to.be.false;
615
- expect(el.open).to.be.true;
616
535
  });
617
536
  it("can throw focus after `change`", async () => {
618
537
  var _a;
@@ -655,17 +574,20 @@ export function runPickerTests() {
655
574
  button.dispatchEvent(tEvent());
656
575
  await elementUpdated(el);
657
576
  expect(el.open, "still closed").to.be.false;
658
- const opened = oneEvent(el, "sp-opened");
659
577
  button.dispatchEvent(arrowUpEvent());
660
578
  await elementUpdated(el);
661
579
  expect(el.open, "open by ArrowUp").to.be.true;
662
- await opened;
663
- const closed = oneEvent(el, "sp-closed");
664
- sendKeys({
665
- press: "Escape"
666
- });
667
- await closed;
668
- expect(el.open).to.be.false;
580
+ await waitUntil(
581
+ () => document.querySelector("active-overlay") !== null,
582
+ "an active-overlay has been inserted on the page"
583
+ );
584
+ button.dispatchEvent(escapeEvent());
585
+ await elementUpdated(el);
586
+ await waitUntil(() => el.open === false, "closed by Escape");
587
+ await waitUntil(
588
+ () => document.querySelector("active-overlay") === null,
589
+ "an active-overlay has been inserted on the page"
590
+ );
669
591
  });
670
592
  it("opens on ArrowDown", async () => {
671
593
  var _a, _b;
@@ -679,18 +601,19 @@ export function runPickerTests() {
679
601
  const opened = oneEvent(el, "sp-opened");
680
602
  button.dispatchEvent(arrowDownEvent());
681
603
  await opened;
604
+ await elementUpdated(el);
682
605
  expect(el.open, "open by ArrowDown").to.be.true;
683
606
  expect((_a = el.selectedItem) == null ? void 0 : _a.itemText).to.be.undefined;
684
607
  expect(el.value).to.equal("");
685
608
  const closed = oneEvent(el, "sp-closed");
686
609
  firstItem.click();
687
610
  await closed;
611
+ await elementUpdated(el);
688
612
  expect(el.open).to.be.false;
689
613
  expect((_b = el.selectedItem) == null ? void 0 : _b.itemText).to.equal("Deselect");
690
614
  expect(el.value).to.equal("Deselect");
691
615
  });
692
616
  it("quick selects on ArrowLeft/Right", async () => {
693
- await nextFrame();
694
617
  const selectionSpy = spy();
695
618
  el.addEventListener("change", (event) => {
696
619
  const { value } = event.target;
@@ -718,7 +641,6 @@ export function runPickerTests() {
718
641
  expect(selectionSpy.calledWith("Make Work Path")).to.be.false;
719
642
  });
720
643
  it("quick selects first item on ArrowRight when no value", async () => {
721
- await nextFrame();
722
644
  const selectionSpy = spy();
723
645
  el.addEventListener("change", (event) => {
724
646
  const { value } = event.target;
@@ -736,10 +658,6 @@ export function runPickerTests() {
736
658
  });
737
659
  it("refocuses on list when open", async () => {
738
660
  const firstItem = el.querySelector("sp-menu-item");
739
- const thirdItem = el.querySelector(
740
- "sp-menu-item:nth-of-type(3)"
741
- );
742
- const button = el.button;
743
661
  const input = document.createElement("input");
744
662
  el.insertAdjacentElement("afterend", input);
745
663
  el.focus();
@@ -747,79 +665,44 @@ export function runPickerTests() {
747
665
  expect(document.activeElement === input).to.be.true;
748
666
  await sendKeys({ press: "Shift+Tab" });
749
667
  expect(document.activeElement === el).to.be.true;
668
+ await sendKeys({ press: "Enter" });
750
669
  const opened = oneEvent(el, "sp-opened");
751
- sendKeys({ press: "Enter" });
670
+ el.open = true;
752
671
  await opened;
753
672
  await elementUpdated(el);
754
673
  await waitUntil(
755
674
  () => firstItem.focused,
756
675
  "The first items should have become focused visually."
757
676
  );
758
- await sendKeys({ press: "ArrowDown" });
759
- await sendKeys({ press: "ArrowDown" });
760
- expect(thirdItem.focused).to.be.true;
761
- button.focus();
762
- expect(isMenuActiveElement(el)).to.be.false;
677
+ el.blur();
678
+ await elementUpdated(el);
679
+ expect(el.open).to.be.true;
763
680
  el.focus();
764
681
  await elementUpdated(el);
765
682
  await waitUntil(
766
- () => isMenuActiveElement(el),
683
+ () => isMenuActiveElement(),
767
684
  "first item refocused"
768
685
  );
769
- expect(isMenuActiveElement(el)).to.be.true;
770
- expect(thirdItem.focused).to.be.true;
771
- });
772
- it("does not listen to streaming `Enter` keydown", async () => {
773
- const openSpy = spy();
774
- const closedSpy = spy();
775
- el.addEventListener("sp-opened", () => openSpy());
776
- el.addEventListener("sp-closed", () => closedSpy());
777
- const firstItem = el.querySelector("sp-menu-item");
778
- const thirdItem = el.querySelector(
779
- "sp-menu-item:nth-of-type(3)"
780
- );
781
- const input = document.createElement("input");
782
- el.insertAdjacentElement("afterend", input);
783
- el.focus();
784
- await sendKeys({ press: "Tab" });
785
- expect(document.activeElement === input).to.be.true;
786
- await sendKeys({ press: "Shift+Tab" });
787
- expect(document.activeElement === el).to.be.true;
788
- const opened = oneEvent(el, "sp-opened");
789
- sendKeys({ down: "Enter" });
790
- await opened;
791
- await aTimeout(300);
792
- expect(openSpy.callCount).to.equal(1);
793
- await sendKeys({ up: "Enter" });
794
- await waitUntil(
795
- () => firstItem.focused,
796
- "The first items should have become focused visually."
797
- );
798
- await sendKeys({ press: "ArrowDown" });
686
+ expect(el.open).to.be.true;
687
+ expect(isMenuActiveElement()).to.be.true;
799
688
  await sendKeys({ press: "ArrowDown" });
800
- expect(thirdItem.focused).to.be.true;
801
- const closed = oneEvent(el, "sp-closed");
802
- sendKeys({ down: "Enter" });
803
- await closed;
804
- await aTimeout(300);
805
- expect(el.value).to.equal(thirdItem.value);
806
- expect(openSpy.callCount).to.equal(1);
807
- expect(closedSpy.callCount).to.equal(1);
808
- await sendKeys({ up: "Enter" });
689
+ await sendKeys({ press: "ArrowUp" });
690
+ expect(firstItem.focused).to.be.true;
809
691
  });
810
- it("allows tabing to close", async () => {
811
- const input = document.createElement("input");
812
- el.insertAdjacentElement("afterend", input);
813
- const opened = oneEvent(el, "sp-opened");
692
+ it("does not allow tabing to close", async () => {
814
693
  el.open = true;
815
- await opened;
816
- await nextFrame();
694
+ await elementUpdated(el);
817
695
  expect(el.open).to.be.true;
818
696
  el.focus();
819
- const closed = oneEvent(el, "sp-closed");
820
- sendKeys({ press: "Tab" });
821
- await closed;
822
- expect(el.open, "closes").to.be.false;
697
+ await elementUpdated(el);
698
+ await waitUntil(
699
+ () => isMenuActiveElement(),
700
+ "first item refocused"
701
+ );
702
+ expect(el.open).to.be.true;
703
+ expect(isMenuActiveElement()).to.be.true;
704
+ await sendKeys({ press: "Tab" });
705
+ expect(el.open, "stays open").to.be.true;
823
706
  });
824
707
  describe("tab order", () => {
825
708
  let input1;
@@ -874,7 +757,51 @@ export function runPickerTests() {
874
757
  input1
875
758
  );
876
759
  });
877
- it("can close and immediately tab to the next tab stop", async () => {
760
+ it('traps tab in the menu as a `type="modal"` overlay forward', async () => {
761
+ el.focus();
762
+ await nextFrame();
763
+ expect(document.activeElement, "focuses el").to.equal(el);
764
+ const opened = oneEvent(el, "sp-opened");
765
+ sendKeys({ press: "ArrowDown" });
766
+ await opened;
767
+ expect(el.open, "opened").to.be.true;
768
+ await waitUntil(
769
+ () => isMenuActiveElement(),
770
+ "first item focused"
771
+ );
772
+ const activeElement = document.activeElement;
773
+ if (!isWebKit()) {
774
+ const blured = oneEvent(activeElement, "blur");
775
+ sendKeys({ press: "Tab" });
776
+ await blured;
777
+ expect(el.open, "picker still open").to.be.true;
778
+ expect(document.activeElement === input1).to.be.false;
779
+ expect(document.activeElement === input2).to.be.false;
780
+ }
781
+ });
782
+ it('traps tab in the menu as a `type="modal"` overlay backwards', async () => {
783
+ el.focus();
784
+ await nextFrame();
785
+ expect(document.activeElement, "focuses el").to.equal(el);
786
+ const opened = oneEvent(el, "sp-opened");
787
+ await sendKeys({ press: "ArrowDown" });
788
+ await opened;
789
+ expect(el.open, "opened").to.be.true;
790
+ await waitUntil(
791
+ () => isMenuActiveElement(),
792
+ "first item focused"
793
+ );
794
+ const activeElement = document.activeElement;
795
+ if (!isWebKit()) {
796
+ const blured = oneEvent(activeElement, "blur");
797
+ sendKeys({ press: "Shift+Tab" });
798
+ await blured;
799
+ expect(el.open, "picker still open").to.be.true;
800
+ expect(document.activeElement === input1).to.be.false;
801
+ expect(document.activeElement === input2).to.be.false;
802
+ }
803
+ });
804
+ it("can close and immediate tab to the next tab stop", async () => {
878
805
  el.focus();
879
806
  await nextFrame();
880
807
  expect(document.activeElement, "focuses el").to.equal(el);
@@ -883,7 +810,7 @@ export function runPickerTests() {
883
810
  await opened;
884
811
  expect(el.open, "opened").to.be.true;
885
812
  await waitUntil(
886
- () => isMenuActiveElement(el),
813
+ () => isMenuActiveElement(),
887
814
  "first item focused"
888
815
  );
889
816
  const closed = oneEvent(el, "sp-closed");
@@ -900,13 +827,13 @@ export function runPickerTests() {
900
827
  it("can close and immediate shift+tab to the previous tab stop", async () => {
901
828
  el.focus();
902
829
  await nextFrame();
903
- expect(document.activeElement === el, "focuses el").to.be.true;
830
+ expect(document.activeElement, "focuses el").to.equal(el);
904
831
  const opened = oneEvent(el, "sp-opened");
905
832
  await sendKeys({ press: "ArrowUp" });
906
833
  await opened;
907
834
  expect(el.open, "opened").to.be.true;
908
835
  await waitUntil(
909
- () => isMenuActiveElement(el),
836
+ () => isMenuActiveElement(),
910
837
  "first item focused"
911
838
  );
912
839
  const closed = oneEvent(el, "sp-closed");
@@ -915,7 +842,7 @@ export function runPickerTests() {
915
842
  expect(el.open).to.be.false;
916
843
  expect(document.activeElement === el).to.be.true;
917
844
  const focused = oneEvent(input1, "focus");
918
- sendKeys({ press: "Shift+Tab" });
845
+ await sendKeys({ press: "Shift+Tab" });
919
846
  await focused;
920
847
  expect(el.open).to.be.false;
921
848
  expect(document.activeElement === input1).to.be.true;
@@ -930,7 +857,8 @@ export function runPickerTests() {
930
857
  expect(el.open).to.be.false;
931
858
  });
932
859
  it("scrolls selected into view on open", async () => {
933
- el.shadowRoot.querySelector("sp-popover").style.height = "40px";
860
+ await el.generatePopover();
861
+ el.popoverEl.style.height = "40px";
934
862
  const firstItem = el.querySelector(
935
863
  "sp-menu-item:first-child"
936
864
  );
@@ -940,15 +868,11 @@ export function runPickerTests() {
940
868
  lastItem.disabled = false;
941
869
  el.value = lastItem.value;
942
870
  await elementUpdated(el);
943
- const opened = oneEvent(el, "sp-opened");
944
871
  el.open = true;
945
- await opened;
946
- await waitUntil(
947
- () => isMenuActiveElement(el),
948
- "first item focused"
949
- );
872
+ await elementUpdated(el);
873
+ await waitUntil(() => isMenuActiveElement(), "first item focused");
950
874
  const getParentOffset = (el2) => {
951
- const parentScroll = el2.assignedSlot.parentElement.scrollTop;
875
+ const parentScroll = el2.parentElement.scrollTop;
952
876
  const parentOffset = el2.offsetTop - parentScroll;
953
877
  return parentOffset;
954
878
  };
@@ -957,9 +881,7 @@ export function runPickerTests() {
957
881
  lastItem.dispatchEvent(
958
882
  new FocusEvent("focusin", { bubbles: true })
959
883
  );
960
- await sendKeys({
961
- press: "ArrowDown"
962
- });
884
+ lastItem.dispatchEvent(arrowDownEvent());
963
885
  await elementUpdated(el);
964
886
  await nextFrame();
965
887
  expect(getParentOffset(lastItem)).to.be.greaterThan(40);
@@ -997,8 +919,6 @@ export function runPickerTests() {
997
919
  beforeEach(async () => {
998
920
  el = await groupedFixture();
999
921
  await elementUpdated(el);
1000
- await nextFrame();
1001
- await nextFrame();
1002
922
  });
1003
923
  it("selects the item with a matching value in a group", async () => {
1004
924
  const item = el.querySelector("#should-be-selected");
@@ -1036,7 +956,6 @@ export function runPickerTests() {
1036
956
  beforeEach(async () => {
1037
957
  el = await pickerFixture2();
1038
958
  await elementUpdated(el);
1039
- await nextFrame();
1040
959
  });
1041
960
  afterEach(async () => {
1042
961
  if (el.open) {
@@ -1122,7 +1041,6 @@ export function runPickerTests() {
1122
1041
  beforeEach(async () => {
1123
1042
  el = await pickerFixture2();
1124
1043
  await elementUpdated(el);
1125
- await nextFrame();
1126
1044
  });
1127
1045
  afterEach(async () => {
1128
1046
  if (el.open) {
@@ -1139,6 +1057,7 @@ export function runPickerTests() {
1139
1057
  const opened = oneEvent(el, "sp-opened");
1140
1058
  el.button.click();
1141
1059
  await opened;
1060
+ await elementUpdated(el);
1142
1061
  expect(el.open).to.be.true;
1143
1062
  expect((_a = el.selectedItem) == null ? void 0 : _a.itemText).to.be.undefined;
1144
1063
  expect(el.value).to.equal("");
@@ -1158,7 +1077,6 @@ export function runPickerTests() {
1158
1077
  `);
1159
1078
  const el2 = test.querySelector("sp-picker");
1160
1079
  await elementUpdated(el2);
1161
- await nextFrame();
1162
1080
  let snapshot = await a11ySnapshot({});
1163
1081
  expect(
1164
1082
  findAccessibilityNode(
@@ -1169,9 +1087,6 @@ export function runPickerTests() {
1169
1087
  ).to.not.be.null;
1170
1088
  el2.value = "2";
1171
1089
  await elementUpdated(el2);
1172
- await nextFrame();
1173
- await nextFrame();
1174
- expect(el2.value).to.equal("2");
1175
1090
  snapshot = await a11ySnapshot({});
1176
1091
  expect(
1177
1092
  findAccessibilityNode(
@@ -1184,8 +1099,6 @@ export function runPickerTests() {
1184
1099
  it("toggles between pickers", async () => {
1185
1100
  const el2 = await pickerFixture();
1186
1101
  const el1 = await pickerFixture();
1187
- el1.parentElement.style.float = "left";
1188
- el2.parentElement.style.float = "left";
1189
1102
  el1.id = "away";
1190
1103
  el2.id = "other";
1191
1104
  await Promise.all([elementUpdated(el1), elementUpdated(el2)]);
@@ -1206,8 +1119,8 @@ export function runPickerTests() {
1206
1119
  closed = oneEvent(el2, "sp-closed");
1207
1120
  el1.click();
1208
1121
  await Promise.all([open, closed]);
1209
- expect(el2.open).to.be.false;
1210
1122
  expect(el1.open).to.be.true;
1123
+ expect(el2.open).to.be.false;
1211
1124
  closed = oneEvent(el1, "sp-closed");
1212
1125
  sendKeys({
1213
1126
  press: "Escape"
@@ -1216,7 +1129,7 @@ export function runPickerTests() {
1216
1129
  expect(el1.open).to.be.false;
1217
1130
  });
1218
1131
  it("displays selected item text by default", async () => {
1219
- var _a, _b, _c, _d, _e;
1132
+ var _a, _b, _c, _d;
1220
1133
  const el2 = await fixture(
1221
1134
  html`
1222
1135
  <sp-picker
@@ -1233,7 +1146,6 @@ export function runPickerTests() {
1233
1146
  </sp-picker>
1234
1147
  `
1235
1148
  );
1236
- await nextFrame();
1237
1149
  await elementUpdated(el2);
1238
1150
  await waitUntil(
1239
1151
  () => {
@@ -1259,21 +1171,16 @@ export function runPickerTests() {
1259
1171
  const opened = oneEvent(el2, "sp-opened");
1260
1172
  sendKeys({ press: "Enter" });
1261
1173
  await opened;
1174
+ await elementUpdated(el2.optionsMenu);
1262
1175
  expect(
1263
- el2 === document.activeElement,
1176
+ el2.optionsMenu === document.activeElement,
1264
1177
  `activeElement is ${(_d = document.activeElement) == null ? void 0 : _d.localName}`
1265
1178
  ).to.be.true;
1266
- expect(
1267
- el2.optionsMenu === el2.shadowRoot.activeElement,
1268
- `activeElement is ${(_e = el2.shadowRoot.activeElement) == null ? void 0 : _e.localName}`
1269
- ).to.be.true;
1270
1179
  expect(firstItem.focused, 'firstItem NOT "focused"').to.be.false;
1271
1180
  expect(secondItem.focused, 'secondItem "focused"').to.be.true;
1272
- expect(
1273
- el2.optionsMenu.getAttribute(
1274
- "aria-activedescendant"
1275
- )
1276
- ).to.equal(secondItem.id);
1181
+ expect(el2.optionsMenu.getAttribute("aria-activedescendant")).to.equal(
1182
+ secondItem.id
1183
+ );
1277
1184
  });
1278
1185
  it("resets value when item not available", async () => {
1279
1186
  var _a;
@@ -1355,11 +1262,15 @@ export function runPickerTests() {
1355
1262
  await elementUpdated(el2);
1356
1263
  expect(openedSpy.calledOnce).to.be.true;
1357
1264
  expect(closedSpy.calledOnce).to.be.false;
1265
+ const openedEvent = openedSpy.args[0][0];
1266
+ expect(openedEvent.detail.interaction).to.equal("modal");
1358
1267
  const closed = oneEvent(el2, "sp-closed");
1359
1268
  el2.open = false;
1360
1269
  await closed;
1361
1270
  await elementUpdated(el2);
1362
1271
  expect(closedSpy.calledOnce).to.be.true;
1272
+ const closedEvent = closedSpy.args[0][0];
1273
+ expect(closedEvent.detail.interaction).to.equal("modal");
1363
1274
  });
1364
1275
  }
1365
1276
  //# sourceMappingURL=index.js.map