| import './index'; |
| |
| import { $, $$ } from 'common-sk/modules/dom'; |
| |
| import { languageList } from './test_data'; |
| import { |
| eventPromise, |
| setUpElementUnderTest |
| } from '../../../infra-sk/modules/test_util'; |
| |
| const DOWN_ARROW = 40; |
| const UP_ARROW = 38; |
| const ENTER = 13; |
| |
| describe('suggest-input-sk', () => { |
| // Function to create a new suggest-input-sk, options to give the element |
| // can be passed in, and default to a list of programming languages. |
| const newInstance = setUpElementUnderTest('suggest-input-sk'); |
| |
| let suggestInput; |
| beforeEach(() => { |
| suggestInput = newInstance((el) => { |
| el.options = languageList; |
| }); |
| }); |
| |
| // Simulates up/down/enter navigation through suggestion list. |
| const simulateKeyboardNavigation = (code) => { |
| $$('input', suggestInput).dispatchEvent( |
| new KeyboardEvent('keyup', { keyCode: code }), |
| ); |
| }; |
| |
| const simulateUserClick = () => { |
| $$('input', suggestInput).focus(); |
| }; |
| |
| const simulateUserClickAway = () => { |
| $$('input', suggestInput).blur(); |
| }; |
| |
| // Simulates a user typing 'value' into the input element by setting its |
| // value and triggering the built-in 'input' event. |
| const simulateUserTyping = (value) => { |
| const ele = $$('input', suggestInput); |
| ele.focus(); |
| ele.value = value; |
| ele.dispatchEvent(new Event('input', { |
| bubbles: true, |
| cancelable: true, |
| })); |
| }; |
| |
| it('hides suggestions initially', () => { |
| expect($$('.suggest-list', suggestInput)).to.have.property('hidden', true); |
| }); |
| |
| it('shows suggestions when in focus', () => { |
| simulateUserClick(); |
| expect($$('input', suggestInput)).to.equal(document.activeElement); |
| expect($$('.suggest-list', suggestInput)).to.have.property('hidden', false); |
| expect($('li', suggestInput).length).to.equal(languageList.length); |
| // Expect doesn't handle real JS arrays well in all cases, we need the |
| // original NodeList. |
| expect(suggestInput.querySelectorAll('li')).to.contain.text([ |
| 'golang', |
| 'c++', |
| 'JavaScript', |
| 'TypeScript', |
| 'Python', |
| 'Python2.7', |
| 'Python3', |
| 'IronPython']); |
| }); |
| |
| it('hides suggestions when loses focus', () => { |
| simulateUserClick(); |
| simulateUserClickAway(); |
| expect($$('.suggest-list', suggestInput)).to.have.property('hidden', true); |
| }); |
| |
| it('shows only suggestions that substring match', () => { |
| simulateUserTyping('script'); |
| |
| expect($$('.suggest-list', suggestInput)).to.have.property('hidden', false); |
| expect($('li', suggestInput).length).to.equal(2); |
| // Expect doesn't handle real JS arrays well in all cases, we need the |
| // original NodeList. |
| expect(suggestInput.querySelectorAll('li')) |
| .to.contain.text(['JavaScript', 'TypeScript']); |
| expect(suggestInput.querySelectorAll('li')) |
| .to.not.contain.text(['Python', 'golang', 'c++']); |
| |
| simulateUserTyping('scriptz'); |
| expect($('li', suggestInput).length).to.equal(0); |
| simulateUserTyping(''); |
| expect($('li', suggestInput).length).to.equal(languageList.length); |
| }); |
| |
| it('shows only suggestions that regex match', () => { |
| simulateUserTyping('.*'); |
| expect($('li', suggestInput).length).to.equal(languageList.length); |
| simulateUserTyping('[0-9]'); |
| expect($('li', suggestInput).length).to.equal(2); |
| // Expect doesn't handle real JS arrays well in all cases, we need the |
| // original NodeList. |
| expect(suggestInput.querySelectorAll('li')) |
| .to.contain.text(['Python2.7', 'Python3']); |
| }); |
| |
| it('selects suggestion by click', async () => { |
| simulateUserTyping('Python'); |
| expect($('li', suggestInput).length).to.equal(4); |
| // Expect doesn't handle real JS arrays well in all cases, we need the |
| // original NodeList. |
| expect(suggestInput.querySelectorAll('li')) |
| .to.contain.text(['Python', 'Python2.7', 'Python3', 'IronPython']); |
| const valueChangedEvent = eventPromise('value-changed'); |
| // Click 'Python2.7'. |
| $('li', suggestInput)[1].dispatchEvent( |
| new MouseEvent('click', { bubbles: true, cancelable: true }), |
| ); |
| const selectionMade = await valueChangedEvent; |
| expect(selectionMade.detail.value).to.equal('Python2.7'); |
| expect($$('input', suggestInput).value).to.equal('Python2.7'); |
| }); |
| |
| it('select suggestion by arrows/enter', () => { |
| simulateUserTyping('Python[0-9]'); |
| expect($('li', suggestInput).length).to.equal(2); |
| // Expect doesn't handle real JS arrays well in all cases, we need the |
| // original NodeList. |
| expect(suggestInput.querySelectorAll('li')) |
| .to.contain.text(['Python2.7', 'Python3']); |
| // Helper to check that only the expected list item is selected. |
| const checkSelected = (expected) => { |
| const selected = suggestInput.querySelectorAll('li.selected'); |
| expect(selected).to.have.lengthOf(1).and.have.text([expected]); |
| }; |
| // Navigate down the list. |
| simulateKeyboardNavigation(DOWN_ARROW); |
| checkSelected('Python2.7'); |
| simulateKeyboardNavigation(DOWN_ARROW); |
| checkSelected('Python3'); |
| // Wrap around. |
| simulateKeyboardNavigation(DOWN_ARROW); |
| checkSelected('Python2.7'); |
| // And back up. |
| simulateKeyboardNavigation(UP_ARROW); |
| checkSelected('Python3'); |
| // Select. |
| simulateKeyboardNavigation(ENTER); |
| expect($$('input', suggestInput).value).to.equal('Python3'); |
| }); |
| |
| it('select suggestion by arrows/blur', () => { |
| simulateUserTyping('Python[0-9]'); |
| // Go to first suggestion (Python2.7) |
| simulateKeyboardNavigation(DOWN_ARROW); |
| simulateUserClickAway(); |
| expect($$('input', suggestInput).value).to.equal('Python2.7'); |
| }); |
| |
| it('clears on unlisted value without acceptCustomValue', () => { |
| simulateUserTyping('blarg'); |
| simulateUserClickAway(); |
| expect($$('input', suggestInput).value).to.equal(''); |
| }); |
| |
| it('accepts unlisted value with acceptCustomValue', () => { |
| suggestInput.acceptCustomValue = true; |
| simulateUserTyping('blarg'); |
| simulateUserClickAway(); |
| expect($$('input', suggestInput).value).to.equal('blarg'); |
| }); |
| }); |