@loadsmart/loadsmart-ui 6.0.8 → 6.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../DragDropFile.context-c7cd1441.js"),t=require("@testing-library/react"),i=require("../toArray-b56541b4.js"),n=require("@testing-library/user-event"),r=require("../miranda-compatibility.theme-ec2c3370.js"),o=require("react");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("@loadsmart/miranda-tokens");var a=c(n),d=c(o);function l(e){return e.parentNode.parentNode.parentNode.parentNode}function u(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=l(i);t.queries.queryByRole(n,"menu")||(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(i),expect(yield t.queries.findByRole(n,"menu")).toBeInTheDocument()})))))}))}function s(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=l(i);t.queries.queryByRole(n,"menu")&&(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(t.queries.getByText(n,"Close")),yield t.waitForElementToBeRemoved((()=>t.queries.queryByRole(n,"menu")))})))))}))}const f={getContainer:l,expand:u,collapse:s,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const r=l(n);yield u(n),yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){n.focus();const e=t.queries.getByLabelText(r,i);e&&"false"==e.getAttribute("aria-checked")&&t.fireEvent.click(e)})))),yield s(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=l(i);yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){const e=t.queries.getByLabelText(n,"Clear selection");t.fireEvent.click(e)})))),yield s(i)}))},getSelectedDates:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=l(i);yield u(i);const n=t.queries.queryAllByRole(e,"checkbox",{checked:!0});return yield s(i),n}))}};function v(t){return e.__awaiter(this,void 0,void 0,(function*(){yield f.expand(t)}))}function y(t){return e.__awaiter(this,void 0,void 0,(function*(){yield f.collapse(t)}))}const p={getContainer:f.getContainer,expand:v,collapse:y,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const e=f.getContainer(n);yield v(n);const[r,o]=i;if(null!=r){const i=t.queries.getByTestId(e,"input-date-range-start");yield f.pick(r,i)}if(null!=o){const i=t.queries.getByTestId(e,"input-date-range-end");yield f.pick(o,i)}yield y(n)}))},clear:function(t){return e.__awaiter(this,void 0,void 0,(function*(){yield f.clear(t)}))},getSelectedDates:function(t){return e.__awaiter(this,void 0,void 0,(function*(){return f.getSelectedDates(t)}))}},_=e=>e.parentNode,h={dragOver:e=>{const i=_(e),n=t.createEvent.dragOver(i);t.fireEvent(i,n)},dragLeave:e=>{const i=_(e),n=t.createEvent.dragLeave(i);t.fireEvent(i,n)},dropFiles:(e,n)=>{const r=_(e),o=t.createEvent.drop(r);Object.defineProperty(o,"dataTransfer",{value:{files:i.toArray(n)}}),t.fireEvent(r,o)}};function g(e){return e.parentNode.parentNode.parentNode}function w(e){return e.parentNode.parentNode.nextSibling}function x(e){return e.parentNode.nextSibling.nextSibling}function B(e){return e.parentNode}function q(e){return 3==g(e).children.length}function b(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=B(i);t.within(e).queryByTestId("select-trigger-loading")&&(yield t.waitForElementToBeRemoved((()=>t.within(e).queryByTestId("select-trigger-loading")),{timeout:2500}))}))}function m(i){return e.__awaiter(this,void 0,void 0,(function*(){if(yield b(i),q(i))return;const n=x(i);yield t.waitFor((()=>{expect(n).toBeEnabled()})),a.default.click(n),yield t.waitFor((()=>e.__awaiter(this,void 0,void 0,(function*(){expect(yield t.within(g(i)).findByRole("listbox")).toBeInTheDocument()}))))}))}function k(i){return e.__awaiter(this,void 0,void 0,(function*(){if(!q(i))return;const e=x(i);a.default.click(e),yield t.waitFor((()=>{expect(t.within(g(i)).queryByRole("listbox")).not.toBeInTheDocument()}))}))}const E={select:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield m(n);const e=w(n),r=yield t.within(e).findByLabelText(i);r&&"false"==r.getAttribute("aria-selected")&&a.default.click(r),yield k(n)}))},unselect:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield m(n);const e=w(n),r=yield t.within(e).findByLabelText(i);r&&"true"==r.getAttribute("aria-selected")&&a.default.click(r),yield k(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield b(i);const e=B(i),n=t.within(e).getByTestId("select-trigger-clear");t.act((()=>{n&&a.default.click(n)}))}))},search:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const e=g(n);a.default.type(n,i),yield t.within(e).findAllByRole("option",void 0,{timeout:2500})}))},expand:m,collapse:k,getOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield m(i);const e=w(i),n=t.within(e).queryAllByRole("option");return yield k(i),n}))},getSelectedOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield m(i);const e=w(i);let n=[];try{n=yield t.within(e).findAllByRole("option",{selected:!0})}catch(e){n=[]}return yield k(i),n}))},isMenuExpanded:q};const D={fileList:[],onFilesAdded:jest.fn(),onRetryUpload:jest.fn(),onRemoveFile:jest.fn()};exports.DatePickerEvent=f,exports.DateRangePickerEvent=p,exports.DragDropFileEvent=h,exports.SelectEvent=E,exports.getInterpolatedStyles=function(e){return i.toArray(e).map((e=>{for(;r.isFunction(e);)e=e({theme:r.alice});return e})).join("")},exports.renderWithDragDropFileProvider=(i,n)=>{const r=Object.assign(Object.assign({},D),n);return t.render((o=i,d.default.createElement(e.DragDropFileContext.Provider,{value:r},o)));var o};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../DragDropFile.context-c7cd1441.js"),t=require("@testing-library/react"),i=require("../toArray-b56541b4.js"),n=require("../miranda-compatibility.theme-ec2c3370.js"),r=require("react");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("@loadsmart/miranda-tokens");var c=o(r);function a(e){return e.parentNode.parentNode.parentNode.parentNode}function d(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);t.queries.queryByRole(n,"menu")||(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(i),expect(yield t.queries.findByRole(n,"menu")).toBeInTheDocument()})))))}))}function u(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);t.queries.queryByRole(n,"menu")&&(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(t.queries.getByText(n,"Close")),yield t.waitForElementToBeRemoved((()=>t.queries.queryByRole(n,"menu")))})))))}))}const l={getContainer:a,expand:d,collapse:u,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const r=a(n);yield d(n),yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){n.focus();const e=t.queries.getByLabelText(r,i);e&&"false"==e.getAttribute("aria-checked")&&t.fireEvent.click(e)})))),yield u(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){const e=t.queries.getByLabelText(n,"Clear selection");t.fireEvent.click(e)})))),yield u(i)}))},getSelectedDates:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=a(i);yield d(i);const n=t.queries.queryAllByRole(e,"checkbox",{checked:!0});return yield u(i),n}))}};function s(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.expand(t)}))}function f(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.collapse(t)}))}const v={getContainer:l.getContainer,expand:s,collapse:f,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const e=l.getContainer(n);yield s(n);const[r,o]=i;if(null!=r){const i=t.queries.getByTestId(e,"input-date-range-start");yield l.pick(r,i)}if(null!=o){const i=t.queries.getByTestId(e,"input-date-range-end");yield l.pick(o,i)}yield f(n)}))},clear:function(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.clear(t)}))},getSelectedDates:function(t){return e.__awaiter(this,void 0,void 0,(function*(){return l.getSelectedDates(t)}))}},y=e=>e.parentNode,p={dragOver:e=>{const i=y(e),n=t.createEvent.dragOver(i);t.fireEvent(i,n)},dragLeave:e=>{const i=y(e),n=t.createEvent.dragLeave(i);t.fireEvent(i,n)},dropFiles:(e,n)=>{const r=y(e),o=t.createEvent.drop(r);Object.defineProperty(o,"dataTransfer",{value:{files:i.toArray(n)}}),t.fireEvent(r,o)}};function _(e){return e.parentNode.parentNode.parentNode}function h(e){return e.parentNode.parentNode.nextSibling}function g(e){return e.parentNode.nextSibling.nextSibling}function w(e){return e.parentNode}function x(e){return 3===_(e).children.length}function E(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=w(i);t.within(e).queryByTestId("select-trigger-loading")&&(yield t.waitForElementToBeRemoved((()=>t.within(e).queryByTestId("select-trigger-loading")),{timeout:2500}))}))}function b(i){return e.__awaiter(this,void 0,void 0,(function*(){if(yield E(i),x(i))return;const n=g(i);yield t.waitFor((()=>{expect(n).toBeEnabled()})),t.act((()=>{i.dispatchEvent(new MouseEvent("click",{bubbles:!0}))})),yield t.waitFor((()=>e.__awaiter(this,void 0,void 0,(function*(){expect(yield t.within(_(i)).findByRole("listbox")).toBeInTheDocument()}))))}))}function B(i){return e.__awaiter(this,void 0,void 0,(function*(){if(!x(i))return;const e=g(i);t.fireEvent.click(e),yield t.waitFor((()=>{expect(t.within(_(i)).queryByRole("listbox")).not.toBeInTheDocument()}))}))}const q={select:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield b(n);const e=h(n),r=yield t.within(e).findByLabelText(i);r&&"false"==r.getAttribute("aria-selected")&&(t.fireEvent.mouseDown(r),t.act((()=>{r.focus()})),t.fireEvent.mouseUp(r),t.fireEvent.click(r)),yield B(n)}))},unselect:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield b(n);const e=h(n),r=yield t.within(e).findByLabelText(i);r&&"true"===r.getAttribute("aria-selected")&&t.fireEvent.click(r),yield B(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield E(i);const e=w(i),n=t.within(e).getByTestId("select-trigger-clear");n&&t.fireEvent.click(n)}))},search:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.change(n,{target:{value:i}}),yield E(n);const e=h(n);yield t.within(e).findAllByRole("option")}))},expand:b,collapse:B,getOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield b(i);const e=h(i),n=t.within(e).queryAllByRole("option");return yield B(i),n}))},getSelectedOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield b(i);const e=h(i);let n=[];try{n=yield t.within(e).findAllByRole("option",{selected:!0})}catch(e){n=[]}return yield B(i),n}))},isMenuExpanded:x};const m={fileList:[],onFilesAdded:jest.fn(),onRetryUpload:jest.fn(),onRemoveFile:jest.fn()};exports.DatePickerEvent=l,exports.DateRangePickerEvent=v,exports.DragDropFileEvent=p,exports.SelectEvent=q,exports.getInterpolatedStyles=function(e){return i.toArray(e).map((e=>{for(;n.isFunction(e);)e=e({theme:n.alice});return e})).join("")},exports.renderWithDragDropFileProvider=(i,n)=>{const r=Object.assign(Object.assign({},m),n);return t.render((o=i,c.default.createElement(e.DragDropFileContext.Provider,{value:r},o)));var o};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/testing/DatePickerEvent/DatePickerEvent.ts","../../src/testing/DatePickerEvent/DateRangePickerEvent.ts","../../src/testing/DragDropFileEvent/DragDropFileEvent.ts","../../src/testing/SelectEvent/SelectEvent.ts","../../src/testing/renderWithDragDropFileProvider/renderWithDragDropFileProvider.tsx","../../src/testing/getInterpolatedStyles/getInterpolatedStyles.ts"],"sourcesContent":["/* eslint-disable */\nimport { act, queries, fireEvent, waitForElementToBeRemoved } from '@testing-library/react'\n\n// find the date picker container from its input field 🤷\nfunction getContainerFromInput(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.parentNode!.parentNode as HTMLElement\n}\n\n/**\n * Expand the `DatePicker` calendar, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n // if menu is rendered, then the select is already expanded\n if (queries.queryByRole(datePickerContainer, 'menu')) {\n return\n }\n\n await act(async () => {\n fireEvent.click(input)\n\n expect(await queries.findByRole(datePickerContainer, 'menu')).toBeInTheDocument()\n })\n}\n\n/**\n * Collapse the `DatePicker` calendar, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n // if menu is not rendered, then the select is already collapsed\n if (!queries.queryByRole(datePickerContainer, 'menu')) {\n return\n }\n\n await act(async () => {\n fireEvent.click(queries.getByText(datePickerContainer, 'Close'))\n\n await waitForElementToBeRemoved(() => queries.queryByRole(datePickerContainer, 'menu'))\n })\n}\n\n/**\n * Pick (select) the provided day in the current month/year.\n * Notice that we programatically expand the `DatePicker` calendar before picking the date.\n * @param {string} day - Label for the day to be picked, formatted as mm/dd/yyyy.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function pick(day: string, input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n await expand(input)\n\n await act(async () => {\n input.focus()\n\n const dayElement = queries.getByLabelText(datePickerContainer, day)\n\n if (dayElement && dayElement.getAttribute('aria-checked') == 'false') {\n fireEvent.click(dayElement)\n }\n })\n\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n await act(async () => {\n const clearButton = queries.getByLabelText(datePickerContainer, 'Clear selection')\n\n fireEvent.click(clearButton)\n })\n\n await collapse(input)\n}\n\n/**\n * Get options elements currently selected in the `DatePicker` calendar.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedDates(input: HTMLElement): Promise<HTMLElement[]> {\n const datePickerContainer = getContainerFromInput(input)\n\n await expand(input)\n\n const selectedDays: HTMLElement[] = queries.queryAllByRole(datePickerContainer, 'checkbox', {\n checked: true,\n })\n\n await collapse(input)\n\n return selectedDays\n}\n\nconst datePickerEvent = {\n getContainer: getContainerFromInput,\n expand,\n collapse,\n pick,\n clear,\n getSelectedDates,\n}\n\nexport default datePickerEvent\n","/* eslint-disable */\nimport { queries } from '@testing-library/react'\n\nimport DatePickerEvent from './DatePickerEvent'\n\n/**\n * Expand the `DatePicker` calendar, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n await DatePickerEvent.expand(input)\n}\n\n/**\n * Collapse the `DatePicker` calendar, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n await DatePickerEvent.collapse(input)\n}\n\n/**\n * Pick (select) the provided day in the current month/year.\n * Notice that we programatically expand the `DatePicker` calendar before picking the date.\n * @param {string} day - Label for the day to be picked, formatted as mm/dd/yyyy.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function pick(range: [string | null, string | null], input: HTMLElement): Promise<void> {\n const dateRangePickerContainer = DatePickerEvent.getContainer(input)\n\n await expand(input)\n\n const [rangeStart, rangeEnd] = range\n\n if (rangeStart != null) {\n const dateRangeStartInput = queries.getByTestId(\n dateRangePickerContainer,\n 'input-date-range-start'\n )\n\n await DatePickerEvent.pick(rangeStart, dateRangeStartInput)\n }\n\n if (rangeEnd != null) {\n const dateRangeEndInput = queries.getByTestId(dateRangePickerContainer, 'input-date-range-end')\n\n await DatePickerEvent.pick(rangeEnd, dateRangeEndInput)\n }\n\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n await DatePickerEvent.clear(input)\n}\n\n/**\n * Get options elements currently selected in the `DatePicker` calendar.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedDates(input: HTMLElement): Promise<HTMLElement[]> {\n return DatePickerEvent.getSelectedDates(input)\n}\n\nexport const dateRangePickerEvent = {\n getContainer: DatePickerEvent.getContainer,\n expand,\n collapse,\n pick,\n clear,\n getSelectedDates,\n}\n\nexport default dateRangePickerEvent\n","import { createEvent, fireEvent } from '@testing-library/react'\n\nimport toArray from 'utils/toolset/toArray'\n\n/**\n * Get the input dropzone, which is the input parent (label).\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst getDropZoneFromInput = (input: HTMLInputElement): HTMLLabelElement =>\n input.parentNode as HTMLLabelElement\n\n/**\n * Simulates the onDragOver event on the drop zone.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dragOver = (input: HTMLInputElement) => {\n const dropzone = getDropZoneFromInput(input)\n\n const dragOverEvent = createEvent.dragOver(dropzone)\n\n fireEvent(dropzone, dragOverEvent)\n}\n\n/**\n * Simulates the onDragLeave event on the drop zone.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dragLeave = (input: HTMLInputElement) => {\n const dropzone = getDropZoneFromInput(input)\n\n const dragLeaveEvent = createEvent.dragLeave(dropzone)\n\n fireEvent(dropzone, dragLeaveEvent)\n}\n\n/**\n * Simulates the onDrop event on the drop zone. You can provide a list of files or a single file.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dropFiles = (input: HTMLInputElement, files: File | File[]) => {\n const dropzone = getDropZoneFromInput(input)\n\n const fileDropEvent = createEvent.drop(dropzone)\n\n Object.defineProperty(fileDropEvent, 'dataTransfer', { value: { files: toArray(files) } })\n\n fireEvent(dropzone, fileDropEvent)\n}\n\nexport const DragDropFileEvent = {\n dragOver,\n dragLeave,\n dropFiles,\n}\n\nexport default DragDropFileEvent\n","import { act, waitFor, within, waitForElementToBeRemoved } from '@testing-library/react'\nimport userEvent from '@testing-library/user-event'\n\n// based on https://github.com/romgain/react-select-event/blob/master/src/index.ts\n\n// find the select container from its input field 🤷\nfunction getSelectContainer(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.parentNode as HTMLElement\n}\n\n/**\n * Please, make sure to call expand before trying to get the menu container\n */\nfunction getSelectMenu(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.nextSibling as HTMLElement\n}\n\nfunction getSelectTriggerHandle(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.nextSibling!.nextSibling as HTMLElement\n}\n\nfunction getSelectSearchContainer(input: HTMLElement): HTMLElement {\n return input.parentNode as HTMLElement\n}\n\nfunction isSelectMenuExpanded(input: HTMLElement): boolean {\n const selectContainer = getSelectContainer(input)\n\n /**\n * Once the select is expanded, we have the following structure:\n * +-------------+\n * | Close button (visually hiddren)\n * +-------------+\n * | DropdownTrigger\n * +-------------+\n * | Popover\n * +-------------+\n *\n * This, if the container has 3 children, we assume the menu is expanded\n */\n return selectContainer.children.length == 3\n}\n\n/**\n * This is needed because some datasources might be asynchronous.\n * To ensure that the data they retrieve will be available, we wait for the\n * querying phase to finish.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n */\nasync function waitForPendingQuery(input: HTMLElement) {\n const searchContainer = getSelectSearchContainer(input)\n\n if (!within(searchContainer).queryByTestId('select-trigger-loading')) {\n return\n }\n\n await waitForElementToBeRemoved(\n () => within(searchContainer).queryByTestId('select-trigger-loading'),\n { timeout: 2500 }\n )\n}\n\n/**\n * Expand the `Select` menu, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n await waitForPendingQuery(input)\n\n if (isSelectMenuExpanded(input)) {\n return\n }\n\n const triggerHandle = getSelectTriggerHandle(input)\n\n await waitFor(() => {\n expect(triggerHandle).toBeEnabled()\n })\n\n userEvent.click(triggerHandle)\n\n await waitFor(async () => {\n expect(await within(getSelectContainer(input)).findByRole('listbox')).toBeInTheDocument()\n })\n}\n\n/**\n * Collapse the `Select` menu, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n if (!isSelectMenuExpanded(input)) {\n return\n }\n\n const triggerHandle = getSelectTriggerHandle(input)\n\n userEvent.click(triggerHandle)\n\n await waitFor(() => {\n expect(within(getSelectContainer(input)).queryByRole('listbox')).not.toBeInTheDocument()\n })\n}\n\n/**\n * Select the provided option(s), if they are present in the menu.\n * Notice that we programatically expand the `Select` menu before select the item\n * @param {string} option - Label for the option to be selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function select(option: string, input: HTMLElement): Promise<void> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const optionElement = await within(menuContainer).findByLabelText(option)\n\n // click the option if exists; Select currently closes when an item is clicked.\n if (optionElement && optionElement.getAttribute('aria-selected') == 'false') {\n userEvent.click(optionElement)\n }\n\n // we collapse in the case the option was not clicked\n await collapse(input)\n}\n\n/**\n * Unselect the provided option(s), if they are present in the menu AND are selected.\n * Notice that we programatically expand the `Select` menu before select the item\n * @param {string} option - Label for the option to be unselected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function unselect(option: string, input: HTMLElement): Promise<void> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const optionElement = await within(menuContainer).findByLabelText(option)\n\n // ensures that the option exists and IS selected\n if (optionElement && optionElement.getAttribute('aria-selected') == 'true') {\n userEvent.click(optionElement)\n }\n\n // we collapse in the case the option was not clicked\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n await waitForPendingQuery(input)\n\n const searchContainer = getSelectSearchContainer(input)\n\n const clearButton = within(searchContainer).getByTestId('select-trigger-clear')\n\n act(() => {\n if (clearButton) {\n userEvent.click(clearButton)\n }\n })\n}\n\n/**\n * Perform search based on the given `query`. It will fail if the option is not found.\n * @param {string} query - Search term.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function search(query: string, input: HTMLElement): Promise<void> {\n const selectContainer = getSelectContainer(input)\n\n userEvent.type(input, query)\n\n await within(selectContainer).findAllByRole('option', undefined, { timeout: 2500 })\n}\n\n/**\n * Get options elements currently available in the `Select` menu.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getOptions(input: HTMLElement): Promise<HTMLElement[]> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const options = within(menuContainer).queryAllByRole('option')\n\n await collapse(input)\n\n return options\n}\n\n/**\n * Get options elements currently selected in the `Select` menu.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedOptions(input: HTMLElement): Promise<HTMLElement[]> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n let selectedOptions: HTMLElement[] = []\n\n try {\n selectedOptions = await within(menuContainer).findAllByRole('option', {\n selected: true,\n })\n } catch (err) {\n selectedOptions = []\n }\n\n await collapse(input)\n\n return selectedOptions\n}\n\nexport const selectEvent = {\n select,\n unselect,\n clear,\n search,\n expand,\n collapse,\n getOptions,\n getSelectedOptions,\n isMenuExpanded: isSelectMenuExpanded,\n}\n\nexport default selectEvent\n","import React, { ReactNode } from 'react'\nimport { render } from '@testing-library/react'\nimport type { RenderResult } from '@testing-library/react'\n\nimport type { DragDropFileContextValue } from '../../components/DragDropFile/types'\nimport { DragDropFileContext } from '../../components/DragDropFile/DragDropFile.context'\n\nconst defaultContextValueMock: DragDropFileContextValue = {\n fileList: [],\n onFilesAdded: jest.fn(),\n onRetryUpload: jest.fn(),\n onRemoveFile: jest.fn(),\n}\n\nconst renderWithDragDropFileProvider = (\n ui: ReactNode,\n customContext?: Partial<DragDropFileContextValue>\n): RenderResult => {\n const contextValue = { ...defaultContextValueMock, ...customContext }\n\n const renderedUi = (children: ReactNode) => (\n <DragDropFileContext.Provider value={contextValue}>{children}</DragDropFileContext.Provider>\n )\n\n return render(renderedUi(ui))\n}\n\nexport default renderWithDragDropFileProvider\n","import type { Interpolation, ThemeProps } from 'styled-components'\nimport { isFunction } from '@loadsmart/utils-function'\n\nimport { Alice } from '../../theming/themes'\nimport type { CustomTheme } from '../../theming'\nimport toArray from 'utils/toolset/toArray'\n\ntype ThemedInterpolation = Interpolation<ThemeProps<CustomTheme>>\n\n/**\n * Use this function to simulate the CSS that would be generated by styled-components\n * @param {Interpolation<ThemeProps<CustomTheme>>} styles - A `css` reference with interpolated styles\n * @returns {string} The final CSS\n */\nexport default function getInterpolatedStyles(styles: ThemedInterpolation): string {\n return toArray(styles)\n .map((interpolation) => {\n while (isFunction(interpolation)) {\n interpolation = interpolation({ theme: Alice })\n }\n\n return interpolation\n })\n .join('')\n}\n"],"names":["getContainerFromInput","input","parentNode","expand","datePickerContainer","queries","queryByRole","act","__awaiter","this","fireEvent","click","expect","findByRole","toBeInTheDocument","collapse","getByText","waitForElementToBeRemoved","datePickerEvent","getContainer","day","focus","dayElement","getByLabelText","getAttribute","clearButton","selectedDays","queryAllByRole","checked","DatePickerEvent","dateRangePickerEvent","pick","range","dateRangePickerContainer","rangeStart","rangeEnd","dateRangeStartInput","getByTestId","dateRangeEndInput","clear","getSelectedDates","getDropZoneFromInput","DragDropFileEvent","dragOver","dropzone","dragOverEvent","createEvent","dragLeave","dragLeaveEvent","dropFiles","files","fileDropEvent","drop","Object","defineProperty","value","toArray","getSelectContainer","getSelectMenu","nextSibling","getSelectTriggerHandle","getSelectSearchContainer","isSelectMenuExpanded","children","length","waitForPendingQuery","searchContainer","within","queryByTestId","timeout","triggerHandle","waitFor","toBeEnabled","userEvent","not","selectEvent","select","option","menuContainer","optionElement","findByLabelText","unselect","search","query","selectContainer","type","findAllByRole","undefined","getOptions","options","getSelectedOptions","selectedOptions","selected","err","isMenuExpanded","defaultContextValueMock","fileList","onFilesAdded","jest","fn","onRetryUpload","onRemoveFile","styles","map","interpolation","isFunction","theme","Alice","join","ui","customContext","contextValue","assign","render","React","createElement","DragDropFileContext","Provider"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/testing/DatePickerEvent/DatePickerEvent.ts","../../src/testing/DatePickerEvent/DateRangePickerEvent.ts","../../src/testing/DragDropFileEvent/DragDropFileEvent.ts","../../src/testing/SelectEvent/SelectEvent.ts","../../src/testing/renderWithDragDropFileProvider/renderWithDragDropFileProvider.tsx","../../src/testing/getInterpolatedStyles/getInterpolatedStyles.ts"],"sourcesContent":["/* eslint-disable */\nimport { act, queries, fireEvent, waitForElementToBeRemoved } from '@testing-library/react'\n\n// find the date picker container from its input field 🤷\nfunction getContainerFromInput(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.parentNode!.parentNode as HTMLElement\n}\n\n/**\n * Expand the `DatePicker` calendar, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n // if menu is rendered, then the select is already expanded\n if (queries.queryByRole(datePickerContainer, 'menu')) {\n return\n }\n\n await act(async () => {\n fireEvent.click(input)\n\n expect(await queries.findByRole(datePickerContainer, 'menu')).toBeInTheDocument()\n })\n}\n\n/**\n * Collapse the `DatePicker` calendar, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n // if menu is not rendered, then the select is already collapsed\n if (!queries.queryByRole(datePickerContainer, 'menu')) {\n return\n }\n\n await act(async () => {\n fireEvent.click(queries.getByText(datePickerContainer, 'Close'))\n\n await waitForElementToBeRemoved(() => queries.queryByRole(datePickerContainer, 'menu'))\n })\n}\n\n/**\n * Pick (select) the provided day in the current month/year.\n * Notice that we programatically expand the `DatePicker` calendar before picking the date.\n * @param {string} day - Label for the day to be picked, formatted as mm/dd/yyyy.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function pick(day: string, input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n await expand(input)\n\n await act(async () => {\n input.focus()\n\n const dayElement = queries.getByLabelText(datePickerContainer, day)\n\n if (dayElement && dayElement.getAttribute('aria-checked') == 'false') {\n fireEvent.click(dayElement)\n }\n })\n\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n const datePickerContainer = getContainerFromInput(input)\n\n await act(async () => {\n const clearButton = queries.getByLabelText(datePickerContainer, 'Clear selection')\n\n fireEvent.click(clearButton)\n })\n\n await collapse(input)\n}\n\n/**\n * Get options elements currently selected in the `DatePicker` calendar.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedDates(input: HTMLElement): Promise<HTMLElement[]> {\n const datePickerContainer = getContainerFromInput(input)\n\n await expand(input)\n\n const selectedDays: HTMLElement[] = queries.queryAllByRole(datePickerContainer, 'checkbox', {\n checked: true,\n })\n\n await collapse(input)\n\n return selectedDays\n}\n\nconst datePickerEvent = {\n getContainer: getContainerFromInput,\n expand,\n collapse,\n pick,\n clear,\n getSelectedDates,\n}\n\nexport default datePickerEvent\n","/* eslint-disable */\nimport { queries } from '@testing-library/react'\n\nimport DatePickerEvent from './DatePickerEvent'\n\n/**\n * Expand the `DatePicker` calendar, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n await DatePickerEvent.expand(input)\n}\n\n/**\n * Collapse the `DatePicker` calendar, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n await DatePickerEvent.collapse(input)\n}\n\n/**\n * Pick (select) the provided day in the current month/year.\n * Notice that we programatically expand the `DatePicker` calendar before picking the date.\n * @param {string} day - Label for the day to be picked, formatted as mm/dd/yyyy.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function pick(range: [string | null, string | null], input: HTMLElement): Promise<void> {\n const dateRangePickerContainer = DatePickerEvent.getContainer(input)\n\n await expand(input)\n\n const [rangeStart, rangeEnd] = range\n\n if (rangeStart != null) {\n const dateRangeStartInput = queries.getByTestId(\n dateRangePickerContainer,\n 'input-date-range-start'\n )\n\n await DatePickerEvent.pick(rangeStart, dateRangeStartInput)\n }\n\n if (rangeEnd != null) {\n const dateRangeEndInput = queries.getByTestId(dateRangePickerContainer, 'input-date-range-end')\n\n await DatePickerEvent.pick(rangeEnd, dateRangeEndInput)\n }\n\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n await DatePickerEvent.clear(input)\n}\n\n/**\n * Get options elements currently selected in the `DatePicker` calendar.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `DatePicker`\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedDates(input: HTMLElement): Promise<HTMLElement[]> {\n return DatePickerEvent.getSelectedDates(input)\n}\n\nexport const dateRangePickerEvent = {\n getContainer: DatePickerEvent.getContainer,\n expand,\n collapse,\n pick,\n clear,\n getSelectedDates,\n}\n\nexport default dateRangePickerEvent\n","import { createEvent, fireEvent } from '@testing-library/react'\n\nimport toArray from 'utils/toolset/toArray'\n\n/**\n * Get the input dropzone, which is the input parent (label).\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst getDropZoneFromInput = (input: HTMLInputElement): HTMLLabelElement =>\n input.parentNode as HTMLLabelElement\n\n/**\n * Simulates the onDragOver event on the drop zone.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dragOver = (input: HTMLInputElement) => {\n const dropzone = getDropZoneFromInput(input)\n\n const dragOverEvent = createEvent.dragOver(dropzone)\n\n fireEvent(dropzone, dragOverEvent)\n}\n\n/**\n * Simulates the onDragLeave event on the drop zone.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dragLeave = (input: HTMLInputElement) => {\n const dropzone = getDropZoneFromInput(input)\n\n const dragLeaveEvent = createEvent.dragLeave(dropzone)\n\n fireEvent(dropzone, dragLeaveEvent)\n}\n\n/**\n * Simulates the onDrop event on the drop zone. You can provide a list of files or a single file.\n * @param {HTMLInputElement} input - You can refer to this element by the aria-label you provide to the DragDropFile component\n */\nconst dropFiles = (input: HTMLInputElement, files: File | File[]) => {\n const dropzone = getDropZoneFromInput(input)\n\n const fileDropEvent = createEvent.drop(dropzone)\n\n Object.defineProperty(fileDropEvent, 'dataTransfer', { value: { files: toArray(files) } })\n\n fireEvent(dropzone, fileDropEvent)\n}\n\nexport const DragDropFileEvent = {\n dragOver,\n dragLeave,\n dropFiles,\n}\n\nexport default DragDropFileEvent\n","import { act, waitFor, within, waitForElementToBeRemoved, fireEvent } from '@testing-library/react'\n\n// based on https://github.com/romgain/react-select-event/blob/master/src/index.ts\n\n// find the select container from its input field 🤷\nfunction getSelectContainer(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.parentNode as HTMLElement\n}\n\n/**\n * Please, make sure to call expand before trying to get the menu container\n */\nfunction getSelectMenu(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.parentNode!.nextSibling as HTMLElement\n}\n\nfunction getSelectTriggerHandle(input: HTMLElement): HTMLElement {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return input.parentNode!.nextSibling!.nextSibling as HTMLElement\n}\n\nfunction getSelectSearchContainer(input: HTMLElement): HTMLElement {\n return input.parentNode as HTMLElement\n}\n\nfunction isSelectMenuExpanded(input: HTMLElement): boolean {\n const selectContainer = getSelectContainer(input)\n\n /**\n * Once the select is expanded, we have the following structure:\n * +-------------+\n * | Close button (visually hidden)\n * +-------------+\n * | DropdownTrigger\n * +-------------+\n * | Popover\n * +-------------+\n *\n * This, if the container has 3 children, we assume the menu is expanded\n */\n return selectContainer.children.length === 3\n}\n\n/**\n * This is needed because some datasources might be asynchronous.\n * To ensure that the data they retrieve will be available, we wait for the\n * querying phase to finish.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n */\nasync function waitForPendingQuery(input: HTMLElement) {\n const searchContainer = getSelectSearchContainer(input)\n\n if (!within(searchContainer).queryByTestId('select-trigger-loading')) {\n return\n }\n\n await waitForElementToBeRemoved(\n () => within(searchContainer).queryByTestId('select-trigger-loading'),\n { timeout: 2500 }\n )\n}\n\n/**\n * Expand the `Select` menu, if it not already expanded.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function expand(input: HTMLElement): Promise<void> {\n await waitForPendingQuery(input)\n\n if (isSelectMenuExpanded(input)) {\n return\n }\n\n const triggerHandle = getSelectTriggerHandle(input)\n\n await waitFor(() => {\n expect(triggerHandle).toBeEnabled()\n })\n\n /**\n * Using act and a manually dispatched event so we can account for the\n * state changes that happen when the search input is clicked.\n * This is mainly related to the `handleEvent` from the `useClickOutside` hook.\n */\n act(() => {\n input.dispatchEvent(new MouseEvent('click', { bubbles: true }))\n })\n\n await waitFor(async () => {\n expect(await within(getSelectContainer(input)).findByRole('listbox')).toBeInTheDocument()\n })\n}\n\n/**\n * Collapse the `Select` menu, if it not already collapsed.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function collapse(input: HTMLElement): Promise<void> {\n if (!isSelectMenuExpanded(input)) {\n return\n }\n\n const triggerHandle = getSelectTriggerHandle(input)\n\n fireEvent.click(triggerHandle)\n\n await waitFor(() => {\n expect(within(getSelectContainer(input)).queryByRole('listbox')).not.toBeInTheDocument()\n })\n}\n\n/**\n * Select the provided option(s), if they are present in the menu.\n * Notice that we programatically expand the `Select` menu before select the item\n * @param {string} option - Label for the option to be selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function select(option: string, input: HTMLElement): Promise<void> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const optionElement = await within(menuContainer).findByLabelText(option)\n\n // click the option if exists; Select currently closes when an item is clicked.\n if (optionElement && optionElement.getAttribute('aria-selected') == 'false') {\n /**\n * This is a replacement for the `userEvent.click`.\n * We are adopting this approach to remove the peer dep to @testing-library/user-event for\n * applications using this helper, so they are not tied to the same user-event as this library.\n * It follows the same sequence of event stated in the documentation available at:\n * https://testing-library.com/docs/guide-events/#interactions-vs-events\n */\n fireEvent.mouseDown(optionElement)\n\n act(() => {\n optionElement.focus()\n })\n\n fireEvent.mouseUp(optionElement)\n fireEvent.click(optionElement)\n }\n\n // we collapse in the case the option was not clicked\n await collapse(input)\n}\n\n/**\n * Unselect the provided option(s), if they are present in the menu AND are selected.\n * Notice that we programatically expand the `Select` menu before select the item\n * @param {string} option - Label for the option to be unselected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function unselect(option: string, input: HTMLElement): Promise<void> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const optionElement = await within(menuContainer).findByLabelText(option)\n\n // ensures that the option exists and IS selected\n if (optionElement && optionElement.getAttribute('aria-selected') === 'true') {\n fireEvent.click(optionElement)\n }\n\n // we collapse in the case the option was not clicked\n await collapse(input)\n}\n\n/**\n * Clear the selection, if there are any options selected.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function clear(input: HTMLElement): Promise<void> {\n await waitForPendingQuery(input)\n\n const searchContainer = getSelectSearchContainer(input)\n\n const clearButton = within(searchContainer).getByTestId('select-trigger-clear')\n\n if (clearButton) {\n fireEvent.click(clearButton)\n }\n}\n\n/**\n * Perform search based on the given `query`. It will fail if the option is not found.\n * @param {string} query - Search term.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<void>}\n */\nasync function search(query: string, input: HTMLElement): Promise<void> {\n fireEvent.change(input, {\n target: { value: query },\n })\n\n await waitForPendingQuery(input)\n\n const menuContainer = getSelectMenu(input)\n\n await within(menuContainer).findAllByRole('option')\n}\n\n/**\n * Get options elements currently available in the `Select` menu.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getOptions(input: HTMLElement): Promise<HTMLElement[]> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n\n const options = within(menuContainer).queryAllByRole('option')\n\n await collapse(input)\n\n return options\n}\n\n/**\n * Get options elements currently selected in the `Select` menu.\n * @param {HTMLElement} input - You can refer to this element by the label you applied to the `Select`.\n * @returns {Promise<HTMLElement[]>}\n */\nasync function getSelectedOptions(input: HTMLElement): Promise<HTMLElement[]> {\n await expand(input)\n\n const menuContainer = getSelectMenu(input)\n let selectedOptions: HTMLElement[] = []\n\n try {\n selectedOptions = await within(menuContainer).findAllByRole('option', {\n selected: true,\n })\n } catch (err) {\n selectedOptions = []\n }\n\n await collapse(input)\n\n return selectedOptions\n}\n\nexport const selectEvent = {\n select,\n unselect,\n clear,\n search,\n expand,\n collapse,\n getOptions,\n getSelectedOptions,\n isMenuExpanded: isSelectMenuExpanded,\n}\n\nexport default selectEvent\n","import React, { ReactNode } from 'react'\nimport { render } from '@testing-library/react'\nimport type { RenderResult } from '@testing-library/react'\n\nimport type { DragDropFileContextValue } from '../../components/DragDropFile/types'\nimport { DragDropFileContext } from '../../components/DragDropFile/DragDropFile.context'\n\nconst defaultContextValueMock: DragDropFileContextValue = {\n fileList: [],\n onFilesAdded: jest.fn(),\n onRetryUpload: jest.fn(),\n onRemoveFile: jest.fn(),\n}\n\nconst renderWithDragDropFileProvider = (\n ui: ReactNode,\n customContext?: Partial<DragDropFileContextValue>\n): RenderResult => {\n const contextValue = { ...defaultContextValueMock, ...customContext }\n\n const renderedUi = (children: ReactNode) => (\n <DragDropFileContext.Provider value={contextValue}>{children}</DragDropFileContext.Provider>\n )\n\n return render(renderedUi(ui))\n}\n\nexport default renderWithDragDropFileProvider\n","import type { Interpolation, ThemeProps } from 'styled-components'\nimport { isFunction } from '@loadsmart/utils-function'\n\nimport { Alice } from '../../theming/themes'\nimport type { CustomTheme } from '../../theming'\nimport toArray from 'utils/toolset/toArray'\n\ntype ThemedInterpolation = Interpolation<ThemeProps<CustomTheme>>\n\n/**\n * Use this function to simulate the CSS that would be generated by styled-components\n * @param {Interpolation<ThemeProps<CustomTheme>>} styles - A `css` reference with interpolated styles\n * @returns {string} The final CSS\n */\nexport default function getInterpolatedStyles(styles: ThemedInterpolation): string {\n return toArray(styles)\n .map((interpolation) => {\n while (isFunction(interpolation)) {\n interpolation = interpolation({ theme: Alice })\n }\n\n return interpolation\n })\n .join('')\n}\n"],"names":["getContainerFromInput","input","parentNode","expand","datePickerContainer","queries","queryByRole","act","__awaiter","this","fireEvent","click","expect","findByRole","toBeInTheDocument","collapse","getByText","waitForElementToBeRemoved","datePickerEvent","getContainer","day","focus","dayElement","getByLabelText","getAttribute","clearButton","selectedDays","queryAllByRole","checked","DatePickerEvent","dateRangePickerEvent","pick","range","dateRangePickerContainer","rangeStart","rangeEnd","dateRangeStartInput","getByTestId","dateRangeEndInput","clear","getSelectedDates","getDropZoneFromInput","DragDropFileEvent","dragOver","dropzone","dragOverEvent","createEvent","dragLeave","dragLeaveEvent","dropFiles","files","fileDropEvent","drop","Object","defineProperty","value","toArray","getSelectContainer","getSelectMenu","nextSibling","getSelectTriggerHandle","getSelectSearchContainer","isSelectMenuExpanded","children","length","waitForPendingQuery","searchContainer","within","queryByTestId","timeout","triggerHandle","waitFor","toBeEnabled","dispatchEvent","MouseEvent","bubbles","not","selectEvent","select","option","menuContainer","optionElement","findByLabelText","mouseDown","mouseUp","unselect","search","query","change","target","findAllByRole","getOptions","options","getSelectedOptions","selectedOptions","selected","err","isMenuExpanded","defaultContextValueMock","fileList","onFilesAdded","jest","fn","onRetryUpload","onRemoveFile","styles","map","interpolation","isFunction","theme","Alice","join","ui","customContext","contextValue","assign","render","React","createElement","DragDropFileContext","Provider"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loadsmart/loadsmart-ui",
3
- "version": "6.0.8",
3
+ "version": "6.0.10",
4
4
  "description": "Miranda UI, a React UI library",
