wix-style-react
Version:
wix-style-react
392 lines (311 loc) • 15.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 _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _enzyme = require('enzyme');
var _Button = require('../../Button');
var _Button2 = _interopRequireDefault(_Button);
var _driverFactory = require('wix-ui-test-utils/driver-factory');
var _FocusableHOC = require('./FocusableHOC');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var focusableDriver = function focusableDriver(_ref) {
var element = _ref.element,
eventTrigger = _ref.eventTrigger;
return {
focus: function focus() {
return eventTrigger.focus(element);
},
blur: function blur() {
return eventTrigger.blur(element);
},
hasFocusState: function hasFocusState() {
return !!element.getAttribute('data-focus');
},
hasFocusVisibleState: function hasFocusVisibleState() {
return !!element.getAttribute('data-focus-visible');
}
};
};
describe('FocusableHOC', function () {
var _class, _temp;
var render = function render(Comp) {
return (0, _enzyme.mount)(Comp, { attachTo: document.createElement('div') });
};
// Pure component without state
var PureChildComponent = (_temp = _class = function (_React$PureComponent) {
_inherits(PureChildComponent, _React$PureComponent);
function PureChildComponent(props) {
_classCallCheck(this, PureChildComponent);
var _this = _possibleConstructorReturn(this, (PureChildComponent.__proto__ || Object.getPrototypeOf(PureChildComponent)).call(this, props));
_this.id = props.id;
_this.boundMethod = _this.boundMethod.bind(_this);
return _this;
}
_createClass(PureChildComponent, [{
key: 'unboundMethod',
value: function unboundMethod() {
return 'unboundMethod';
}
}, {
key: 'boundMethod',
value: function boundMethod() {
return this.id;
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
_extends({
onFocus: this.props.focusableOnFocus // eslint-disable-line react/prop-types
, onBlur: this.props.focusableOnBlur // eslint-disable-line react/prop-types
}, (0, _FocusableHOC.focusableStates)(this.props)),
'Hello'
);
}
}], [{
key: 'staticMethod',
value: function staticMethod() {
return 'staticMethod';
}
}]);
return PureChildComponent;
}(_react2.default.PureComponent), _class.propTypes = {
id: _propTypes2.default.string
}, _class.staticVariable = 'staticVariable', _temp);
var pureChildDriverFactory = function pureChildDriverFactory(_ref2) {
var element = _ref2.element,
eventTrigger = _ref2.eventTrigger;
return _extends({}, focusableDriver({
element: element,
getFocusableElement: function getFocusableElement() {
return element;
},
eventTrigger: eventTrigger
}));
};
var WithFocusableComp = (0, _FocusableHOC.withFocusable)(PureChildComponent);
describe('Pure component HOC', function () {
it('should render the wrapped component', function () {
var wrapper = render(_react2.default.createElement(WithFocusableComp, null));
expect(wrapper.children().instance()).toBeInstanceOf(PureChildComponent);
});
describe('hoisting', function () {
it('should hoist static methods', function () {
expect(WithFocusableComp.staticMethod()).toEqual('staticMethod');
});
it('should hoist static variables', function () {
expect(WithFocusableComp.staticVariable).toEqual('staticVariable');
});
it('should hoist prototype methods from child to HOC and bind them', function () {
var wrapper = render(_react2.default.createElement(WithFocusableComp, { id: 'some_id' }));
expect(wrapper.instance().unboundMethod()).toEqual('unboundMethod');
expect(wrapper.instance().boundMethod()).toEqual('some_id');
});
});
});
describe('Focusable', function () {
var driverFactory = (0, _driverFactory.createDriverFactory)(pureChildDriverFactory);
var createDriver = function createDriver(Component) {
var driver = driverFactory(Component);
var fireMouseDown = function fireMouseDown() {
return window.dispatchEvent(new window.Event('mousedown'));
};
var fireMouseUp = function fireMouseUp() {
return window.dispatchEvent(new window.Event('mouseup'));
};
var fireKeyDown = function fireKeyDown() {
return window.dispatchEvent(new window.Event('keydown'));
};
var fireKeyUp = function fireKeyUp() {
return window.dispatchEvent(new window.Event('keyup'));
};
var tabOut = function tabOut() {
fireKeyDown();
driver.blur();
fireKeyUp();
};
var tabIn = function tabIn() {
fireKeyDown();
driver.focus();
fireKeyUp();
};
var click = function click() {
fireMouseDown();
driver.focus();
fireMouseUp();
};
return _extends({}, driver, {
fireMouseDown: fireMouseDown,
fireKeyDown: fireKeyDown,
fireKeyUp: fireKeyUp,
tabOut: tabOut,
tabIn: tabIn,
click: click
});
};
var expectKeyboardFocused = function expectKeyboardFocused(driver, msg) {
var prefix = msg ? msg + ' - ' : '';
expect(driver.hasFocusState()).toBe(true, prefix + 'hasFocusState');
expect(driver.hasFocusVisibleState()).toBe(true, prefix + 'hasFocusVisibleState');
};
var expectNotFocused = function expectNotFocused(driver, msg) {
var prefix = msg ? msg + ' - ' : '';
expect(driver.hasFocusState()).toBe(false, prefix + 'hasFocusState');
expect(driver.hasFocusVisibleState()).toBe(false, prefix + 'hasFocusVisibleState');
};
var expectMouseFocused = function expectMouseFocused(driver, msg) {
var prefix = msg ? msg + ' - ' : '';
expect(driver.hasFocusState()).toBe(true, prefix + 'hasFocusState');
expect(driver.hasFocusVisibleState()).toBe(false, prefix + 'hasFocusVisibleState');
};
var WithFocusableComp2 = void 0;
var focusableModule = void 0;
beforeEach(function () {
// Reseting modules, in order to reset the FocusableHOC.InputMethod.method state.
jest.resetModules();
focusableModule = require('./FocusableHOC');
WithFocusableComp2 = focusableModule.withFocusable(PureChildComponent);
// TODO: find a way to reset the eventHandlers which are added to the window.
});
it('should not have focus nor focus-visible [given] initial render', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
expectNotFocused(driver);
});
it('should have focus and focus-visible [when] focused programatically', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.focus();
// Default input is keyboard
expectKeyboardFocused(driver, 'after focus');
});
it('should have focus and focus-visible [when] tabbed in', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.tabIn();
expectKeyboardFocused(driver, 'after focus');
});
it('should have focus and focus-visible [when] tabbed in withot keyDown', function () {
// This test case checks a scenario when the focus is on the browser's
// url input, and we press tab. The keyDown is not fired.
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.focus();
driver.fireKeyUp();
expectKeyboardFocused(driver, 'after focus');
});
it('should not have focus nor focus-visible [when] blured programatically [given] keyboard focused', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.tabIn();
expectKeyboardFocused(driver, 'after focus');
driver.blur();
expectNotFocused(driver, 'after blur');
});
it('should have focus but not focus-visible [when] clicked', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.click();
expectMouseFocused(driver, 'after click');
});
it('should have focus but not focus-visible [when] focused programatically [given] current input method is mouse', function () {
// This test must be here , after a test which finishes with the input method = mouse.
// this test is only to test that we are reseting the FocusableHOC global state proparely,
// usin the jest.resetModules() call.
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.focus();
expectKeyboardFocused(driver, 'after click');
});
/**
* This test checks that the InpurMethod.method state is updated to `keyboard` after
* is was set to `mouse`.
*/
it('should have focus and focus-visible [when] focused [given] mouseDown and blur', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp2, null));
driver.click();
expectMouseFocused(driver, 'after click');
driver.blur();
expectNotFocused(driver, 'after blur');
driver.tabIn();
expectKeyboardFocused(driver, 'after focus');
});
it('should not be focused [when] tabbed out [given] focused by mouse', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp, null));
driver.click();
expectMouseFocused(driver, 'after click');
driver.tabOut();
expectNotFocused(driver, 'after tab');
});
it('should have focus and focus-visible, when: any keyboard key pressed [given] focused by mouse', function () {
var driver = createDriver(_react2.default.createElement(WithFocusableComp, null));
driver.click();
expectMouseFocused(driver, 'after click');
driver.fireKeyDown();
expectKeyboardFocused(driver, 'after pressing space');
});
});
describe('regressions', function () {
var ButtonWithDisabledState = function (_React$Component) {
_inherits(ButtonWithDisabledState, _React$Component);
function ButtonWithDisabledState() {
var _ref3;
var _temp2, _this2, _ret;
_classCallCheck(this, ButtonWithDisabledState);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp2 = (_this2 = _possibleConstructorReturn(this, (_ref3 = ButtonWithDisabledState.__proto__ || Object.getPrototypeOf(ButtonWithDisabledState)).call.apply(_ref3, [this].concat(args))), _this2), _this2.state = { disabled: false }, _this2.handleButtonClick = function () {
_this2.setState({ disabled: true });
}, _temp2), _possibleConstructorReturn(_this2, _ret);
}
_createClass(ButtonWithDisabledState, [{
key: 'render',
value: function render() {
var _this3 = this;
return _react2.default.createElement(
'div',
null,
_react2.default.createElement(
_Button2.default,
{
dataHook: 'disabled-button',
disabled: this.state.disabled,
onClick: this.handleButtonClick
},
'click me'
),
_react2.default.createElement('input', {
placeholder: 'click the button and type here',
onChange: function onChange() {
return _this3.setState({ disabled: false });
}
})
);
}
}]);
return ButtonWithDisabledState;
}(_react2.default.Component);
it('ISSUE-1721: Fix focusable button in disabled state', function () {
var component = (0, _enzyme.mount)(_react2.default.createElement(ButtonWithDisabledState, null));
var button = component.find('button');
var input = component.find('input');
/* by default should not have focus and should not be disabled */
expect(button.getDOMNode().disabled).toBeFalsy();
expect(button.getDOMNode().attributes['data-focus']).toBeFalsy();
/* become focused */
button.simulate('focus');
expect(button.getDOMNode().attributes['data-focus']).toBeTruthy();
/* click on button after that, button should become disabled */
button.simulate('click');
expect(button.getDOMNode().disabled).toBeTruthy();
/* bug was here, after button become disabled, focus should disappear */
expect(button.getDOMNode().attributes['data-focus']).toBeFalsy();
/* input change, after that should be disabled === false */
input.simulate('change', { target: { value: '123' } });
expect(button.getDOMNode().disabled).toBeFalsy();
/* bug was here, after input change, button should become unfocused */
expect(button.getDOMNode().attributes['data-focus']).toBeFalsy();
});
});
});