import { Required } from '@lion/form-core'; import { expect, html, triggerBlurFor, triggerFocusFor, fixture } from '@open-wc/testing'; import '@lion/core/src/differentKeyEventNamesShimIE.js'; import '@lion/listbox/lion-option.js'; import '@lion/listbox/lion-options.js'; import '../lion-select-rich.js'; describe('lion-select-rich interactions', () => { describe('Keyboard navigation', () => { it('navigates to first and last option with [Home] and [End] keys', async () => { const el = await fixture(html` Item 1 Item 2 Item 3 Item 4 `); expect(el.modelValue).to.equal(30); el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home' })); expect(el.modelValue).to.equal(10); el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'End' })); expect(el.modelValue).to.equal(40); }); }); describe('Keyboard navigation Windows', () => { it('navigates through list with [ArrowDown] [ArrowUp] keys activates and checks the option', async () => { function expectOnlyGivenOneOptionToBeChecked(options, selectedIndex) { options.forEach((option, i) => { if (i === selectedIndex) { expect(option.checked).to.be.true; } else { expect(option.checked).to.be.false; } }); } const el = await fixture(html` Item 1 Item 2 Item 3 `); const options = Array.from(el.querySelectorAll('lion-option')); expect(el.activeIndex).to.equal(0); expect(el.checkedIndex).to.equal(0); expectOnlyGivenOneOptionToBeChecked(options, 0); el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' })); expect(el.activeIndex).to.equal(1); expect(el.checkedIndex).to.equal(1); expectOnlyGivenOneOptionToBeChecked(options, 1); el._listboxNode.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' })); expect(el.activeIndex).to.equal(0); expect(el.checkedIndex).to.equal(0); expectOnlyGivenOneOptionToBeChecked(options, 0); }); it('navigates through list with [ArrowDown] [ArrowUp] keys checks the option while listbox unopened', async () => { function expectOnlyGivenOneOptionToBeChecked(options, selectedIndex) { options.forEach((option, i) => { if (i === selectedIndex) { expect(option.checked).to.be.true; } else { expect(option.checked).to.be.false; } }); } const el = await fixture(html` Item 1 Item 2 Item 3 `); const options = Array.from(el.querySelectorAll('lion-option')); expect(el.checkedIndex).to.equal(0); expectOnlyGivenOneOptionToBeChecked(options, 0); el.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' })); expect(el.checkedIndex).to.equal(1); expectOnlyGivenOneOptionToBeChecked(options, 1); el.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowUp' })); expect(el.checkedIndex).to.equal(0); expectOnlyGivenOneOptionToBeChecked(options, 0); }); }); describe('Disabled', () => { it('cannot be focused if disabled', async () => { const el = await fixture(html` `); expect(el._invokerNode.tabIndex).to.equal(-1); }); it('cannot be opened via click if disabled', async () => { const el = await fixture(html` `); el._invokerNode.click(); expect(el.opened).to.be.false; }); it('reflects disabled attribute to invoker', async () => { const el = await fixture(html` `); expect(el._invokerNode.hasAttribute('disabled')).to.be.true; el.removeAttribute('disabled'); await el.updateComplete; expect(el._invokerNode.hasAttribute('disabled')).to.be.false; }); }); describe('Interaction states', () => { it('becomes touched if blurred once', async () => { const el = await fixture(html` Item 1 Item 2 `); expect(el.touched).to.be.false; await triggerFocusFor(el._invokerNode); await triggerBlurFor(el._invokerNode); expect(el.touched).to.be.true; }); }); describe('Accessibility', () => { it('sets [aria-invalid="true"] to "._invokerNode" when there is an error', async () => { const el = await fixture(html` Please select a value Item 1 `); const invokerNode = el._invokerNode; const options = el.querySelectorAll('lion-option'); await el.feedbackComplete; await el.updateComplete; expect(invokerNode.getAttribute('aria-invalid')).to.equal('false'); options[0].checked = true; await el.feedbackComplete; await el.updateComplete; expect(invokerNode.getAttribute('aria-invalid')).to.equal('true'); options[1].checked = true; await el.feedbackComplete; await el.updateComplete; expect(invokerNode.getAttribute('aria-invalid')).to.equal('false'); }); }); });