5
5
  "main": "dist",
6
6
  "files": [
@@ -151,7 +151,6 @@
151
151
  "peerDependencies": {
152
152
  "@loadsmart/miranda-tokens": ">=1.3.0",
153
153
  "@testing-library/react": ">=11.2.6",
154
- "@testing-library/user-event": "^13.5.0",
155
154
  "react": ">=16.8.0",
156
155
  "react-dom": ">=16.8.0",
157
156
  "styled-components": ">=5.3.0"
@@ -11,7 +11,6 @@ import selectEvent from '../../testing/SelectEvent'
11
11
 
12
12
  import type { SelectProps, Option } from './Select.types'
13
13
  import Select from './Select'
14
- import userEvent from '@testing-library/user-event'
15
14
  import type { Selectable } from 'hooks/useSelectable'
16
15
 
17
16
  const {
@@ -78,7 +77,7 @@ describe('Select', () => {
78
77
 
79
78
  expect(selectEvent.isMenuExpanded(searchInput)).toBe(true)
80
79
 
81
- const options = await selectEvent.getOptions(searchInput)
80
+ const options = await screen.findAllByRole('option')
82
81
 
83
82
  for (let i = 0; i < FRUITS.length; i++) {
84
83
  expect(options[i]).toHaveTextContent(FRUITS[i].label)
@@ -88,13 +87,21 @@ describe('Select', () => {
88
87
  it('expands with the available options when trigger handle is clicked', async () => {
89
88
  setup({})
90
89
 
90
+ const triggerHandle = screen.getByTestId('select-trigger-handle')
91
+
92
+ await waitFor(() => {
93
+ expect(triggerHandle).toBeEnabled()
94
+ })
95
+
91
96
  const searchInput = screen.getByLabelText('Select your favorite fruit')
92
97
 
93
98
  expect(selectEvent.isMenuExpanded(searchInput)).toBe(false)
94
99
 
95
- await selectEvent.expand(searchInput)
100
+ fire.click(triggerHandle)
96
101
 
97
- const options = await selectEvent.getOptions(searchInput)
102
+ expect(selectEvent.isMenuExpanded(searchInput)).toBe(true)
103
+
104
+ const options = await screen.findAllByRole('option')
98
105
 
99
106
  for (let i = 0; i < FRUITS.length; i++) {
100
107
  expect(options[i]).toHaveTextContent(FRUITS[i].label)
@@ -110,9 +117,14 @@ describe('Select', () => {
110
117
  expect(triggerHandle).toBeDisabled()
111
118
  expect(selectEvent.isMenuExpanded(searchInput)).toBe(false)
112
119
 
113
- userEvent.type(searchInput, generator.word())
114
-
115
- await selectEvent.expand(searchInput)
120
+ /**
121
+ * using userEvent.type goes beyond the event dispatching we need here to
122
+ * make the select component to react and expand the menu; additionally,
123
+ * it throws the `act` warning in `useClickOutide`'s `handleEvent`, but we do not have any testable evidence
124
+ * that can make for a valid assertion.
125
+ * that's why we use `fireEvent.change` instead of `userEvent.type`.
126
+ */
127
+ fire.change(searchInput, { target: { value: generator.word() } })
116
128
 
117
129
  expect(selectEvent.isMenuExpanded(searchInput)).toBe(true)
118
130
 
@@ -162,9 +174,7 @@ describe('Select', () => {
162
174
  const searchInput = screen.getByLabelText('Select your favorite fruit')
163
175
  const searchedFruit = generator.pickone([...FRUITS])
164
176
 
165
- fire.change(searchInput, {
166
- target: { value: searchedFruit.label },
167
- })
177
+ await selectEvent.search(searchedFruit.label, searchInput)
168
178
 
169
179
  const options = await selectEvent.getOptions(searchInput)
170
180
 
@@ -181,16 +191,41 @@ describe('Select', () => {
181
191
 
182
192
  await selectEvent.expand(selectInput)
183
193
 
184
- userEvent.click(document.body)
194
+ /**
195
+ * we are using `act` with manually triggered elements so RTL waits for
196
+ * all state changes that happen during click and key presses before proceeding to
197
+ * the assetions.
198
+ * If you remove these and replace with userEvent, you will see the `act` warning.
199
+ */
200
+ act(() => {
201
+ selectInput.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))
202
+ selectInput.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }))
203
+ })
204
+
205
+ act(() => {
206
+ selectInput.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
207
+ selectInput.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape', bubbles: true }))
208
+ })
209
+
210
+ await waitFor(() => {
211
+ expect(onBlur).toHaveBeenCalled()
212
+ })
185
213
 
186
214
  await selectEvent.expand(selectInput)
187
215
 
188
- userEvent.keyboard('{Escape}{/Escape}')
216
+ act(() => {
217
+ selectInput.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))
218
+ selectInput.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }))
219
+ })
189
220
 
190
- expect(onBlur).toHaveBeenCalledTimes(2)
221
+ act(() => {
222
+ document.body.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))
223
+ document.body.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }))
224
+ })
191
225
 
192
- expect(onBlur).toHaveBeenNthCalledWith(1, new MouseEvent('mousedown'))
193
- expect(onBlur).toHaveBeenNthCalledWith(2, new KeyboardEvent('keyup'))
226
+ await waitFor(() => {
227
+ expect(onBlur).toHaveBeenCalled()
228
+ })
194
229
  })
195
230
 
196
231
  it('shrinks when an option is selected', async () => {
@@ -314,6 +349,7 @@ describe('Select', () => {
314
349
 
315
350
  expect(await selectEvent.getSelectedOptions(searchInput)).toHaveLength(0)
316
351
  expect(searchInput).toHaveDisplayValue('')
352
+ expect(selectEvent.isMenuExpanded(searchInput)).toBe(false)
317
353
  })
318
354
 
319
355
  it('removes the clear button', async () => {
@@ -358,7 +394,7 @@ describe('Select', () => {
358
394
 
359
395
  expect(firstSelection).toHaveTextContent(firstOption.label)
360
396
  expect(secondSelection).toHaveTextContent(secondOption.label)
361
- }, 30_000)
397
+ })
362
398
 
363
399
  it('unselects a selected option keeping selected the others', async () => {
364
400
  const [firstOption, secondOption, thirdOption] = generator.pickset([...FRUITS], 3)
@@ -451,9 +487,7 @@ describe('Select', () => {
451
487
  const searchInput = screen.getByLabelText('Select the project manager')
452
488
  const searchedUser = generator.pickone([...USERS])
453
489
 
454
- fire.change(searchInput, {
455
- target: { value: searchedUser.name },
456
- })
490
+ await selectEvent.search(searchedUser.name, searchInput)
457
491
 
458
492
  const options = await selectEvent.getOptions(searchInput)
459
493
 
@@ -542,7 +576,7 @@ describe('Select', () => {
542
576
  const optionText = getOptionText(option)
543
577
  expect(selectedOptions[index]).toHaveTextContent(optionText)
544
578
  }
545
- }, 30_000)
579
+ })
546
580
 
547
581
  it.each([[{ multiple: true }], [{ multiple: false }]])(
548
582
  'overrides the empty component with %s',
@@ -1054,6 +1088,6 @@ describe('Select', () => {
1054
1088
 
1055
1089
  await selectEvent.expand(searchInput)
1056
1090
  expect(screen.getByText('No more options.')).toBeInTheDocument()
1057
- }, 30_000)
1091
+ })
1058
1092
  })
1059
1093
  })
@@ -30,6 +30,7 @@ import type {
30
30
  SelectDatasourceFunction,
31
31
  SelectProps,
32
32
  SelectStatus,
33
+ SelectValue,
33
34
  useSelectReturn,
34
35
  } from './Select.types'
35
36
 
@@ -223,7 +224,7 @@ function useSelect(props: SelectProps): useSelectReturn {
223
224
  multiple,
224
225
  adapters,
225
226
  onChange: useCallback(
226
- function handleSelectionChange(selected) {
227
+ function handleSelectionChange(selected: SelectValue) {
227
228
  onChange?.({ target: { id, name, value: getValue(selected, multiple) } })
228
229
  },
229
230
  [id, multiple, name, onChange]
@@ -303,13 +304,14 @@ function useSelect(props: SelectProps): useSelectReturn {
303
304
  toggle: dropdown.toggle,
304
305
  expanded: dropdown.expanded,
305
306
  onBlur(event?: MouseEvent | TouchEvent | KeyboardEvent) {
307
+ setQueryTyped(false)
308
+
306
309
  if (!multiple) {
307
310
  setQuery(getDisplayValue(adapters, selectable.selected, multiple))
308
311
  } else {
309
312
  setQuery('')
310
313
  }
311
314
  options.reset()
312
-
313
315
  onBlur?.(event)
314
316
  },
315
317
  expandDisabled,
@@ -338,10 +340,11 @@ function useSelect(props: SelectProps): useSelectReturn {
338
340
  },
339
341
  value: query,
340
342
  onChange(e: ChangeEvent<HTMLInputElement>) {
341
- onQueryChange?.(e)
343
+ const sanitizedValue = e.target.value.replace(/\s+/, '')
342
344
 
345
+ setQueryTyped(sanitizedValue !== '')
346
+ onQueryChange?.(e)
343
347
  setQuery(e.target.value)
344
- setQueryTyped(true)
345
348
  },
346
349
  onFocus: TriggerOnFocusHandler,
347
350
  }
@@ -353,10 +356,10 @@ function useSelect(props: SelectProps): useSelectReturn {
353
356
  function getClearProps() {
354
357
  return {
355
358
  onClick() {
359
+ setQueryTyped(false)
356
360
  setQuery('')
357
361
  selectable.clear()
358
362
  options.reset()
359
-
360
363
  triggerRef.current?.focus()
361
364
  },
362
365
  }
@@ -1,5 +1,4 @@
1
- import { act, waitFor, within, waitForElementToBeRemoved } from '@testing-library/react'
2
- import userEvent from '@testing-library/user-event'
1
+ import { act, waitFor, within, waitForElementToBeRemoved, fireEvent } from '@testing-library/react'
3
2
 
4
3
  // based on https://github.com/romgain/react-select-event/blob/master/src/index.ts
5
4
 
@@ -32,7 +31,7 @@ function isSelectMenuExpanded(input: HTMLElement): boolean {
32
31
  /**
33
32
  * Once the select is expanded, we have the following structure:
34
33
  * +-------------+
35
- * | Close button (visually hiddren)
34
+ * | Close button (visually hidden)
36
35
  * +-------------+
37
36
  * | DropdownTrigger
38
37
  * +-------------+
@@ -41,7 +40,7 @@ function isSelectMenuExpanded(input: HTMLElement): boolean {
41
40
  *
42
41
  * This, if the container has 3 children, we assume the menu is expanded
43
42
  */
44
- return selectContainer.children.length == 3
43
+ return selectContainer.children.length === 3
45
44
  }
46
45
 
47
46
  /**
@@ -81,7 +80,14 @@ async function expand(input: HTMLElement): Promise<void> {
81
80
  expect(triggerHandle).toBeEnabled()
82
81
  })
83
82
 
84
- userEvent.click(triggerHandle)
83
+ /**
84
+ * Using act and a manually dispatched event so we can account for the
85
+ * state changes that happen when the search input is clicked.
86
+ * This is mainly related to the `handleEvent` from the `useClickOutside` hook.
87
+ */
88
+ act(() => {
89
+ input.dispatchEvent(new MouseEvent('click', { bubbles: true }))
90
+ })
85
91
 
86
92
  await waitFor(async () => {
87
93
  expect(await within(getSelectContainer(input)).findByRole('listbox')).toBeInTheDocument()
@@ -100,7 +106,7 @@ async function collapse(input: HTMLElement): Promise<void> {
100
106
 
101
107
  const triggerHandle = getSelectTriggerHandle(input)
102
108
 
103
- userEvent.click(triggerHandle)
109
+ fireEvent.click(triggerHandle)
104
110
 
105
111
  await waitFor(() => {
106
112
  expect(within(getSelectContainer(input)).queryByRole('listbox')).not.toBeInTheDocument()
@@ -123,7 +129,21 @@ async function select(option: string, input: HTMLElement): Promise<void> {
123
129
 
124
130
  // click the option if exists; Select currently closes when an item is clicked.
125
131
  if (optionElement && optionElement.getAttribute('aria-selected') == 'false') {
126
- userEvent.click(optionElement)
132
+ /**
133
+ * This is a replacement for the `userEvent.click`.
134
+ * We are adopting this approach to remove the peer dep to @testing-library/user-event for
135
+ * applications using this helper, so they are not tied to the same user-event as this library.
136
+ * It follows the same sequence of event stated in the documentation available at:
137
+ * https://testing-library.com/docs/guide-events/#interactions-vs-events
138
+ */
139
+ fireEvent.mouseDown(optionElement)
140
+
141
+ act(() => {
142
+ optionElement.focus()
143
+ })
144
+
145
+ fireEvent.mouseUp(optionElement)
146
+ fireEvent.click(optionElement)
127
147
  }
128
148
 
129
149
  // we collapse in the case the option was not clicked
@@ -145,8 +165,8 @@ async function unselect(option: string, input: HTMLElement): Promise<void> {
145
165
  const optionElement = await within(menuContainer).findByLabelText(option)
146
166
 
147
167
  // ensures that the option exists and IS selected
148
- if (optionElement && optionElement.getAttribute('aria-selected') == 'true') {
149
- userEvent.click(optionElement)
168
+ if (optionElement && optionElement.getAttribute('aria-selected') === 'true') {
169
+ fireEvent.click(optionElement)
150
170
  }
151
171
 
152
172
  // we collapse in the case the option was not clicked
@@ -165,11 +185,9 @@ async function clear(input: HTMLElement): Promise<void> {
165
185
 
166
186
  const clearButton = within(searchContainer).getByTestId('select-trigger-clear')
167
187
 
168
- act(() => {
169
- if (clearButton) {
170
- userEvent.click(clearButton)
171
- }
172
- })
188
+ if (clearButton) {
189
+ fireEvent.click(clearButton)
190
+ }
173
191
  }
174
192
 
175
193
  /**
@@ -179,11 +197,15 @@ async function clear(input: HTMLElement): Promise<void> {
179
197
  * @returns {Promise<void>}
180
198
  */
181
199
  async function search(query: string, input: HTMLElement): Promise<void> {
182
- const selectContainer = getSelectContainer(input)
200
+ fireEvent.change(input, {
201
+ target: { value: query },
202
+ })
183
203
 
184
- userEvent.type(input, query)
204
+ await waitForPendingQuery(input)
205
+
206
+ const menuContainer = getSelectMenu(input)
185
207
 
186
- await within(selectContainer).findAllByRole('option', undefined, { timeout: 2500 })
208
+ await within(menuContainer).findAllByRole('option')
187
209
  }
188
210
 
189
211
  /**