UNPKG

wix-style-react

Version:
630 lines (629 loc) • 24.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _Popover = _interopRequireDefault(require("../Popover")); var _PopoverCore = require("../PopoverCore/PopoverCore"); var _unit = require("../../test-utils/utils/unit"); var _PopoverUni = require("../Popover.uni.driver"); var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/Popover/tests/Popover.spec.tsx", _this = void 0; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var renderPopover = function renderPopover(props) { var content = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Content'; return /*#__PURE__*/React.createElement(_Popover.default, (0, _extends2.default)({}, props, { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 15, columnNumber: 3 } }), /*#__PURE__*/React.createElement(_Popover.default.Element, { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 16, columnNumber: 5 } }, /*#__PURE__*/React.createElement("div", { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 17, columnNumber: 7 } }, "Element")), /*#__PURE__*/React.createElement(_Popover.default.Content, { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 19, columnNumber: 5 } }, /*#__PURE__*/React.createElement("div", { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 20, columnNumber: 7 } }, content))); }; describe('Popover', () => { var render = (0, _unit.createAsyncRendererWithUniDriver)(_PopoverUni.popoverUniDriverFactory); describe('props', () => { describe('shown', () => { it("doesn't display popup when shown={false}", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { placement: 'bottom', shown: false }; var { driver } = yield render(renderPopover(props)); expect(yield driver.isTargetElementExists()).toBe(true); expect(yield driver.isContentElementExists()).toBe(false); })); it("displays popup when shown={true}", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { placement: 'bottom', shown: true }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); })); }); describe('onMouseEnter & onMouseLeave', () => { it("calls mouseEnter and mouseLeave callbacks", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onMouseEnter = jest.fn(); var onMouseLeave = jest.fn(); var props = { onMouseEnter, onMouseLeave }; var { driver } = yield render(renderPopover(props)); yield driver.mouseEnter(); expect(onMouseEnter).toHaveBeenCalled(); yield driver.mouseLeave(); expect(onMouseLeave).toBeCalled(); })); }); describe('onClick', () => { it("calls onClick callback", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onClick = jest.fn(); var props = { onClick }; var { driver } = yield render(renderPopover(props)); yield driver.click(); expect(onClick).toBeCalled(); })); }); describe('onClickOutside', () => { it('should be triggered when outside of the popover is called', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onClickOutside = jest.fn(); var props = { onClickOutside, shown: true }; var { driver } = yield render(renderPopover(props)); yield driver.clickOutside(); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { return expect(onClickOutside).toBeCalled(); })); })); it('should not trigger onClickOutside when clicking inside with an excluded class', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onClickOutside = jest.fn(); var props = { onClickOutside, shown: false, excludeClass: 'excludeClass' }; var { driver } = yield render(renderPopover(props)); yield driver.click(); expect(onClickOutside).not.toBeCalled(); })); }); describe('disableClickOutsideWhenClosed', () => { it('should be triggered when outside of the popover is called', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onClickOutside = jest.fn(); var props = { shown: true, onClickOutside, disableClickOutsideWhenClosed: true }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { yield driver.clickOutside(); })); expect(onClickOutside).toBeCalled(); })); it('should *not* be triggered when outside of the popover is called and the popover is *not* shown', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onClickOutside = jest.fn(); var props = { shown: false, onClickOutside, disableClickOutsideWhenClosed: true }; var { driver } = yield render(renderPopover(props)); yield driver.clickOutside(); expect(onClickOutside).not.toBeCalled(); })); }); describe('dataHook', () => { it('should be found on target element container', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, appendTo: 'window', dataHook: 'random' }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var target = yield driver.getTargetElement(); expect(target.parentNode.getAttribute('data-hook')).toBe('random'); })); })); it('should construct data-content-hook', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, appendTo: 'window', dataHook: 'random' }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var target = yield driver.getTargetElement(); expect(target.parentNode.getAttribute('data-content-hook')).toMatch(/popover-content-random-/); })); })); it('should apply data-content-element on content element', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, appendTo: 'window', dataHook: 'random' }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); var content = yield driver.getContentElement(); expect(content.getAttribute('data-content-element')).toMatch(/popover-content-random-/); })); it('should not override portal component data-hook', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, appendTo: 'window', dataHook: 'random' }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); var content = yield driver.getContentElement(); expect(content.parentNode.getAttribute('data-hook')).toBe('popover-portal'); })); }); describe('customArrow', () => { it('should display a custom arrow element', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var customArrow = (placement, arrowProps) => /*#__PURE__*/React.createElement("p", (0, _extends2.default)({ "data-test": "custom-arrow", "data-placement": placement }, arrowProps, { __self: _this, __source: { fileName: _jsxFileName, lineNumber: 214, columnNumber: 11 } })); var props = { shown: true, showArrow: true, customArrow, placement: 'top' }; var { driver, container } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); var arrowElement = container.querySelector('[data-test="custom-arrow"]'); expect(!!arrowElement).toBe(true); })); }); describe('moveArrowTo', () => { it("offsets the popup arrow by specified amount", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, showArrow: true, moveArrowTo: 10 }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect((yield driver.getArrowOffset()).left).toBe('10px'); })); })); }); describe('timeout', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it("remove timeout on close [when] given a timeout={0}", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var timeout = { timeout: 0 }; var props = _objectSpread({ shown: true }, timeout); var { driver, rerender } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); yield rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: false }))); expect(yield driver.isContentElementExists()).toBe(false); })); it('adds timeout of 100ms on close [when] given a timeout={100}', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var timeout = 100; var props = { shown: true, timeout }; var { driver, rerender } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); yield rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: false }))); expect(yield driver.isContentElementExists()).toBe(true); yield (0, _unit.act)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { jest.advanceTimersByTime(timeout); })); expect(yield driver.isContentElementExists()).toBe(false); })); }); describe('hideDelay', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it("should close after hideDelay", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var timeout = 500; var props = { shown: true, hideDelay: timeout }; var { driver, rerender } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); yield rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: false }))); expect(yield driver.isContentElementExists()).toBe(true); yield (0, _unit.act)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { jest.advanceTimersByTime(timeout); })); expect(yield driver.isContentElementExists()).toBe(false); })); it("should not update delay until the popover visibillity has fully changed", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var timeout = 500; var props = { shown: true, hideDelay: timeout }; var { driver, rerender } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); yield rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: false, hideDelay: 100 }))); expect(yield driver.isContentElementExists()).toBe(true); yield (0, _unit.act)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { jest.advanceTimersByTime(timeout); })); expect(yield driver.isContentElementExists()).toBe(false); })); }); describe('showDelay', () => { it("should show the content immediately on first render", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, showDelay: 100 }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); })); it("should open after showDelay", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var timeout = { timeout: 500 }; var props = { shown: false, showDelay: 100 }; var { driver, rerender } = yield render(renderPopover(props)); expect(yield driver.isContentElementExists()).toBe(false); yield rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: true }))); expect(yield driver.isContentElementExists()).toBe(false); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); }), timeout); })); }); describe('onShow', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it('should call the onShow callback when popover is shown', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onShow = jest.fn(); var props = { shown: false, onShow }; var { driver, rerender } = yield render(renderPopover(props)); expect(yield driver.isContentElementExists()).toBe(false); expect(onShow).not.toHaveBeenCalled(); yield (0, _unit.act)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: true }))); })); expect(yield driver.isContentElementExists()).toBe(true); expect(onShow).toHaveBeenCalledTimes(1); })); it('should call the onShow callback when popover is shown after a delay', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var onShow = jest.fn(); var showDelay = 100; var props = { shown: false, showDelay, onShow }; var { driver, rerender } = yield render(renderPopover(props)); expect(yield driver.isContentElementExists()).toBe(false); expect(onShow).not.toHaveBeenCalled(); rerender(renderPopover(_objectSpread(_objectSpread({}, props), {}, { shown: true }))); expect(yield driver.isContentElementExists()).toBe(false); expect(onShow).not.toHaveBeenCalled(); yield (0, _unit.act)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { jest.advanceTimersByTime(showDelay + 10); })); expect(yield driver.isContentElementExists()).toBe(true); expect(onShow).toHaveBeenCalledTimes(1); })); }); }); describe('Accessibility', () => { it('should pass aria attrs to content wrapper', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var role = 'someRole'; var ariaAttributes = { 'aria-label': 'someAriaLabel', 'aria-labelledby': 'someAriaLabelledby', 'aria-describedby': 'someAriaDescribedby' }; var props = _objectSpread({ shown: true, role }, ariaAttributes); var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); var contentElement = yield driver.getContentElement(); expect(contentElement.getAttribute('role')).toBe(role); for (var [ariaAttr, ariaAttrValue] of Object.entries(ariaAttributes)) { expect(contentElement.getAttribute(ariaAttr)).toBe(ariaAttrValue); } })); it('should apply id attribute only on popover content', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var ariaId = 'test-labelled'; var { driver, container } = yield render(renderPopover({ id: ariaId, shown: true })); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(container.querySelectorAll("[id=\"".concat(ariaId, "\"]"))).toHaveLength(1); })); expect(yield driver.getContentElement()).toHaveProperty('id', ariaId); })); }); describe('Popper update behaviour', () => { it("should update popper's position when props are chaning", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var updatePositionSpy = jest.spyOn(_PopoverCore.PopoverCore.prototype, 'updatePosition'); var { rerender } = yield render(renderPopover({ shown: true })); yield rerender(renderPopover({ shown: true }, 'New Content')); expect(updatePositionSpy).toHaveBeenCalledTimes(2); updatePositionSpy.mockRestore(); })); it("should not directly update popper's position when the visibillity hasn't changed", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var updatePositionSpy = jest.spyOn(_PopoverCore.PopoverCore.prototype, 'updatePosition'); var { rerender } = yield render(renderPopover({ hideDelay: 10, showDelay: 10, shown: false })); yield rerender(renderPopover({ hideDelay: 10, showDelay: 10, shown: true })); yield rerender(renderPopover({ hideDelay: 10, showDelay: 10, shown: false })); expect(updatePositionSpy).toHaveBeenCalledTimes(1); updatePositionSpy.mockRestore(); })); }); describe('Portal and containment', () => { it('should render content inside portal [when] appendTo = window', /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: true, appendTo: 'window' }; var { driver } = yield render(renderPopover(props)); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(yield driver.isContentElementExists()).toBe(true); })); var portalElement = document.body.querySelector('[data-hook="popover-portal"]'); expect(!!portalElement).toBe(true); })); it("renders an empty portal when closed", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: false, appendTo: 'window' }; yield render(renderPopover(props)); var portalElement = document.body.querySelector('[data-hook="popover-portal"]'); expect(!!portalElement).toBe(true); })); it("removes portal on unmount", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var props = { shown: false, appendTo: 'window' }; var { unmount } = yield render(renderPopover(props)); var portalElement = document.body.querySelector('[data-hook="popover-portal"]'); expect(!!portalElement).toBe(true); unmount(); var portalElementUnounted = document.body.querySelector('[data-hook="popover-portal"]'); expect(!!portalElementUnounted).toBe(false); })); it("adds the portal to the closest scrollable element when appendTo=\"scrollParent\"", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var _document$body$queryS; var srollableHook = 'scrollable-element'; var props = { shown: false, appendTo: 'scrollParent' }; yield render(/*#__PURE__*/React.createElement("div", { "data-hook": srollableHook, style: { overflow: 'scroll' }, __self: _this, __source: { fileName: _jsxFileName, lineNumber: 573, columnNumber: 9 } }, /*#__PURE__*/React.createElement("div", { style: { overflow: 'visible' }, __self: _this, __source: { fileName: _jsxFileName, lineNumber: 574, columnNumber: 11 } }, renderPopover(props)))); var parentElementHook = (_document$body$queryS = document.body.querySelector('[data-hook="popover-portal"]')) == null || (_document$body$queryS = _document$body$queryS.parentElement) == null ? void 0 : _document$body$queryS.getAttribute('data-hook'); expect(parentElementHook).toBe(srollableHook); })); it("should update the portal's styles when updated", /*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { var className = 'some-class'; var props = { shown: true, appendTo: 'window', className }; yield render(renderPopover(props)); var portalElement = document.body.querySelector('[data-hook="popover-portal"]'); yield (0, _unit.waitFor)(/*#__PURE__*/(0, _asyncToGenerator2.default)(function* () { expect(portalElement == null ? void 0 : portalElement.classList).toContain(className); })); })); }); }); //# sourceMappingURL=Popover.spec.js.map