UNPKG

wix-style-react

Version:
618 lines (522 loc) • 26.1 kB
'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _jestSetup = require('wix-ui-test-utils/dist/src/jest-setup'); var _DropdownLayout = require('./DropdownLayout'); var _DropdownLayout2 = _interopRequireDefault(_DropdownLayout); var _DropdownLayout3 = require('./DropdownLayout.driver'); var _DropdownLayout4 = _interopRequireDefault(_DropdownLayout3); var _react3 = require('../../test/utils/react'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } describe('DropdownLayout', function () { var render = (0, _react3.createRendererWithDriver)(_DropdownLayout4.default); var createDriver = function createDriver(jsx) { return render(jsx).driver; }; afterEach(function () { (0, _react3.cleanup)(); }); var options = [{ id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3', disabled: true }, { id: 3, value: 'Option 4' }, { id: 'divider1', value: '-' }, { id: 'element1', value: _react2.default.createElement( 'span', { style: { color: 'brown' } }, 'Option 4' ) }, { value: '-' }]; it('should have be invisible and drop down by default', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { options: options })); expect(driver.isShown()).toBeFalsy(); expect(driver.isDown()).toBeTruthy(); }); it('should throw an error when trying to click on a non exists option', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(function () { return driver.clickAtOption(20); }).toThrow(); }); it('should focus on selected option', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { focusOnSelectedOption: true, visible: true, options: options, selectedId: 3 })); expect(driver.optionsScrollTop()).toBe(0); }); it('should be visible and drop down', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.isShown()).toBeTruthy(); expect(driver.isDown()).toBeTruthy(); }); it('should have all options values in dropdown list', function () { var _options = [{ id: 0, value: 'Option 1' }, { id: 1, value: 'Option 2' }, { id: 2, value: 'Option 3' }]; var optionsContent = _options.map(function (option) { return option.value; }); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { options: _options })); expect(driver.optionsContent()).toEqual(optionsContent); }); it('should hide dropdown on outside click', function () { var _render = render(_react2.default.createElement(_DropdownLayout2.default, { onClickOutside: function onClickOutside() { return rerender(_react2.default.createElement(_DropdownLayout2.default, { visible: false, options: options })); }, visible: true, options: options })), driver = _render.driver, rerender = _render.rerender; expect(driver.isShown()).toBeTruthy(); driver.mouseClickOutside(); expect(driver.isShown()).toBeFalsy(); }); it('should have a default tab index', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.tabIndex()).toBe(0); }); it('should have options', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.optionsLength()).toBe(7); expect(driver.optionContentAt(0)).toBe('Option 1'); expect(driver.isOptionADivider(4)).toBeTruthy(); expect(driver.optionByHook('dropdown-divider-divider1').isDivider()).toBeTruthy(); expect(driver.optionContentAt(5)).toBe('Option 4'); expect(driver.isOptionADivider(6)).toBeTruthy(); expect(driver.optionByHook('dropdown-divider-6').isDivider()).toBeTruthy(); }); it('should call onClose when esc key is pressed', function () { var onClose = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onClose: onClose })); driver.mouseEnterAtOption(0); driver.pressEscKey(); expect(onClose).toBeCalled(); }); it('should click an option by value', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.clickAtOptionWithValue('Option 4'); expect(onSelect).toBeCalledWith(options[3], false); }); describe('onSelect', function () { describe('with selectedId', function () { it('should call onSelect with true value when clicking on a selected option', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect, selectedId: 0 })); driver.clickAtOption(0); expect(onSelect).toBeCalledWith(options[0], true); }); it('should call onSelect with false value when clicking on a selected option by hook', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect, selectedId: 0 })); driver.optionByHook('dropdown-item-3').click(); expect(onSelect).toBeCalledWith(options[3], false); }); }); describe('without selectedId', function () { it('should nofity a new option was selected for first selection', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.clickAtOption(0); expect(onSelect).toBeCalledWith(options[0], false); }); it('should nofity a new option was selected after a value was previously selected', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.clickAtOption(0); driver.clickAtOption(1); expect(onSelect).toHaveBeenLastCalledWith(options[1], false); }); it('should nofity the same option was selected', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.clickAtOption(0); driver.clickAtOption(0); expect(onSelect).toHaveBeenLastCalledWith(options[0], true); }); }); describe('keyboard events', function () { it('should call onSelect when enter key is pressed', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.pressDownKey(); driver.pressEnterKey(); expect(onSelect).toBeCalled(); }); it('should call onSelect when space key is pressed', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.pressDownKey(); driver.pressSpaceKey(); expect(onSelect).toBeCalled(); }); it('should call onSelect when tab key is pressed', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.pressDownKey(); driver.pressTabKey(); expect(onSelect).toBeCalled(); }); it('should not call onSelect when composing text via external means', function () { var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect })); driver.pressEnterKey(); expect(onSelect).not.toBeCalled(); }); }); }); it('should render a function option with the rendered item props', function () { var selectedId = 0; var unSelectedId = 1; var optionsWithFuncValues = [{ id: 0, value: function value(_ref) { var selected = _ref.selected; return _react2.default.createElement( 'div', null, 'option ', selected ? 'selected' : 'not selected' ); } }, { id: 1, value: function value(_ref2) { var selected = _ref2.selected; return _react2.default.createElement( 'div', null, 'option ', selected ? 'selected' : 'not selected' ); } }]; var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: optionsWithFuncValues, selectedId: selectedId })); expect(driver.optionContentAt(selectedId)).toEqual('option selected'); expect(driver.optionContentAt(unSelectedId)).toEqual('option not selected'); }); it('should select the chosen value', function () { var selectedId = 0; var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, selectedId: selectedId })); expect(driver.isOptionSelected(0)).toBeTruthy(); expect(driver.optionByHook('dropdown-item-0').isSelected()).toBeTruthy(); }); it('should remember the selected option when getting re-opened after got closed', function () { var selectedId = 1; var props = { visible: true, options: options, selectedId: selectedId }; var _render2 = render(_react2.default.createElement(_DropdownLayout2.default, props)), driver = _render2.driver, rerender = _render2.rerender; expect(driver.isOptionSelected(selectedId)).toBeTruthy(); rerender(_react2.default.createElement(_DropdownLayout2.default, _extends({}, props, { visible: false }))); rerender(_react2.default.createElement(_DropdownLayout2.default, _extends({}, props, { visible: true }))); expect(driver.isOptionSelected(selectedId)).toBeTruthy(); }); it('should select the chosen value when overrideStyle is true', function () { var selectedId = 0; var _options = [{ id: 0, value: 'Option 1', overrideStyle: true }]; var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: _options, selectedId: selectedId })); expect(driver.isOptionSelectedWithGlobalClassName(0)).toBeTruthy(); expect(driver.optionByHook('dropdown-item-0').isSelectedWithGlobalClassName()).toBeTruthy(); }); it('should not contain pointer arrow without the withArrow property', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.hasTopArrow()).toBeFalsy(); }); it('should contain pointer arrow when withArrow property is true', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, withArrow: true, options: options })); expect(driver.hasTopArrow()).toBeTruthy(); }); it('should support mouse events', function () { var onMouseEnter = jest.fn(); var onMouseLeave = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave })); driver.mouseEnter(); expect(onMouseEnter).toBeCalled(); expect(onMouseLeave).not.toBeCalled(); driver.mouseLeave(); expect(onMouseLeave).toBeCalled(); }); describe('itemHeight prop', function () { it('should be small by default', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.isOptionHeightSmall(0)).toBe(true); }); it('should be small', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, itemHeight: 'small' })); expect(driver.isOptionHeightSmall(0)).toBe(true); }); it('should be big', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, itemHeight: 'big' })); expect(driver.isOptionHeightBig(0)).toBe(true); }); }); describe('selectedHighlight prop', function () { var selectedId = 0; it('should be true by default', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, selectedId: selectedId })); expect(driver.optionById(selectedId).isSelected()).toBe(true); }); describe('when true', function () { it('should give the option a selected classname', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { selectedHighlight: true, visible: true, options: options, selectedId: selectedId })); expect(driver.optionById(selectedId).isSelected()).toBeTruthy(); }); }); describe('when false', function () { it('should not give the option a selected classname', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { selectedHighlight: false, visible: true, options: options, selectedId: selectedId })); expect(driver.optionById(selectedId).isSelected()).toBeFalsy(); }); }); }); describe('options that are links', function () { it('should not be link by default', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(driver.isLinkOption(0)).toBe(false); }); it('should be a link option', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options.map(function (opt) { return _extends({}, opt, { linkTo: 'http://wix.com' }); }) })); expect(driver.isLinkOption(0)).toBe(true); }); }); describe('controlled and uncontrolled logic', function () { describe('controlled', function () { it('should work as a controlled component when selectedId an onSelect are given', function () { //give selectedId and onSelect var onSelect = jest.fn(); var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: onSelect, selectedId: 0 })); //select item driver.clickAtOption(1); //expect internal state to not change expect(driver.isOptionSelected(0)).toBeTruthy(); }); }); describe('uncontrolled', function () { it('should work as an uncontrolled component when only selectedId is supplied', function () { //give selectedId var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, selectedId: 0 })); //select item driver.clickAtOption(1); //expect internal state to change expect(driver.isOptionSelected(1)).toBeTruthy(); }); it('should work as an uncontrolled component when only onSelect is supplied', function () { //give onSelect var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options, onSelect: jest.fn() })); //select item driver.clickAtOption(1); //expect internal state to change expect(driver.isOptionSelected(1)).toBeTruthy(); }); }); }); describe('hover logic', function () { it('should not hover any option by default', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); expect(options.map(function (option, index) { return driver.isOptionHovered(index); })).not.toContain(true); }); it('should hover starting from the top', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.pressDownKey(); expect(driver.isOptionHovered(0)).toBeTruthy(); }); it('should hover starting from the selected item', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.clickAtOption(0); driver.pressDownKey(); expect(driver.isOptionHovered(1)).toBeTruthy(); }); it('should hover when mouse enter and unhover when mouse leave', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.mouseEnterAtOption(0); expect(driver.isOptionHovered(0)).toBeTruthy(); driver.mouseLeaveAtOption(0); expect(driver.isOptionHovered(0)).toBeFalsy(); }); it('should hover when mouse enter and unhover when mouse leave by data hook', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); var option = driver.optionByHook('dropdown-item-0'); option.mouseEnter(); expect(option.isHovered()).toBeTruthy(); option.mouseLeave(); expect(option.isHovered()).toBeFalsy(); }); it('should hover when mouse enter and unhover when mouse leave when overrideStyle is true', function () { var _options = [{ id: 0, value: 'Option 1', overrideStyle: true }]; var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: _options })); driver.mouseEnterAtOption(0); expect(driver.isOptionHoveredWithGlobalClassName(0)).toBeTruthy(); expect(driver.optionByHook('dropdown-item-0').isHoveredWithGlobalClassName()).toBeTruthy(); driver.mouseLeaveAtOption(0); expect(driver.isOptionHoveredWithGlobalClassName(0)).toBeFalsy(); expect(driver.optionByHook('dropdown-item-0').isHoveredWithGlobalClassName()).toBeFalsy(); }); it('should not hover divider or a disabled item when mouse enter', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.mouseEnterAtOption(2); expect(driver.isOptionHovered(2)).toBeFalsy(); driver.mouseLeaveAtOption(4); expect(driver.isOptionHovered(4)).toBeFalsy(); }); it('should have only one hovered option', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.mouseEnterAtOption(0); expect(driver.isOptionHovered(0)).toBeTruthy(); driver.mouseEnterAtOption(1); expect(driver.isOptionHovered(0)).toBeFalsy(); expect(driver.isOptionHovered(1)).toBeTruthy(); }); it('should hovered items cyclic and skipping divider or disabled items on down key', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.pressDownKey(); driver.pressDownKey(); expect(driver.isOptionHovered(1)).toBeTruthy(); driver.pressDownKey(); expect(driver.isOptionHovered(3)).toBeTruthy(); driver.pressDownKey(); expect(driver.isOptionHovered(5)).toBeTruthy(); driver.pressDownKey(); expect(driver.isOptionHovered(0)).toBeTruthy(); }); it('should hovered items cyclic and skipping divider or disabled on up key', function () { var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: options })); driver.pressUpKey(); expect(driver.isOptionHovered(5)).toBeTruthy(); driver.pressUpKey(); expect(driver.isOptionHovered(3)).toBeTruthy(); driver.pressUpKey(); expect(driver.isOptionHovered(1)).toBeTruthy(); driver.pressUpKey(); expect(driver.isOptionHovered(0)).toBeTruthy(); }); it('should hover starting from a given item', function () { var _options = [{ id: 10, value: 'Option 1' }, { id: 20, value: 'Option 2' }, { id: 30, value: 'Option 3' }]; var driver = createDriver(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: _options, selectedId: 20, onSelect: jest.fn() })); driver.pressDownKey(); expect(driver.isOptionHovered(2)).toBeTruthy(); }); it('should remember the hovered option when options change', function () { var _options = [{ id: 0, value: 'a 1' }, { id: 1, value: 'a 2' }, { id: 2, value: 'a 3' }, { id: 3, value: 'a 4' }]; var _render3 = render(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: _options })), driver = _render3.driver, rerender = _render3.rerender; driver.pressDownKey(); driver.pressDownKey(); driver.pressDownKey(); driver.pressDownKey(); expect(driver.isOptionHovered(3)).toBeTruthy(); rerender(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: _options.slice(1) })); expect(driver.isOptionHovered(2)).toBeTruthy(); }); it('should reset the hovered option when options change and hovered option does not exist anymore', function () { var initialOptions = [{ id: 0, value: 'a 1' }, { id: 1, value: 'a 2' }, { id: 2, value: 'a 3' }, { id: 3, value: 'a 4' }]; var _render4 = render(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: initialOptions })), driver = _render4.driver, rerender = _render4.rerender; driver.pressDownKey(); driver.pressDownKey(); expect(driver.isOptionHovered(1)).toBeTruthy(); rerender(_react2.default.createElement(_DropdownLayout2.default, { visible: true, options: initialOptions.slice(2) })); expect(driver.isOptionHovered(0)).toBeFalsy(); expect(driver.isOptionHovered(1)).toBeFalsy(); }); }); describe('theme support', function () { it('should allow setting a custom theme', function () { var props = { theme: 'material', options: options }; var _render5 = render(_react2.default.createElement(_DropdownLayout2.default, props)), driver = _render5.driver; expect(driver.hasTheme('material')).toBe(true); }); }); describe('option validator', function () { describe('valid', function () { it('option', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ id: '1', value: 'hello' }] })); expect(_jestSetup.consoleErrors.get()).toHaveLength(0); }); it('option with function value', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ id: '1', value: function value() {} }] })); expect(_jestSetup.consoleErrors.get()).toHaveLength(0); }); it('divider', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ value: _DropdownLayout.DIVIDER_OPTION_VALUE }] })); expect(_jestSetup.consoleErrors.get()).toHaveLength(0); }); }); describe('invalid', function () { var consoleErrorSpy = void 0; beforeEach(function () { consoleErrorSpy = jest.spyOn(global.console, 'error').mockImplementation(jest.fn()); }); afterEach(function () { consoleErrorSpy.mockRestore(); }); it('no value', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ id: '1' }] })); expect(consoleErrorSpy).toHaveBeenCalledTimes(1); expect(consoleErrorSpy).toBeCalledWith(expect.stringContaining('option.value')); }); it('no id and not divider', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ value: 'aaa' }] })); expect(consoleErrorSpy).toHaveBeenCalledTimes(1); expect(consoleErrorSpy).toBeCalledWith(expect.stringContaining('option.id')); }); it('empty trimmed id', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ id: ' ', value: 'hello' }] })); expect(consoleErrorSpy).toHaveBeenCalledTimes(1); expect(consoleErrorSpy).toBeCalledWith(expect.stringContaining('option.id')); }); it('empty trimmed value', function () { render(_react2.default.createElement(_DropdownLayout2.default, { options: [{ id: '1', value: ' ' }] })); expect(consoleErrorSpy).toHaveBeenCalledTimes(1); expect(consoleErrorSpy).toBeCalledWith(expect.stringContaining('option.value')); }); }); }); });