fix(combobox): displayoverlay on keydown event
Co-authored-by: Thijs Louisse <Thijs.Louisse@ing.com>
This commit is contained in:
parent
3aa4783326
commit
63e05c36e3
4 changed files with 221 additions and 83 deletions
5
.changeset/four-days-pull.md
Normal file
5
.changeset/four-days-pull.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/combobox': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Combobox evaluates show condition after keyup(instead of keydown), so textbox value is updated
|
||||||
|
|
@ -390,8 +390,12 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_showOverlayCondition({ lastKey }) {
|
_showOverlayCondition({ lastKey }) {
|
||||||
const doNotOpenOn = ['Tab', 'Esc', 'Enter'];
|
// when no keyboard action involved (on focused change), return current opened state
|
||||||
return lastKey && !doNotOpenOn.includes(lastKey);
|
if (!lastKey) {
|
||||||
|
return this.opened;
|
||||||
|
}
|
||||||
|
const doNotShowOn = ['Tab', 'Esc', 'Enter'];
|
||||||
|
return !doNotShowOn.includes(lastKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -699,7 +703,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
|
||||||
*/
|
*/
|
||||||
_setupOpenCloseListeners() {
|
_setupOpenCloseListeners() {
|
||||||
super._setupOpenCloseListeners();
|
super._setupOpenCloseListeners();
|
||||||
this._inputNode.addEventListener('keydown', this.__requestShowOverlay);
|
this._inputNode.addEventListener('keyup', this.__requestShowOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -707,7 +711,7 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
|
||||||
*/
|
*/
|
||||||
_teardownOpenCloseListeners() {
|
_teardownOpenCloseListeners() {
|
||||||
super._teardownOpenCloseListeners();
|
super._teardownOpenCloseListeners();
|
||||||
this._inputNode.removeEventListener('keydown', this.__requestShowOverlay);
|
this._inputNode.removeEventListener('keyup', this.__requestShowOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -806,13 +810,9 @@ export class LionCombobox extends OverlayMixin(LionListbox) {
|
||||||
* @param {KeyboardEvent} [ev]
|
* @param {KeyboardEvent} [ev]
|
||||||
*/
|
*/
|
||||||
__requestShowOverlay(ev) {
|
__requestShowOverlay(ev) {
|
||||||
if (
|
this.opened = this._showOverlayCondition({
|
||||||
this._showOverlayCondition({
|
lastKey: ev && ev.key,
|
||||||
lastKey: ev && ev.key,
|
currentValue: this._inputNode.value,
|
||||||
currentValue: this._inputNode.value,
|
});
|
||||||
})
|
|
||||||
) {
|
|
||||||
this.opened = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,19 @@ function mimicUserTyping(el, value) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
el._inputNode.value = value;
|
el._inputNode.value = value;
|
||||||
el._inputNode.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
el._inputNode.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
||||||
|
el._inputNode.dispatchEvent(new KeyboardEvent('keyup', { key: value }));
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: value }));
|
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: value }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLInputElement} el
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
function mimicKeyPress(el, key) {
|
||||||
|
el.dispatchEvent(new KeyboardEvent('keydown', { key }));
|
||||||
|
el.dispatchEvent(new KeyboardEvent('keyup', { key }));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {LionCombobox} el
|
* @param {LionCombobox} el
|
||||||
* @param {string[]} values
|
* @param {string[]} values
|
||||||
|
|
@ -53,7 +63,7 @@ async function mimicUserTypingAdvanced(el, values) {
|
||||||
inputNode.value += key;
|
inputNode.value += key;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputNode.dispatchEvent(new KeyboardEvent('keydown', { key }));
|
mimicKeyPress(inputNode, key);
|
||||||
el._inputNode.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
el._inputNode.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
||||||
|
|
||||||
el.updateComplete.then(() => {
|
el.updateComplete.then(() => {
|
||||||
|
|
@ -264,7 +274,7 @@ describe('lion-combobox', () => {
|
||||||
expect(el.opened).to.equal(false);
|
expect(el.opened).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows overlay again after select and char keydown', async () => {
|
it('shows overlay again after select and char keyup', async () => {
|
||||||
/**
|
/**
|
||||||
* Scenario:
|
* Scenario:
|
||||||
* [1] user focuses textbox: overlay hidden
|
* [1] user focuses textbox: overlay hidden
|
||||||
|
|
@ -348,7 +358,7 @@ describe('lion-combobox', () => {
|
||||||
expect(el.opened).to.equal(true);
|
expect(el.opened).to.equal(true);
|
||||||
expect(el._inputNode.value).to.equal('Artichoke');
|
expect(el._inputNode.value).to.equal('Artichoke');
|
||||||
|
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Tab' }));
|
mimicKeyPress(el._inputNode, 'Tab');
|
||||||
expect(el.opened).to.equal(false);
|
expect(el.opened).to.equal(false);
|
||||||
expect(el._inputNode.value).to.equal('Artichoke');
|
expect(el._inputNode.value).to.equal('Artichoke');
|
||||||
});
|
});
|
||||||
|
|
@ -405,6 +415,79 @@ describe('lion-combobox', () => {
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.opened).to.equal(true);
|
expect(el.opened).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows to control overlay visibility via "_showOverlayCondition": should not display overlay if currentValue length condition is not fulfilled', async () => {
|
||||||
|
class ShowOverlayConditionCombobox extends LionCombobox {
|
||||||
|
/** @param {{ currentValue: string, lastKey:string }} options */
|
||||||
|
_showOverlayCondition(options) {
|
||||||
|
return options.currentValue.length > 3 && super._showOverlayCondition(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
||||||
|
const tag = unsafeStatic(tagName);
|
||||||
|
|
||||||
|
const el = /** @type {LionCombobox} */ (await fixture(html`
|
||||||
|
<${tag} name="foo">
|
||||||
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
||||||
|
</${tag}>
|
||||||
|
`));
|
||||||
|
|
||||||
|
mimicUserTyping(el, 'aaa');
|
||||||
|
expect(el.opened).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows to control overlay visibility via "_showOverlayCondition": should display overlay if currentValue length condition is fulfilled', async () => {
|
||||||
|
class ShowOverlayConditionCombobox extends LionCombobox {
|
||||||
|
/** @param {{ currentValue: string, lastKey:string }} options */
|
||||||
|
_showOverlayCondition(options) {
|
||||||
|
return options.currentValue.length > 3 && super._showOverlayCondition(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
||||||
|
const tag = unsafeStatic(tagName);
|
||||||
|
|
||||||
|
const el = /** @type {LionCombobox} */ (await fixture(html`
|
||||||
|
<${tag} name="foo">
|
||||||
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
||||||
|
</${tag}>
|
||||||
|
`));
|
||||||
|
|
||||||
|
mimicUserTyping(el, 'aaaa');
|
||||||
|
expect(el.opened).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('allows to control overlay visibility via "_showOverlayCondition": should not display overlay if currentValue length condition is not fulfilled after once fulfilled', async () => {
|
||||||
|
class ShowOverlayConditionCombobox extends LionCombobox {
|
||||||
|
/** @param {{ currentValue: string, lastKey:string }} options */
|
||||||
|
_showOverlayCondition(options) {
|
||||||
|
return options.currentValue.length > 3 && super._showOverlayCondition(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
||||||
|
const tag = unsafeStatic(tagName);
|
||||||
|
|
||||||
|
const el = /** @type {LionCombobox} */ (await fixture(html`
|
||||||
|
<${tag} name="foo">
|
||||||
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
||||||
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
||||||
|
</${tag}>
|
||||||
|
`));
|
||||||
|
|
||||||
|
mimicUserTyping(el, 'aaaa');
|
||||||
|
expect(el.opened).to.be.true;
|
||||||
|
|
||||||
|
mimicUserTyping(el, 'aaa');
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.opened).to.be.false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Accessibility', () => {
|
describe('Accessibility', () => {
|
||||||
|
|
@ -488,7 +571,7 @@ describe('lion-combobox', () => {
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
|
|
||||||
// Simulate backspace deleting the char at the end of the string
|
// Simulate backspace deleting the char at the end of the string
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Backspace' }));
|
mimicKeyPress(el._inputNode, 'Backspace');
|
||||||
el._inputNode.dispatchEvent(new Event('input'));
|
el._inputNode.dispatchEvent(new Event('input'));
|
||||||
const arr = el._inputNode.value.split('');
|
const arr = el._inputNode.value.split('');
|
||||||
arr.splice(el._inputNode.value.length - 1, 1);
|
arr.splice(el._inputNode.value.length - 1, 1);
|
||||||
|
|
@ -1123,11 +1206,11 @@ describe('lion-combobox', () => {
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('changes whether active index is set to the closest match automatically depending on autocomplete', async () => {
|
it('changes whether activeIndex is set to the closest match automatically depending on autocomplete', async () => {
|
||||||
/**
|
/**
|
||||||
* Automatic selection (setting activeIndex to closest matching option) in lion is set for inline & both autocomplete,
|
* Automatic selection (setting activeIndex to closest matching option) in lion is set for
|
||||||
* because it is unavoidable there
|
* 'inline' & 'both' autocomplete, because it is unavoidable there
|
||||||
* For list & none autocomplete, it is turned off and manual selection is required.
|
* For 'list' & 'none' autocomplete, it is turned off and manual selection is required.
|
||||||
* TODO: Make this configurable for list & none autocomplete?
|
* TODO: Make this configurable for list & none autocomplete?
|
||||||
*/
|
*/
|
||||||
const el = /** @type {LionCombobox} */ (await fixture(html`
|
const el = /** @type {LionCombobox} */ (await fixture(html`
|
||||||
|
|
@ -1139,49 +1222,64 @@ describe('lion-combobox', () => {
|
||||||
</lion-combobox>
|
</lion-combobox>
|
||||||
`));
|
`));
|
||||||
|
|
||||||
/** @param {LionCombobox} elm */
|
/**
|
||||||
function reset(elm) {
|
* @param {LionCombobox} elm
|
||||||
|
* @param {'none'|'list'|'inline'|'both'} autocomplete
|
||||||
|
*/
|
||||||
|
async function setup(elm, autocomplete) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
elm.autocomplete = autocomplete;
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
elm.activeIndex = -1;
|
elm.activeIndex = -1;
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
elm.checkedIndex = -1;
|
elm.checkedIndex = -1;
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
elm.opened = true;
|
||||||
|
await elm.updateComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
||||||
// Example 1. List Autocomplete with Manual Selection:
|
// Example 1. List Autocomplete with Manual Selection:
|
||||||
// does not set active at all until user selects
|
// does not set active at all until user selects
|
||||||
reset(el);
|
await setup(el, 'none');
|
||||||
el.autocomplete = 'none';
|
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
|
||||||
expect(el.activeIndex).to.equal(-1);
|
expect(el.activeIndex).to.equal(-1);
|
||||||
expect(el.opened).to.be.true;
|
expect(el.opened).to.be.true;
|
||||||
|
|
||||||
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
|
expect(el.opened).to.be.false;
|
||||||
|
expect(el.activeIndex).to.equal(-1);
|
||||||
|
|
||||||
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
||||||
// Example 2. List Autocomplete with Automatic Selection:
|
// Example 2. List Autocomplete with Automatic Selection:
|
||||||
// does not set active at all until user selects
|
// does not set active at all until user selects
|
||||||
reset(el);
|
await setup(el, 'list');
|
||||||
el.autocomplete = 'list';
|
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
|
||||||
expect(el.activeIndex).to.equal(-1);
|
|
||||||
expect(el.opened).to.be.true;
|
expect(el.opened).to.be.true;
|
||||||
|
expect(el.activeIndex).to.equal(-1);
|
||||||
|
|
||||||
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
|
expect(el.activeIndex).to.equal(-1);
|
||||||
|
expect(el.opened).to.be.false;
|
||||||
|
|
||||||
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
||||||
// Example 3. List with Inline Autocomplete (mostly, but with aria-autocomplete="inline")
|
// Example 3. List with Inline Autocomplete (mostly, but with aria-autocomplete="inline")
|
||||||
reset(el);
|
await setup(el, 'inline');
|
||||||
el.autocomplete = 'inline';
|
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
expect(el.opened).to.be.true;
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
|
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
||||||
|
|
@ -1190,13 +1288,12 @@ describe('lion-combobox', () => {
|
||||||
|
|
||||||
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
||||||
// Example 3. List with Inline Autocomplete
|
// Example 3. List with Inline Autocomplete
|
||||||
reset(el);
|
await setup(el, 'both');
|
||||||
el.autocomplete = 'both';
|
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
expect(el.opened).to.be.false;
|
expect(el.opened).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
@ -1225,7 +1322,7 @@ describe('lion-combobox', () => {
|
||||||
// select artichoke
|
// select artichoke
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'artichoke');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'artichoke');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
|
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
@ -1247,10 +1344,10 @@ describe('lion-combobox', () => {
|
||||||
// Select something
|
// Select something
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(el._inputNode, 'Enter');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
|
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
|
mimicKeyPress(el._inputNode, 'Escape');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el._inputNode.textContent).to.equal('');
|
expect(el._inputNode.textContent).to.equal('');
|
||||||
|
|
||||||
|
|
@ -1293,7 +1390,8 @@ describe('lion-combobox', () => {
|
||||||
mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(null);
|
expect(el._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(null);
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
// el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
||||||
|
mimicKeyPress(el._inputNode, 'ArrowDown');
|
||||||
expect(el._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
expect(el._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
||||||
'artichoke-option',
|
'artichoke-option',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,15 @@ import sinon from 'sinon';
|
||||||
|
|
||||||
const fixture = /** @type {(arg: TemplateResult) => Promise<LionListbox>} */ (_fixture);
|
const fixture = /** @type {(arg: TemplateResult) => Promise<LionListbox>} */ (_fixture);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} el
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
function mimicKeyPress(el, key) {
|
||||||
|
el.dispatchEvent(new KeyboardEvent('keydown', { key }));
|
||||||
|
el.dispatchEvent(new KeyboardEvent('keyup', { key }));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {LionListbox} lionListboxEl
|
* @param {LionListbox} lionListboxEl
|
||||||
*/
|
*/
|
||||||
|
|
@ -382,7 +391,8 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(activeDescendantOwner.getAttribute('aria-activedescendant')).to.equal('first');
|
expect(activeDescendantOwner.getAttribute('aria-activedescendant')).to.equal('first');
|
||||||
activeDescendantOwner.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(activeDescendantOwner, 'ArrowDown');
|
||||||
|
// activeDescendantOwner.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(activeDescendantOwner.getAttribute('aria-activedescendant')).to.equal('second');
|
expect(activeDescendantOwner.getAttribute('aria-activedescendant')).to.equal('second');
|
||||||
});
|
});
|
||||||
|
|
@ -537,12 +547,17 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
// Normalize
|
// Normalize
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
const options = el.formElements;
|
const options = el.formElements;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
// mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
|
mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
expect(options[0].active).to.be.true;
|
expect(options[0].active).to.be.true;
|
||||||
expect(options[1].active).to.be.false;
|
expect(options[1].active).to.be.false;
|
||||||
expect(options[2].active).to.be.false;
|
expect(options[2].active).to.be.false;
|
||||||
el.activeIndex = 2;
|
el.activeIndex = 2;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
// mimicKeyPress(listbox, 'ArrowDown');
|
||||||
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
|
|
||||||
expect(options[0].active).to.be.false;
|
expect(options[0].active).to.be.false;
|
||||||
expect(options[1].active).to.be.false;
|
expect(options[1].active).to.be.false;
|
||||||
expect(options[2].active).to.be.true;
|
expect(options[2].active).to.be.true;
|
||||||
|
|
@ -563,14 +578,20 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
|
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
// el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
||||||
|
mimicKeyPress(el._inputNode, 'ArrowUp');
|
||||||
|
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.activeIndex).to.equal(2);
|
expect(el.activeIndex).to.equal(2);
|
||||||
|
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
// el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
||||||
|
mimicKeyPress(el._inputNode, 'ArrowDown');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
// Extra check: regular navigation
|
// Extra check: regular navigation
|
||||||
el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
// el._inputNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
||||||
|
mimicKeyPress(el._inputNode, 'ArrowDown');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -590,8 +611,8 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
const options = el.formElements;
|
const options = el.formElements;
|
||||||
el.checkedIndex = 0;
|
el.checkedIndex = 0;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
expect(options[1].checked).to.be.true;
|
expect(options[1].checked).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -613,14 +634,16 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
const options = el.formElements;
|
const options = el.formElements;
|
||||||
el.checkedIndex = 0;
|
el.checkedIndex = 0;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' }));
|
mimicKeyPress(listbox, ' ');
|
||||||
|
|
||||||
expect(options[1].checked).to.be.true;
|
expect(options[1].checked).to.be.true;
|
||||||
el.checkedIndex = 0;
|
el.checkedIndex = 0;
|
||||||
// @ts-ignore allow protected member access in test
|
// @ts-ignore allow protected member access in test
|
||||||
el._listboxReceivesNoFocus = true;
|
el._listboxReceivesNoFocus = true;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' }));
|
mimicKeyPress(listbox, ' ');
|
||||||
|
|
||||||
expect(options[1].checked).to.be.false;
|
expect(options[1].checked).to.be.false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -668,9 +691,9 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
el.activeIndex = 2;
|
el.activeIndex = 2;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home' }));
|
mimicKeyPress(listbox, 'Home');
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'End' }));
|
mimicKeyPress(listbox, 'End');
|
||||||
expect(el.activeIndex).to.equal(3);
|
expect(el.activeIndex).to.equal(3);
|
||||||
});
|
});
|
||||||
it('navigates through open lists with [ArrowDown] [ArrowUp] keys activates the option', async () => {
|
it('navigates through open lists with [ArrowDown] [ArrowUp] keys activates the option', async () => {
|
||||||
|
|
@ -690,10 +713,11 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
el.selectionFollowsFocus = false;
|
el.selectionFollowsFocus = false;
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(-1);
|
expect(el.checkedIndex).to.equal(-1);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
expect(el.checkedIndex).to.equal(-1);
|
expect(el.checkedIndex).to.equal(-1);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(-1);
|
expect(el.checkedIndex).to.equal(-1);
|
||||||
});
|
});
|
||||||
|
|
@ -718,21 +742,24 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
expect(options[0].active).to.be.true;
|
expect(options[0].active).to.be.true;
|
||||||
expect(options[1].active).to.be.false;
|
expect(options[1].active).to.be.false;
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(options[0].active).to.be.false;
|
expect(options[0].active).to.be.false;
|
||||||
expect(options[1].active).to.be.true;
|
expect(options[1].active).to.be.true;
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
expect(options[0].active).to.be.true;
|
expect(options[0].active).to.be.true;
|
||||||
expect(options[1].active).to.be.false;
|
expect(options[1].active).to.be.false;
|
||||||
|
|
||||||
// No response to horizontal arrows...
|
// No response to horizontal arrows...
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
|
mimicKeyPress(listbox, 'ArrowRight');
|
||||||
|
|
||||||
expect(options[0].active).to.be.true;
|
expect(options[0].active).to.be.true;
|
||||||
expect(options[1].active).to.be.false;
|
expect(options[1].active).to.be.false;
|
||||||
|
|
||||||
el.activeIndex = 1;
|
el.activeIndex = 1;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }));
|
mimicKeyPress(listbox, 'ArrowLeft');
|
||||||
|
|
||||||
expect(options[0].active).to.be.false;
|
expect(options[0].active).to.be.false;
|
||||||
expect(options[1].active).to.be.true;
|
expect(options[1].active).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
@ -753,18 +780,21 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
|
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
|
mimicKeyPress(listbox, 'ArrowRight');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }));
|
mimicKeyPress(listbox, 'ArrowLeft');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
|
|
||||||
// No response to vertical arrows...
|
// No response to vertical arrows...
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
|
|
||||||
el.activeIndex = 1;
|
el.activeIndex = 1;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -834,13 +864,13 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
|
|
||||||
// Enter
|
// Enter
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
el.activeIndex = 1;
|
el.activeIndex = 1;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
expect(options[0].checked).to.equal(true);
|
expect(options[0].checked).to.equal(true);
|
||||||
expect(el.modelValue).to.eql(['Artichoke', 'Chard']);
|
expect(el.modelValue).to.eql(['Artichoke', 'Chard']);
|
||||||
// also deselect
|
// also deselect
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
expect(options[0].checked).to.equal(true);
|
expect(options[0].checked).to.equal(true);
|
||||||
expect(el.modelValue).to.eql(['Artichoke']);
|
expect(el.modelValue).to.eql(['Artichoke']);
|
||||||
|
|
||||||
|
|
@ -855,13 +885,16 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
|
|
||||||
// Space
|
// Space
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' }));
|
mimicKeyPress(listbox, ' ');
|
||||||
|
|
||||||
el.activeIndex = 1;
|
el.activeIndex = 1;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' }));
|
mimicKeyPress(listbox, ' ');
|
||||||
|
|
||||||
expect(options[0].checked).to.equal(true);
|
expect(options[0].checked).to.equal(true);
|
||||||
expect(el.modelValue).to.eql(['Artichoke', 'Chard']);
|
expect(el.modelValue).to.eql(['Artichoke', 'Chard']);
|
||||||
// also deselect
|
// also deselect
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: ' ' }));
|
mimicKeyPress(listbox, ' ');
|
||||||
|
|
||||||
expect(options[0].checked).to.equal(true);
|
expect(options[0].checked).to.equal(true);
|
||||||
expect(el.modelValue).to.eql(['Artichoke']);
|
expect(el.modelValue).to.eql(['Artichoke']);
|
||||||
});
|
});
|
||||||
|
|
@ -925,11 +958,12 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
expect(el.checkedIndex).to.equal(1);
|
expect(el.checkedIndex).to.equal(1);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 1);
|
expectOnlyGivenOneOptionToBeChecked(options, 1);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
|
mimicKeyPress(listbox, 'ArrowUp');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
||||||
|
|
@ -964,11 +998,13 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }));
|
mimicKeyPress(listbox, 'ArrowRight');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
expect(el.checkedIndex).to.equal(1);
|
expect(el.checkedIndex).to.equal(1);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 1);
|
expectOnlyGivenOneOptionToBeChecked(options, 1);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }));
|
mimicKeyPress(listbox, 'ArrowLeft');
|
||||||
|
|
||||||
expect(el.activeIndex).to.equal(0);
|
expect(el.activeIndex).to.equal(0);
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
expectOnlyGivenOneOptionToBeChecked(options, 0);
|
||||||
|
|
@ -990,9 +1026,9 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(el.modelValue).to.equal('30');
|
expect(el.modelValue).to.equal('30');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home' }));
|
mimicKeyPress(listbox, 'Home');
|
||||||
expect(el.modelValue).to.equal('10');
|
expect(el.modelValue).to.equal('10');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'End' }));
|
mimicKeyPress(listbox, 'End');
|
||||||
expect(el.modelValue).to.equal('40');
|
expect(el.modelValue).to.equal('40');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1009,7 +1045,7 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
|
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
const { checkedIndex } = el;
|
const { checkedIndex } = el;
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.checkedIndex).to.equal(checkedIndex);
|
expect(el.checkedIndex).to.equal(checkedIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1065,11 +1101,11 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
// Normalize activeIndex across multiple implementers of ListboxMixinSuite
|
// Normalize activeIndex across multiple implementers of ListboxMixinSuite
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
|
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
// Checked index stays where it was
|
// Checked index stays where it was
|
||||||
expect(el.checkedIndex).to.equal(0);
|
expect(el.checkedIndex).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
@ -1087,11 +1123,11 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
// Normalize activeIndex across multiple implementers of ListboxMixinSuite
|
// Normalize activeIndex across multiple implementers of ListboxMixinSuite
|
||||||
el.activeIndex = 0;
|
el.activeIndex = 0;
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(1);
|
expect(el.activeIndex).to.equal(1);
|
||||||
expect(el.checkedIndex).to.equal(-1);
|
expect(el.checkedIndex).to.equal(-1);
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
|
mimicKeyPress(listbox, 'ArrowDown');
|
||||||
expect(el.activeIndex).to.equal(2);
|
expect(el.activeIndex).to.equal(2);
|
||||||
expect(el.checkedIndex).to.equal(2);
|
expect(el.checkedIndex).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
@ -1318,8 +1354,7 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
// Allow options that behave like anchors (think of Google Search) to trigger the anchor behavior
|
// Allow options that behave like anchors (think of Google Search) to trigger the anchor behavior
|
||||||
const activeOption = el.formElements[1];
|
const activeOption = el.formElements[1];
|
||||||
const clickSpy = sinon.spy(activeOption, 'click');
|
const clickSpy = sinon.spy(activeOption, 'click');
|
||||||
|
mimicKeyPress(listbox, 'Enter');
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
|
||||||
|
|
||||||
expect(clickSpy).to.have.been.calledOnce;
|
expect(clickSpy).to.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
@ -1339,7 +1374,7 @@ export function runListboxMixinSuite(customConfig = {}) {
|
||||||
const activeOption = el.formElements[0];
|
const activeOption = el.formElements[0];
|
||||||
const clickSpy = sinon.spy(activeOption, 'click');
|
const clickSpy = sinon.spy(activeOption, 'click');
|
||||||
|
|
||||||
listbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));
|
mimicKeyPress(listbox, 'Enter');
|
||||||
|
|
||||||
expect(clickSpy).to.not.have.been.called;
|
expect(clickSpy).to.not.have.been.called;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue