UNPKG

custom-select

Version:

A lightweight JavaScript library for custom HTML <select> creation and managing. No dependencies needed.

307 lines (232 loc) 8.4 kB
import test from 'tape'; import customSelect from './../'; var options; var select1; var select2; var eventMessage; test('On click opens the panel', assert => { document.body.innerHTML = ''; select1 = document.createElement('select'); select1.innerHTML = ` <option value="">Select...</option> <optgroup label="Cars"> <option value="ferrari">Ferrari</option> </optgroup> <optgroup label="Motorcycles"> <option value="honda">Honda</option> </optgroup>`; document.body.appendChild(select1); const cstSelects = customSelect('select'); options = cstSelects[0].pluginOptions; document.getElementsByClassName(options.openerClass)[0].children[0].click(); const actual = document.getElementsByClassName(options.containerClass)[0] .classList.contains('is-open'); assert.true(actual, 'should return true'); assert.end(); }); test('On click on second select closes the first...', assert => { select2 = document.createElement('select'); select2.innerHTML = ` <option value="">Select...</option> <option value="apple">Apple</option> <option value="banana">Banana</option>; <option value="avocado">Avocado</option>`; document.body.appendChild(select2); customSelect(select2); document.getElementsByClassName(options.openerClass)[1].click(); const actual = document.getElementsByClassName(options.containerClass)[0] .classList.contains('is-open'); assert.false(actual, 'should return false'); assert.end(); }); test('... opens the second panel.', assert => { const actual = document.getElementsByClassName(options.containerClass)[1] .classList.contains('is-open'); assert.true(actual, 'should return true'); assert.end(); }); test('On click outside the selects closes the opened one', assert => { document.body.click(); const actual = document.querySelectorAll('.is-open').length; const expected = 0; assert.deepEqual(actual, expected, 'should return 0'); assert.end(); }); test('On click on an option sets selected class', assert => { // Add change events listener for next test select1.addEventListener('change', () => { eventMessage = 'First select has changed it\'s value'; }); // first select document.getElementsByClassName(options.openerClass)[1].parentNode.customSelect.open = true; document.getElementsByClassName(options.optionClass)[2].click(); const actual = document.querySelectorAll(`.${options.optionClass}`)[2] .classList.contains('is-selected'); assert.true(actual, 'should return true'); assert.end(); }); test('... and focus class', assert => { const actual = document.getElementsByClassName(options.optionClass)[2] .classList.contains('has-focus'); assert.true(actual, 'should return true'); assert.end(); }); test('... and closes the select', assert => { const actual = document.getElementsByTagName('select')[0].parentNode.customSelect.open; assert.false(actual, 'should return false'); assert.end(); }); test('... and sets the original select value', assert => { const actual = document.getElementsByTagName('select')[0].value; const expected = 'honda'; assert.deepEqual(actual, expected, 'should return honda'); assert.end(); }); test('... and there is only one selected option', assert => { const actual = document.getElementsByTagName('select')[0] .parentNode.querySelectorAll('.is-selected').length; const expected = 1; assert.deepEqual(actual, expected, 'should return 1'); assert.end(); }); test('... and updates opener text', assert => { const actual = document.getElementsByTagName('select')[0] .parentNode.getElementsByClassName(options.openerClass)[0].children[0].textContent; const expected = 'Honda'; assert.deepEqual(actual, expected, 'should return Honda'); assert.end(); }); test('... and dispatches the change event', assert => { assert.equal(eventMessage, 'First select has changed it\'s value', 'First select has changed it\'s value'); assert.end(); }); test('On keydown on the first select...', assert => { var actual; var expected; // first select container const currentContainer = document.getElementsByTagName('select')[0].parentNode; const e = new KeyboardEvent('keydown', {}); currentContainer.focus(); assert.test('... ArrowDown opens the panel', q => { Object.defineProperty(e, 'keyCode', { value: 40, writable: true }); currentContainer.dispatchEvent(e); actual = currentContainer.customSelect.open; q.true(actual, 'should return true'); q.end(); }); assert.test('... with a second ArrowDown the focus remains on the last option', q => { currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').getAttribute('data-value'); expected = 'honda'; q.deepEqual(actual, expected, 'should return honda'); q.end(); }); assert.test('... an ArrowUp sets the focus on the prev option', q => { e.keyCode = 38; currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').getAttribute('data-value'); expected = 'ferrari'; q.deepEqual(actual, expected, 'should return ferrari'); q.end(); }); assert.test('... a second ArrowUp sets the focus on first option', q => { currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').getAttribute('data-value'); expected = ''; q.deepEqual(actual, expected, 'should return ""'); q.end(); }); assert.test('... with a third ArrowUp the focus remains on the first option', q => { currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').getAttribute('data-value'); expected = ''; q.deepEqual(actual, expected, 'should return ""'); q.end(); }); assert.end(); }); test('On keydown on the second select...', assert => { var actual; var expected; // Second select container const currentContainer = document.getElementsByTagName('select')[1].parentNode; const e = new KeyboardEvent('keydown', {}); currentContainer.focus(); assert.test('... Space opens the panel', q => { Object.defineProperty(e, 'keyCode', { value: 32, writable: true }); currentContainer.dispatchEvent(e); actual = currentContainer.classList.contains('is-open'); q.true(actual, 'should return true'); q.end(); }); assert.test('... letter "a" sets focus on the apple option', q => { e.keyCode = 65; currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').textContent; expected = 'Apple'; q.deepEqual(actual, expected, 'should return Apple'); q.end(); }); assert.test('... adding letter "v" sets focus on the avocado option', q => { e.keyCode = 86; currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').textContent; expected = 'Avocado'; q.deepEqual(actual, expected, 'should return Avocado'); q.end(); }); assert.test('... after 2 secs with letter "b" sets focus on banana option', q => { setTimeout(() => { e.keyCode = 66; currentContainer.dispatchEvent(e); actual = currentContainer.querySelector('.has-focus').getAttribute('data-value'); expected = 'banana'; q.deepEqual(actual, expected, 'should return banana'); q.end(); }, 2000); }); assert.test('Enter closes the panel', q => { // Add change events listener for next test select2.addEventListener('change', () => { eventMessage = 'Second select has changed it\'s value'; }); // Resets the eventMessage value for further checks eventMessage = false; e.keyCode = 13; currentContainer.dispatchEvent(e); q.false(currentContainer.customSelect.container.classList.contains('is-open'), 'should return false'); q.end(); }); assert.test('... and changes the select value', q => { actual = currentContainer.children[1].value; expected = 'banana'; q.deepEqual(actual, expected, 'should return "banana"'); q.end(); }); assert.test('... and dispatches the change event', q => { q.equal(eventMessage, 'Second select has changed it\'s value', 'Second select has changed it\'s value'); q.end(); }); assert.end(); });