wix-style-react
Version:
wix-style-react
618 lines (522 loc) • 26.1 kB
JavaScript
;
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'));
});
});
});
});