From 8bc9f3476371e1adb0698570a704c36b7bab0ea0 Mon Sep 17 00:00:00 2001 From: Titani Labaj <39532947+tlabaj@users.noreply.github.com> Date: Tue, 21 Nov 2023 10:54:05 -0500 Subject: [PATCH] Rebase v6 branch (#9832) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(RTL): added right-to-left page demo (#9694) * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.20 - @patternfly/react-core@5.2.0-prerelease.20 - @patternfly/react-docs@6.2.0-prerelease.20 - demo-app-ts@5.1.1-prerelease.43 - @patternfly/react-table@5.2.0-prerelease.20 * fix(Wizard): onStepChange - skip isDisabled & isHidden (#9748) * fix(Text input): Added aria-expanded (#9705) * fix(Text input): Added aria-expanded * add interface * updates from review * fix(Notification Drawer): Added screen reader text for notification drawer item read state (#9569) * fix(Notification Drawer): Added screen reader text for notification drawer item read state * fix snapshot * Update prop description * add aria-live * update snapshots * feat(Wizard): ability to add props to WizardFooter buttons (#9709) * feat: ability to add props to WizardFooter buttons * fix(WizardFooter): null check * fix(Wizard): simpler design of adding footer buttons props * test(Wizard): can add props to footer buttons * docs(WizardFooter): move comment so docs have correct description * refactor(WizardFooter): move FooterButtonProps to types file * chore(Divider): update tests to new standards (#9714) * chore(Divider): update tests to new standards * changes from PR review * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.21 - @patternfly/react-core@5.2.0-prerelease.21 - @patternfly/react-docs@6.2.0-prerelease.21 - demo-app-ts@5.1.1-prerelease.44 - @patternfly/react-table@5.2.0-prerelease.21 * fix(TreeView): define button type (#9770) * bug(build): fixed built ESM files importing CJS files from react-styles (#9347) * bug(build): fixed built ESM files importing CJS files from react-styles * edited yarn.lock to invalidate deps cache in GH actions * excluded file extensions from react-styles path transform in ESM build * updated jest config to transform .mjs files * updated pr action to invalidate deps cache if package files added/edited * chore(deps): Add ts-node to support executing typescript files directly * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.22 - @patternfly/react-core@5.2.0-prerelease.22 - @patternfly/react-docs@6.2.0-prerelease.22 - demo-app-ts@5.1.1-prerelease.45 - @patternfly/react-table@5.2.0-prerelease.22 - transformer-react-styles-esm-imports@1.0.1-prerelease.0 * chore(deps): update dependency @patternfly/patternfly to v5.2.0-prerelease.4 (#9780) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-charts@7.2.0-prerelease.6 - @patternfly/react-code-editor@5.2.0-prerelease.23 - @patternfly/react-core@5.2.0-prerelease.23 - @patternfly/react-docs@6.2.0-prerelease.23 - @patternfly/react-icons@5.2.0-prerelease.6 - demo-app-ts@5.1.1-prerelease.46 - @patternfly/react-styles@5.2.0-prerelease.4 - @patternfly/react-table@5.2.0-prerelease.23 - @patternfly/react-tokens@5.2.0-prerelease.5 * feat(Datalist): implement full page Basic demo to match HTML #9048 (#9087) * feat(Datalist): implement full page Basic demo to match HTML #9048 * fix syntax error * comments applied * comments applied * comments applied * comments applied * \xa0 comments applied * move key per review comments * address PR comments * revert change to package.json * Converted basic demo to TS --------- Co-authored-by: nicolethoen Co-authored-by: Eric Olkowski * fix(ClipboardCopy): kepp caret position (#9772) * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.24 - @patternfly/react-core@5.2.0-prerelease.24 - @patternfly/react-docs@6.2.0-prerelease.24 - demo-app-ts@5.1.1-prerelease.47 - @patternfly/react-table@5.2.0-prerelease.24 * chore(deps): update devdependencies (#9757) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @patternfly/patternfly to v5.2.0-prerelease.5 (#9806) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update devdependencies (#9800) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-charts@7.2.0-prerelease.7 - @patternfly/react-code-editor@5.2.0-prerelease.25 - @patternfly/react-core@5.2.0-prerelease.25 - @patternfly/react-docs@6.2.0-prerelease.25 - @patternfly/react-icons@5.2.0-prerelease.7 - demo-app-ts@5.1.1-prerelease.48 - @patternfly/react-styles@5.2.0-prerelease.5 - @patternfly/react-table@5.2.0-prerelease.25 - @patternfly/react-tokens@5.2.0-prerelease.6 * fix(DatePicker): updated logic for parsing and focus management (#9794) * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.26 - @patternfly/react-core@5.2.0-prerelease.26 - @patternfly/react-docs@6.2.0-prerelease.26 - demo-app-ts@5.1.1-prerelease.49 - @patternfly/react-table@5.2.0-prerelease.26 * chore(PrimaryDetail): convert demos to TS (#9787) * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.27 - @patternfly/react-core@5.2.0-prerelease.27 - @patternfly/react-docs@6.2.0-prerelease.27 - demo-app-ts@5.1.1-prerelease.50 - @patternfly/react-table@5.2.0-prerelease.27 * chore(misc): clean up instances of Array.apply (#9798) * clean up instances of Array.apply * rename item to value * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.28 - @patternfly/react-core@5.2.0-prerelease.28 - @patternfly/react-docs@6.2.0-prerelease.28 - @patternfly/react-integration@5.1.1-prerelease.15 - demo-app-ts@5.1.1-prerelease.51 - @patternfly/react-table@5.2.0-prerelease.28 * chore(eslint): Added React Testing Library linter plugin (#9805) * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.29 - @patternfly/react-core@5.2.0-prerelease.29 - @patternfly/react-docs@6.2.0-prerelease.29 - @patternfly/react-icons@5.2.0-prerelease.8 - demo-app-ts@5.1.1-prerelease.52 - @patternfly/react-table@5.2.0-prerelease.29 * chore(DataList): update tests (#9672) * add spread prop test, update test * chore(DataList): update tests * fix merge error * break out into separate files, pr feedback * updates * fix some example ids * minor test updates * revert action change * bug(ClipboardCopy): change children type to string (#9743) * bug(ClipboardCopy): change children type to string Signed-off-by: gitdallas * fix clipboardcopyexpanded to work with string children Signed-off-by: gitdallas * refactor a bit * fix bad rebase --------- Signed-off-by: gitdallas * chore(deps): update devdependencies (#9817) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix Search Input - composable advanced search demo (#9484) * Search Input - composable advanced search fix date * remove isFill from datePicker * docs(custom menu): add example with search input inline filtering (#9687) * docs(custom menu): add example with search input inline filtering * refactor(demo menu): rename to InlineSearchFilterMenuDemo * chore(HelperText): update tests (#9761) * chore(HelperText): update tests * break out helpertextitem tests, update tests * updates * fix lint * fix(Chip): update tooltip vis when chip updates (#9819) * fix(Chip): enable tooltip when chip updates * fix casting * chore(DescriptionList): update tests (#9753) * chore(DescriptionList): update tests * break out tests, pr feedback * updates * add autofit width mod test * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.30 - @patternfly/react-core@5.2.0-prerelease.30 - @patternfly/react-docs@6.2.0-prerelease.30 - demo-app-ts@5.1.1-prerelease.53 - @patternfly/react-table@5.2.0-prerelease.30 * chore(TreeView): updated tests (#9773) * chore(TreeView): updated tests * Added tests for TreeViewListItem * Added tests for TreeViewRoot and TreeView * Updated snapshots and queries * chore(Table) convert demos to ts (#9621) * chore(table) convert to TS chore(DashboardWrapper) convert to TS chore(Table) convert demos to TS delete superfluous dashboard components declare as ts files remove duplicate ids fix import errors, WIP build errors sync toolbar demo with main * update import paths * fix more import paths * try import from dist/esm * fix build * convert remaining table demos to ts, WIP draggable logic * revert col management with draggable to previous dnd implementation * align file names with demo names, cleanup types, fix TS errors in demo files * update fileNames in table.md * PR feedback from Eric * fix category dropdown * fix demos, remove table actions that do not support main purpose of column management demos * add fix for a11y tests as suggested by Eric * update toolbar snap * add param type to labelText --------- Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.2.0-prerelease.31 - @patternfly/react-core@5.2.0-prerelease.31 - @patternfly/react-docs@6.2.0-prerelease.31 - demo-app-ts@5.1.1-prerelease.54 - @patternfly/react-table@5.2.0-prerelease.31 * chore(deps): update devdependencies (#9829) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --------- Signed-off-by: gitdallas Co-authored-by: Michael Coker <35148959+mcoker@users.noreply.github.com> Co-authored-by: patternfly-build Co-authored-by: Jeff Puzzo <96431149+jpuzz0@users.noreply.github.com> Co-authored-by: adamviktora <84135613+adamviktora@users.noreply.github.com> Co-authored-by: Mark Franceschelli <39063664+mfrances17@users.noreply.github.com> Co-authored-by: kmcfaul <45077788+kmcfaul@users.noreply.github.com> Co-authored-by: Austin Sullivan Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Kells512 <72694484+Kells512@users.noreply.github.com> Co-authored-by: nicolethoen Co-authored-by: Eric Olkowski Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com> Co-authored-by: Dallas Co-authored-by: Maria Co-authored-by: Dominik Petřík <77832970+Dominik-Petrik@users.noreply.github.com> --- .eslintignore | 1 - .eslintrc.json | 9 + .github/workflows/pr-preview.yml | 2 +- jest.config.js | 2 +- package.json | 7 +- packages/react-charts/CHANGELOG.md | 8 + packages/react-code-editor/CHANGELOG.md | 48 + packages/react-core/CHANGELOG.md | 70 + .../__tests__/AboutModalBox.test.tsx | 6 +- .../__tests__/AccordionItem.test.tsx | 4 +- .../Alert/__tests__/AlertGroup.test.tsx | 2 +- .../BackToTop/__tests__/BackToTop.test.tsx | 3 +- .../src/components/Button/Button.tsx | 2 +- .../Button/__tests__/Button.test.tsx | 1 - .../__tests__/CalendarMonth.test.tsx | 4 +- .../Card/__tests__/CardBody.test.tsx | 2 +- .../Card/__tests__/CardFooter.test.tsx | 2 +- .../react-core/src/components/Chip/Chip.tsx | 11 + .../Chip/__tests__/ChipGroup.test.tsx | 6 +- .../ClipboardCopy/ClipboardCopy.tsx | 47 +- .../ClipboardCopy/ClipboardCopyExpanded.tsx | 1 - .../__tests__/ClipboardCopyToggle.test.tsx | 1 - .../src/components/DataList/DataList.tsx | 2 + .../components/DataList/DataListAction.tsx | 2 +- .../DataList/__tests__/DataList.test.tsx | 444 +-- .../__tests__/DataListAction.test.tsx | 75 + .../DataList/__tests__/DataListCell.test.tsx | 120 + .../DataList/__tests__/DataListCheck.test.tsx | 5 + .../__tests__/DataListContent.test.tsx | 73 + .../DataList/__tests__/DataListItem.test.tsx | 46 + .../__tests__/DataListItemCells.test.tsx | 25 + .../__tests__/DataListItemRow.test.tsx | 44 + .../__tests__/DataListToggle.test.tsx | 61 + .../__snapshots__/DataList.test.tsx.snap | 325 +- .../DataListAction.test.tsx.snap | 11 + .../__snapshots__/DataListCell.test.tsx.snap | 11 + .../DataListContent.test.tsx.snap | 17 + .../__snapshots__/DataListItem.test.tsx.snap | 11 + .../DataListItemCells.test.tsx.snap | 9 + .../DataListItemRow.test.tsx.snap | 9 + .../DataListToggle.test.tsx.snap | 45 + .../DataList/examples/DataListCheckboxes.tsx | 10 +- .../examples/DataListMixedExpandable.tsx | 2 +- .../src/components/DatePicker/DatePicker.tsx | 6 +- .../DatePicker/__tests__/DatePicker.test.tsx | 10 +- .../__snapshots__/DatePicker.test.tsx.snap | 4 +- .../__tests__/DescriptionList.test.tsx | 230 +- .../DescriptionListDescription.test.tsx | 25 + .../__tests__/DescriptionListGroup.test.tsx | 25 + .../DescriptionListHelpTextButton.test.tsx | 27 + .../__tests__/DescriptionListTerm.test.tsx | 35 + .../DescriptionListTermHelpText.test.tsx | 25 + .../DescriptionList.test.tsx.snap | 158 +- .../DescriptionListDescription.test.tsx.snap | 15 + .../DescriptionListGroup.test.tsx.snap | 11 + ...escriptionListHelpTextButton.test.tsx.snap | 14 + .../DescriptionListTerm.test.tsx.snap | 15 + .../DescriptionListTermHelpText.test.tsx.snap | 11 + .../Divider/__tests__/Divider.test.tsx | 106 +- .../__snapshots__/Divider.test.tsx.snap | 42 +- .../Drawer/__tests__/Drawer.test.tsx | 12 +- .../Dropdown/__tests__/Dropdown.test.tsx | 6 +- .../Form/__tests__/FormContext.test.tsx | 89 +- .../Form/__tests__/FormFieldGroup.test.tsx | 2 +- .../Form/__tests__/FormGroup.test.tsx | 1 - .../Form/__tests__/FormHelperText.test.tsx | 1 - .../HelperText/__tests__/HelperText.test.tsx | 124 +- .../__tests__/HelperTextItem.test.tsx | 93 + .../__snapshots__/HelperText.test.tsx.snap | 225 +- .../HelperTextItem.test.tsx.snap | 15 + .../components/Icon/__tests__/Icon.test.tsx | 4 +- .../InputGroup/__tests__/InputGroup.test.tsx | 4 +- .../Masthead/__tests__/Masthead.test.tsx | 2 +- .../components/Menu/__tests__/Menu.test.tsx | 5 +- .../MenuToggle/__tests__/MenuToggle.test.tsx | 34 +- .../MultipleFileUploadStatus.test.tsx | 2 +- .../MultipleFileUploadStatusItem.test.tsx | 2 +- .../MultipleFileUploadTitle.test.tsx | 2 +- .../MultipleFileUploadTitleIcon.test.tsx | 2 +- .../MultipleFileUploadTitleText.test.tsx | 2 +- ...tipleFileUploadTitleTextSeparator.test.tsx | 2 +- .../src/components/Nav/__tests__/Nav.test.tsx | 28 +- .../src/components/Nav/examples/NavFlyout.tsx | 2 +- .../Nav/examples/NavHorizontalSubNav.tsx | 2 +- .../Nav/examples/NavLegacyTertiary.tsx | 2 +- .../__tests__/NotificationBadge.test.tsx | 2 +- .../NotificationDrawerHeader.tsx | 4 +- .../NotificationDrawerListItem.tsx | 12 + .../NotificationDrawerGroup.test.tsx | 4 +- .../NotificationDrawerListItem.test.tsx | 13 +- .../NotificationDrawerListItemHeader.test.tsx | 2 +- .../NotificationDrawerHeader.test.tsx.snap | 2 + .../NotificationDrawerListItem.test.tsx.snap | 8 +- .../__tests__/NumberInput.test.tsx | 12 +- .../Pagination/__tests__/Pagination.test.tsx | 6 +- .../Pagination/examples/PaginationSticky.tsx | 4 +- .../components/Panel/__tests__/Panel.test.tsx | 4 +- .../Popover/__tests__/Popover.test.tsx | 2 +- .../Progress/__tests__/Progress.test.tsx | 10 +- .../__tests__/ProgressStep.test.tsx | 2 +- .../__tests__/SearchInput.test.tsx | 21 +- .../__snapshots__/SearchInput.test.tsx.snap | 69 - .../__tests__/SkipToContent.test.tsx | 1 - .../Spinner/__tests__/Spinner.test.tsx | 2 +- .../Switch/__tests__/Switch.test.tsx | 2 +- .../Tabs/__tests__/OverflowTab.test.tsx | 2 +- .../components/Tabs/__tests__/Tabs.test.tsx | 10 +- .../src/components/TextInput/TextInput.tsx | 18 +- .../TextInput/__tests__/TextInput.test.tsx | 17 +- .../TextInput/examples/TextInput.md | 2 +- .../TimePicker/__tests__/TimePicker.test.tsx | 14 +- .../components/Toolbar/ToolbarToggleGroup.tsx | 2 +- .../Toolbar/__tests__/Toolbar.test.tsx | 4 +- .../Toolbar/__tests__/ToolbarGroup.test.tsx | 6 +- .../Toolbar/__tests__/ToolbarItem.test.tsx | 6 +- .../__snapshots__/Toolbar.test.tsx.snap | 1 - .../components/TreeView/TreeViewListItem.tsx | 6 +- .../TreeView/__tests__/TreeView.test.tsx | 517 +-- .../TreeView/__tests__/TreeViewList.test.tsx | 52 + .../__tests__/TreeViewListItem.test.tsx | 708 ++++ .../TreeView/__tests__/TreeViewRoot.test.tsx | 87 + .../__tests__/TreeViewSearch.test.tsx | 93 + .../__snapshots__/TreeView.test.tsx.snap | 3450 +---------------- .../__snapshots__/TreeViewList.test.tsx.snap | 29 + .../TreeViewListItem.test.tsx.snap | 83 + .../__snapshots__/TreeViewRoot.test.tsx.snap | 16 + .../TreeViewSearch.test.tsx.snap | 38 + .../src/components/Wizard/Wizard.tsx | 24 +- .../src/components/Wizard/WizardBody.tsx | 4 +- .../src/components/Wizard/WizardFooter.tsx | 25 +- .../components/Wizard/WizardNavInternal.tsx | 4 +- .../src/components/Wizard/WizardToggle.tsx | 2 +- .../Wizard/__tests__/Wizard.test.tsx | 205 +- .../Wizard/__tests__/WizardBody.test.tsx | 2 +- .../Wizard/__tests__/WizardToggle.test.tsx | 4 +- .../Wizard/__tests__/utils.test.tsx | 2 +- .../Wizard/examples/WizardGetCurrentStep.tsx | 42 +- .../src/components/Wizard/types.tsx | 4 + .../react-core/src/components/Wizard/utils.ts | 27 +- packages/react-core/src/demos/Banner.md | 8 +- .../src/demos/CustomMenus/CustomMenus.md | 6 + .../examples/InlineSearchFilterMenuDemo.tsx | 102 + .../demos/DataList/examples/DataListBasic.tsx | 314 ++ packages/react-core/src/demos/DataListDemo.md | 12 + .../react-core/src/demos/PrimaryDetail.md | 975 +---- packages/react-core/src/demos/RTL/RTL.md | 31 + .../src/demos/RTL/examples/PaginatedTable.css | 7 + .../src/demos/RTL/examples/PaginatedTable.jsx | 507 +++ .../demos/RTL/examples/translations.en.json | 67 + .../demos/RTL/examples/translations.he.json | 82 + .../src/demos/SearchInput/SearchInput.md | 2 +- .../examples/BackToTop/BackToTopNameDemo.tsx | 6 +- ...stheadWithUtilitiesAndUserDropdownMenu.tsx | 4 +- .../src/demos/examples/Nav/NavDefault.tsx | 2 +- .../src/demos/examples/Nav/NavExpandable.tsx | 2 +- .../src/demos/examples/Nav/NavHorizontal.tsx | 2 +- .../examples/Nav/NavHorizontalWithSubnav.tsx | 2 +- .../src/demos/examples/Nav/NavManual.tsx | 2 +- .../src/demos/examples/Nav/NavWithSubnav.tsx | 2 +- .../examples/Nav/deprecated/NavLight.tsx | 2 +- .../examples/Nav/deprecated/NavTertiary.tsx | 2 +- .../Page/PageStickySectionBreadcrumb.tsx | 4 +- .../examples/Page/PageStickySectionGroup.tsx | 4 +- .../Page/PageStickySectionGroupAlternate.tsx | 4 +- .../PrimaryDetail/PrimaryDetailCardView.tsx | 659 ++++ .../PrimaryDetailDataListInCard.tsx | 207 + .../PrimaryDetailSimpleListInCard.tsx | 116 + .../src/demos/examples/Wizard/InModal.tsx | 4 +- .../__tests__/ContextSelectorToggle.test.tsx | 8 +- .../__tests__/DropdownToggle.test.tsx | 2 +- .../Select/__tests__/Select.test.tsx | 2 +- .../Wizard/__tests__/Wizard.test.tsx | 6 +- .../GenerateId/__tests__/GenerateId.test.tsx | 2 +- .../src/helpers/OUIA/__mocks__/ouia.ts | 6 + .../react-core/src/helpers/__mocks__/index.ts | 2 + .../src/helpers/__tests__/fileUtils.test.ts | 15 +- .../src/helpers/__tests__/util.test.ts | 2 +- .../Bullseye/__tests__/Bullseye.test.tsx | 2 +- .../layouts/Grid/__tests__/GridItem.test.tsx | 2 +- packages/react-docs/CHANGELOG.md | 48 + packages/react-icons/CHANGELOG.md | 12 + .../src/__tests__/createIcon.test.tsx | 8 +- packages/react-integration/CHANGELOG.md | 4 + .../demo-app-ts/CHANGELOG.md | 48 + .../demos/BackToTopDemo/BackToTopDemo.tsx | 6 +- packages/react-styles/CHANGELOG.md | 8 + packages/react-table/CHANGELOG.md | 48 + .../examples/TableStickyColumnsAndHeader.tsx | 9 +- .../Table/utils/transformers.test.tsx | 1 + packages/react-table/src/demos/Table.md | 159 + .../examples/TableAutomaticPagination.tsx | 101 + .../examples/TableBulkSelect.tsx} | 61 +- .../demos/examples/TableColumnManagement.tsx | 486 +++ .../TableColumnManagementWithDraggable.tsx | 641 +++ .../examples/TableCompact.tsx} | 48 +- .../examples/TableCompoundExpansion.tsx} | 37 +- .../demos/examples/TableEmptyStateDefault.tsx | 60 + .../demos/examples/TableEmptyStateError.tsx | 53 + .../demos/examples/TableEmptyStateLoading.tsx | 43 + .../examples/TableExpandCollapseAll.tsx} | 27 +- .../src/demos/examples/TableFilterable.tsx | 394 ++ .../examples/TableSortableResponsive.tsx} | 56 +- .../examples/TableStaticBottomPagination.tsx} | 31 +- .../examples/TableStickyFirstColumn.tsx} | 40 +- .../examples/TableStickyHeader.tsx} | 6 +- packages/react-table/src/demos/index.ts | 1 + .../sampleData.js => demos/sampleData.tsx} | 165 +- .../components/Table/__tests__/Table.test.tsx | 13 +- packages/react-table/src/docs/demos/Table.md | 1620 -------- .../demos/table-demos/ColumnManagement.jsx | 471 --- packages/react-table/src/index.ts | 1 + packages/react-table/tsconfig.json | 5 +- packages/react-tokens/CHANGELOG.md | 8 + .../CHANGELOG.md | 8 + .../index.ts | 36 + .../package.json | 12 + packages/tsconfig.base.json | 3 +- yarn.lock | 1621 +++++--- 218 files changed, 9163 insertions(+), 9118 deletions(-) create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListAction.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListCell.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListContent.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListItem.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListItemCells.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListItemRow.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/DataListToggle.test.tsx create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListAction.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListCell.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListContent.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItem.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemCells.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemRow.test.tsx.snap create mode 100644 packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListToggle.test.tsx.snap create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/DescriptionListDescription.test.tsx create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/DescriptionListGroup.test.tsx create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/DescriptionListHelpTextButton.test.tsx create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTerm.test.tsx create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTermHelpText.test.tsx create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListDescription.test.tsx.snap create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListGroup.test.tsx.snap create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListHelpTextButton.test.tsx.snap create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTerm.test.tsx.snap create mode 100644 packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTermHelpText.test.tsx.snap create mode 100644 packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx create mode 100644 packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperTextItem.test.tsx.snap create mode 100644 packages/react-core/src/components/TreeView/__tests__/TreeViewList.test.tsx create mode 100644 packages/react-core/src/components/TreeView/__tests__/TreeViewListItem.test.tsx create mode 100644 packages/react-core/src/components/TreeView/__tests__/TreeViewRoot.test.tsx create mode 100644 packages/react-core/src/components/TreeView/__tests__/TreeViewSearch.test.tsx create mode 100644 packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeViewList.test.tsx.snap create mode 100644 packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeViewListItem.test.tsx.snap create mode 100644 packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeViewRoot.test.tsx.snap create mode 100644 packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeViewSearch.test.tsx.snap create mode 100644 packages/react-core/src/demos/CustomMenus/examples/InlineSearchFilterMenuDemo.tsx create mode 100644 packages/react-core/src/demos/DataList/examples/DataListBasic.tsx create mode 100644 packages/react-core/src/demos/RTL/RTL.md create mode 100644 packages/react-core/src/demos/RTL/examples/PaginatedTable.css create mode 100644 packages/react-core/src/demos/RTL/examples/PaginatedTable.jsx create mode 100644 packages/react-core/src/demos/RTL/examples/translations.en.json create mode 100644 packages/react-core/src/demos/RTL/examples/translations.he.json create mode 100644 packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailCardView.tsx create mode 100644 packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailDataListInCard.tsx create mode 100644 packages/react-core/src/demos/examples/PrimaryDetail/PrimaryDetailSimpleListInCard.tsx create mode 100644 packages/react-core/src/helpers/OUIA/__mocks__/ouia.ts create mode 100644 packages/react-core/src/helpers/__mocks__/index.ts create mode 100644 packages/react-table/src/demos/Table.md create mode 100644 packages/react-table/src/demos/examples/TableAutomaticPagination.tsx rename packages/react-table/src/{docs/demos/table-demos/BulkSelect.jsx => demos/examples/TableBulkSelect.tsx} (71%) create mode 100644 packages/react-table/src/demos/examples/TableColumnManagement.tsx create mode 100644 packages/react-table/src/demos/examples/TableColumnManagementWithDraggable.tsx rename packages/react-table/src/{docs/demos/table-demos/Compact.jsx => demos/examples/TableCompact.tsx} (80%) rename packages/react-table/src/{docs/demos/table-demos/CompoundExpansion.jsx => demos/examples/TableCompoundExpansion.tsx} (89%) create mode 100644 packages/react-table/src/demos/examples/TableEmptyStateDefault.tsx create mode 100644 packages/react-table/src/demos/examples/TableEmptyStateError.tsx create mode 100644 packages/react-table/src/demos/examples/TableEmptyStateLoading.tsx rename packages/react-table/src/{docs/demos/table-demos/ExpandCollapseAll.jsx => demos/examples/TableExpandCollapseAll.tsx} (91%) create mode 100644 packages/react-table/src/demos/examples/TableFilterable.tsx rename packages/react-table/src/{docs/demos/table-demos/SortableResponsive.jsx => demos/examples/TableSortableResponsive.tsx} (88%) rename packages/react-table/src/{docs/demos/table-demos/StaticBottomPagination.jsx => demos/examples/TableStaticBottomPagination.tsx} (83%) rename packages/react-table/src/{docs/demos/table-demos/StickyFirstColumn.jsx => demos/examples/TableStickyFirstColumn.tsx} (88%) rename packages/react-table/src/{docs/demos/table-demos/StickyHeader.jsx => demos/examples/TableStickyHeader.tsx} (90%) create mode 100644 packages/react-table/src/demos/index.ts rename packages/react-table/src/{docs/demos/table-demos/sampleData.js => demos/sampleData.tsx} (83%) delete mode 100644 packages/react-table/src/docs/demos/Table.md delete mode 100644 packages/react-table/src/docs/demos/table-demos/ColumnManagement.jsx create mode 100644 packages/transformer-react-styles-esm-imports/CHANGELOG.md create mode 100644 packages/transformer-react-styles-esm-imports/index.ts create mode 100644 packages/transformer-react-styles-esm-imports/package.json diff --git a/.eslintignore b/.eslintignore index 235d8b73c41..cdfefe2893d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,6 @@ # Javascript builds node_modules dist -__tests__ thirdparty tsc_out .out diff --git a/.eslintrc.json b/.eslintrc.json index b78d47c5ef8..3a119092f7d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -127,6 +127,15 @@ "rules": { "patternfly-react/no-anonymous-functions": "off" } + }, + { + "files": ["**/*.test.[jt]s?(x)"], + "extends": ["plugin:testing-library/react"], + "rules": { + "testing-library/no-node-access": "off", + "react/jsx-key": "off", + "no-console": "off" + } } ] } diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml index 2f400db2655..d943b7a14e5 100644 --- a/.github/workflows/pr-preview.yml +++ b/.github/workflows/pr-preview.yml @@ -26,7 +26,7 @@ jobs: node_modules **/node_modules ~/.cache/Cypress - key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock', 'packages/*/package.json') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - uses: actions/cache@v2 diff --git a/jest.config.js b/jest.config.js index 620b84b3b63..10cbcfd3396 100644 --- a/jest.config.js +++ b/jest.config.js @@ -10,7 +10,7 @@ module.exports = { ], roots: ['/packages'], transform: { - '^.+\\.[jt]sx?$': 'babel-jest', + '^.+\\.m?[jt]sx?$': 'babel-jest', '^.+\\.svg$': 'jest-transform-stub' }, setupFilesAfterEnv: ['/packages/testSetup.ts'], diff --git a/package.json b/package.json index 45f13ae3a79..ac9ce6ef184 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "14.5.1", - "@types/jest": "29.5.5", + "@types/jest": "29.5.8", "@types/react": "^18", "@types/react-dom": "^18", "@typescript-eslint/eslint-plugin": "^5.59.2", @@ -50,6 +50,7 @@ "eslint-plugin-markdown": "^3.0.0", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.32.2", + "eslint-plugin-testing-library": "^6.1.0", "fs-extra": "^11.1.1", "glob": "^9.3.0", "husky": "^4.3.0", @@ -64,7 +65,8 @@ "react-dom": "^18", "surge": "^0.23.1", "ts-patch": "^2.1.0", - "typescript": "^4.7.4" + "typescript": "^4.7.4", + "ts-node": "^10.9.1" }, "scripts": { "build": "yarn clean && yarn build:generate && yarn build:esm && yarn build:cjs && yarn build:subpaths && yarn build:single:packages", @@ -84,6 +86,7 @@ "lint:md": "yarn eslint packages --ext md --no-eslintrc --config .eslintrc-md.json --cache", "lint:ts": "yarn lint packages/*/src", "lint:versions": "node scripts/verifyPatternflyVersions.js", + "lint:tests": "yarn lint packages/*/src/components/*/__tests__/*.test.*", "prepare": "ts-patch install -s", "serve:docs": "yarn workspace @patternfly/react-docs serve", "serve:integration": "lerna run serve:demo-app", diff --git a/packages/react-charts/CHANGELOG.md b/packages/react-charts/CHANGELOG.md index 4f123e2e6ff..7a547260034 100644 --- a/packages/react-charts/CHANGELOG.md +++ b/packages/react-charts/CHANGELOG.md @@ -25,6 +25,14 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @patternfly/react-charts +# 7.2.0-prerelease.7 (2023-11-10) + +**Note:** Version bump only for package @patternfly/react-charts + +# 7.2.0-prerelease.6 (2023-11-03) + +**Note:** Version bump only for package @patternfly/react-charts + # 7.2.0-prerelease.5 (2023-10-26) **Note:** Version bump only for package @patternfly/react-charts diff --git a/packages/react-code-editor/CHANGELOG.md b/packages/react-code-editor/CHANGELOG.md index 568e555f137..e3bfeff2b75 100644 --- a/packages/react-code-editor/CHANGELOG.md +++ b/packages/react-code-editor/CHANGELOG.md @@ -51,6 +51,54 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline **Note:** Version bump only for package @patternfly/react-code-editor +# [5.2.0-prerelease.31](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.30...@patternfly/react-code-editor@5.2.0-prerelease.31) (2023-11-17) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.30](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.29...@patternfly/react-code-editor@5.2.0-prerelease.30) (2023-11-16) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.29](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.28...@patternfly/react-code-editor@5.2.0-prerelease.29) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.28](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.27...@patternfly/react-code-editor@5.2.0-prerelease.28) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.27](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.26...@patternfly/react-code-editor@5.2.0-prerelease.27) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.26](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.25...@patternfly/react-code-editor@5.2.0-prerelease.26) (2023-11-13) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.25](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.24...@patternfly/react-code-editor@5.2.0-prerelease.25) (2023-11-10) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.24](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.23...@patternfly/react-code-editor@5.2.0-prerelease.24) (2023-11-03) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.23](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.22...@patternfly/react-code-editor@5.2.0-prerelease.23) (2023-11-03) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.22](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.21...@patternfly/react-code-editor@5.2.0-prerelease.22) (2023-11-02) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.21](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.20...@patternfly/react-code-editor@5.2.0-prerelease.21) (2023-11-02) + +**Note:** Version bump only for package @patternfly/react-code-editor + +# [5.2.0-prerelease.20](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.19...@patternfly/react-code-editor@5.2.0-prerelease.20) (2023-11-02) + +**Note:** Version bump only for package @patternfly/react-code-editor + # [5.2.0-prerelease.19](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@5.2.0-prerelease.18...@patternfly/react-code-editor@5.2.0-prerelease.19) (2023-10-30) **Note:** Version bump only for package @patternfly/react-code-editor diff --git a/packages/react-core/CHANGELOG.md b/packages/react-core/CHANGELOG.md index 57b121f3334..6e3ba63ceed 100644 --- a/packages/react-core/CHANGELOG.md +++ b/packages/react-core/CHANGELOG.md @@ -76,6 +76,76 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline - **Drawer:** Added start and end to position props, updated resizing to work with RTL ([#9627](https://github.com/patternfly/patternfly-react/issues/9627)) ([e12b872](https://github.com/patternfly/patternfly-react/commit/e12b8726b9ebc2fec921b7316a270a9c09decf96)) +# [5.2.0-prerelease.31](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.30...@patternfly/react-core@5.2.0-prerelease.31) (2023-11-17) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.30](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.29...@patternfly/react-core@5.2.0-prerelease.30) (2023-11-16) + +### Bug Fixes + +- **Chip:** update tooltip vis when chip updates ([#9819](https://github.com/patternfly/patternfly-react/issues/9819)) ([18c140a](https://github.com/patternfly/patternfly-react/commit/18c140a2adcc1833e4b095755aa7495d1d88a177)) + +# [5.2.0-prerelease.29](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.28...@patternfly/react-core@5.2.0-prerelease.29) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.28](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.27...@patternfly/react-core@5.2.0-prerelease.28) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.27](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.26...@patternfly/react-core@5.2.0-prerelease.27) (2023-11-14) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.26](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.25...@patternfly/react-core@5.2.0-prerelease.26) (2023-11-13) + +### Bug Fixes + +- **DatePicker:** updated logic for parsing and focus management ([#9794](https://github.com/patternfly/patternfly-react/issues/9794)) ([a12cf31](https://github.com/patternfly/patternfly-react/commit/a12cf313f0924a61a8cf20ee78b4b27290b9c05f)) + +# [5.2.0-prerelease.25](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.24...@patternfly/react-core@5.2.0-prerelease.25) (2023-11-10) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.24](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.23...@patternfly/react-core@5.2.0-prerelease.24) (2023-11-03) + +### Bug Fixes + +- **ClipboardCopy:** kepp caret position ([#9772](https://github.com/patternfly/patternfly-react/issues/9772)) ([981361e](https://github.com/patternfly/patternfly-react/commit/981361e0de354bbe06c4a799b6e7c92228dab51f)) + +### Features + +- **Datalist:** implement full page Basic demo to match HTML [#9048](https://github.com/patternfly/patternfly-react/issues/9048) ([#9087](https://github.com/patternfly/patternfly-react/issues/9087)) ([ab18059](https://github.com/patternfly/patternfly-react/commit/ab1805993ed5e2b5ed3d2f1be4131e035152b468)) + +# [5.2.0-prerelease.23](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.22...@patternfly/react-core@5.2.0-prerelease.23) (2023-11-03) + +**Note:** Version bump only for package @patternfly/react-core + +# [5.2.0-prerelease.22](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.21...@patternfly/react-core@5.2.0-prerelease.22) (2023-11-02) + +### Bug Fixes + +- **TreeView:** define button type ([#9770](https://github.com/patternfly/patternfly-react/issues/9770)) ([a772c6d](https://github.com/patternfly/patternfly-react/commit/a772c6d67bfa4154979ee14a34ec954406503109)) + +# [5.2.0-prerelease.21](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.20...@patternfly/react-core@5.2.0-prerelease.21) (2023-11-02) + +### Bug Fixes + +- **Notification Drawer:** Added screen reader text for notification drawer item read state ([#9569](https://github.com/patternfly/patternfly-react/issues/9569)) ([bc19f91](https://github.com/patternfly/patternfly-react/commit/bc19f9148e872fb62d8cd2bf644a771d9c5650d7)) +- **Text input:** Added aria-expanded ([#9705](https://github.com/patternfly/patternfly-react/issues/9705)) ([7f6a62c](https://github.com/patternfly/patternfly-react/commit/7f6a62c1a3f860a8759c63cde17da6b763dd7b48)) +- **Wizard:** onStepChange - skip isDisabled & isHidden ([#9748](https://github.com/patternfly/patternfly-react/issues/9748)) ([4d4d623](https://github.com/patternfly/patternfly-react/commit/4d4d623d294bbc7821c6dc9156980f2b8c609c96)) + +### Features + +- **Wizard:** ability to add props to WizardFooter buttons ([#9709](https://github.com/patternfly/patternfly-react/issues/9709)) ([9f21cee](https://github.com/patternfly/patternfly-react/commit/9f21cee5438c8ec4d0e2c5c938f9fffda013757b)) + +# [5.2.0-prerelease.20](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.19...@patternfly/react-core@5.2.0-prerelease.20) (2023-11-02) + +### Bug Fixes + +- **RTL:** added right-to-left page demo ([#9694](https://github.com/patternfly/patternfly-react/issues/9694)) ([d7308ae](https://github.com/patternfly/patternfly-react/commit/d7308aebec1e3ff22df548b5613f058c9ba35262)) + # [5.2.0-prerelease.19](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@5.2.0-prerelease.18...@patternfly/react-core@5.2.0-prerelease.19) (2023-10-30) **Note:** Version bump only for package @patternfly/react-core diff --git a/packages/react-core/src/components/AboutModal/__tests__/AboutModalBox.test.tsx b/packages/react-core/src/components/AboutModal/__tests__/AboutModalBox.test.tsx index 6c1c8b0aaf0..9587eb1a531 100644 --- a/packages/react-core/src/components/AboutModal/__tests__/AboutModalBox.test.tsx +++ b/packages/react-core/src/components/AboutModal/__tests__/AboutModalBox.test.tsx @@ -3,10 +3,6 @@ import { render } from '@testing-library/react'; import { AboutModalBox } from '../AboutModalBox'; test('AboutModalBox Test', () => { - const { asFragment } = render( - - This is a AboutModalBox - - ); + const { asFragment } = render(This is a AboutModalBox); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Accordion/__tests__/AccordionItem.test.tsx b/packages/react-core/src/components/Accordion/__tests__/AccordionItem.test.tsx index d2a6c8ff540..ca18a80cf88 100644 --- a/packages/react-core/src/components/Accordion/__tests__/AccordionItem.test.tsx +++ b/packages/react-core/src/components/Accordion/__tests__/AccordionItem.test.tsx @@ -11,8 +11,6 @@ test('Renders children', () => { }); test('Matches the snapshot', () => { - const { asFragment } = render( - Test - ); + const { asFragment } = render(Test); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Alert/__tests__/AlertGroup.test.tsx b/packages/react-core/src/components/Alert/__tests__/AlertGroup.test.tsx index a2d6186f28d..09f37026d10 100644 --- a/packages/react-core/src/components/Alert/__tests__/AlertGroup.test.tsx +++ b/packages/react-core/src/components/Alert/__tests__/AlertGroup.test.tsx @@ -19,7 +19,7 @@ test('Alert Group renders without children', () => { }); test('Alert Group works with n children', () => { - const { asFragment } = render( + render( diff --git a/packages/react-core/src/components/BackToTop/__tests__/BackToTop.test.tsx b/packages/react-core/src/components/BackToTop/__tests__/BackToTop.test.tsx index 438bae01e72..61ba74b68c6 100644 --- a/packages/react-core/src/components/BackToTop/__tests__/BackToTop.test.tsx +++ b/packages/react-core/src/components/BackToTop/__tests__/BackToTop.test.tsx @@ -115,10 +115,11 @@ test('Clicking backToTop scrolls back to top of the element passed via scrollabl const user = userEvent.setup(); const wrapper = document.getElementById('backToTopWrapper'); fireEvent.scroll(wrapper as HTMLElement, { target: { scrollY: 401 } }); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion wrapper!.scrollTo = jest.fn(); await user.click(screen.getByRole(`button`).parentElement as Element); - expect(wrapper?.scrollTo).toBeCalledTimes(1); + expect(wrapper?.scrollTo).toHaveBeenCalledTimes(1); }); test('Passes correct text content to button child component', () => { diff --git a/packages/react-core/src/components/Button/Button.tsx b/packages/react-core/src/components/Button/Button.tsx index 53863058344..4f0a834ceb6 100644 --- a/packages/react-core/src/components/Button/Button.tsx +++ b/packages/react-core/src/components/Button/Button.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Button/button'; import { css } from '@patternfly/react-styles'; import { Spinner, spinnerSize } from '../Spinner'; -import { useOUIAProps, OUIAProps } from '../../helpers'; +import { useOUIAProps, OUIAProps } from '../../helpers/OUIA/ouia'; import { Badge } from '../Badge'; export enum ButtonVariant { diff --git a/packages/react-core/src/components/Button/__tests__/Button.test.tsx b/packages/react-core/src/components/Button/__tests__/Button.test.tsx index cbd758c1c83..a9d57d538f3 100644 --- a/packages/react-core/src/components/Button/__tests__/Button.test.tsx +++ b/packages/react-core/src/components/Button/__tests__/Button.test.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import CartArrowDownIcon from '@patternfly/react-icons/dist/esm/icons/cart-arrow-down-icon'; import { Button, ButtonVariant } from '../Button'; Object.values(ButtonVariant).forEach((variant) => { diff --git a/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx b/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx index 4b70968618e..f94e4af16a0 100644 --- a/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx +++ b/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx @@ -57,7 +57,9 @@ test('Next year dates have correct year in aria label', () => { }); test('InlineProps render correct wrapper component and attributes', () => { - render(Title, ariaLabelledby: "hi"}} />); + render( + Title, ariaLabelledby: 'hi' }} /> + ); const article = screen.getByRole('article'); expect(article).toHaveAttribute('aria-labelledby', 'hi'); diff --git a/packages/react-core/src/components/Card/__tests__/CardBody.test.tsx b/packages/react-core/src/components/Card/__tests__/CardBody.test.tsx index b4f77d82415..140f3b25a9e 100644 --- a/packages/react-core/src/components/Card/__tests__/CardBody.test.tsx +++ b/packages/react-core/src/components/Card/__tests__/CardBody.test.tsx @@ -30,7 +30,7 @@ describe('CardBody', () => { test('allows passing in a React Component as the component', () => { const Component = () =>
im a div
; - render(); + render(); expect(screen.getByText('im a div')).toBeInTheDocument(); }); diff --git a/packages/react-core/src/components/Card/__tests__/CardFooter.test.tsx b/packages/react-core/src/components/Card/__tests__/CardFooter.test.tsx index c48d145920c..19c7db7eab2 100644 --- a/packages/react-core/src/components/Card/__tests__/CardFooter.test.tsx +++ b/packages/react-core/src/components/Card/__tests__/CardFooter.test.tsx @@ -27,7 +27,7 @@ describe('CardFooter', () => { test('allows passing in a React Component as the component', () => { const Component = () =>
im a div
; - render(); + render(); expect(screen.getByText('im a div')).toBeInTheDocument(); }); }); diff --git a/packages/react-core/src/components/Chip/Chip.tsx b/packages/react-core/src/components/Chip/Chip.tsx index 52c6c62d518..12ab24e665c 100644 --- a/packages/react-core/src/components/Chip/Chip.tsx +++ b/packages/react-core/src/components/Chip/Chip.tsx @@ -81,6 +81,17 @@ class Chip extends React.Component { }); } + componentDidUpdate(_prevProps: ChipProps, prevState: ChipState) { + const nextIsTooltipVisible = Boolean( + this.span.current && this.span.current.offsetWidth < this.span.current.scrollWidth + ); + if (prevState.isTooltipVisible !== nextIsTooltipVisible) { + this.setState({ + isTooltipVisible: nextIsTooltipVisible + }); + } + } + setChipStyle = () => ({ [cssChipTextMaxWidth.name]: this.props.textMaxWidth }); diff --git a/packages/react-core/src/components/Chip/__tests__/ChipGroup.test.tsx b/packages/react-core/src/components/Chip/__tests__/ChipGroup.test.tsx index 807944710f1..148f985133e 100644 --- a/packages/react-core/src/components/Chip/__tests__/ChipGroup.test.tsx +++ b/packages/react-core/src/components/Chip/__tests__/ChipGroup.test.tsx @@ -115,7 +115,7 @@ test('chip group with closeBtnAriaLabel', () => { ); expect(screen.getByLabelText('close button aria label')).toBeInTheDocument(); - expect(screen.getByLabelText('close button aria label')).toHaveAccessibleName("close button aria label category"); + expect(screen.getByLabelText('close button aria label')).toHaveAccessibleName('close button aria label category'); }); test('chip group onClick', async () => { @@ -169,8 +169,6 @@ test('chip group expanded', async () => { }); test('overflow chip does not render by default when < 4 children are passed', async () => { - const user = userEvent.setup(); - render( 1 @@ -183,8 +181,6 @@ test('overflow chip does not render by default when < 4 children are passed', as }); test('overflow chip collapsed by default', async () => { - const user = userEvent.setup(); - render( 1 diff --git a/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx b/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx index b4338b36ce7..142fb4bed37 100644 --- a/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx +++ b/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx @@ -10,7 +10,7 @@ import { ClipboardCopyToggle } from './ClipboardCopyToggle'; import { ClipboardCopyExpanded } from './ClipboardCopyExpanded'; import { getOUIAProps, OUIAProps } from '../../helpers'; -export const clipboardCopyFunc = (event: React.ClipboardEvent, text?: React.ReactNode) => { +export const clipboardCopyFunc = (event: React.ClipboardEvent, text?: string) => { navigator.clipboard.writeText(text.toString()); }; @@ -21,12 +21,13 @@ export enum ClipboardCopyVariant { } export interface ClipboardCopyState { - text: string | number; + text: string; expanded: boolean; copied: boolean; + textWhenExpanded: string; } -export interface ClipboardCopyProps extends Omit, 'onChange'>, OUIAProps { +export interface ClipboardCopyProps extends Omit, 'onChange' | 'children'>, OUIAProps { /** Additional classes added to the clipboard copy container. */ className?: string; /** Tooltip message to display when hover the copy button */ @@ -70,12 +71,12 @@ export interface ClipboardCopyProps extends Omit /** Delay in ms before the tooltip appears. */ entryDelay?: number; /** A function that is triggered on clicking the copy button. */ - onCopy?: (event: React.ClipboardEvent, text?: React.ReactNode) => void; + onCopy?: (event: React.ClipboardEvent, text?: string) => void; /** A function that is triggered on changing the text. */ - onChange?: (event: React.FormEvent, text?: string | number) => void; + onChange?: (event: React.FormEvent, text?: string) => void; /** The text which is copied. */ - children: React.ReactNode; - /** Additional actions for inline-compact clipboard copy. Should be wrapped with ClipboardCopyAction. */ + children: string; + /** Additional actions for inline clipboard copy. Should be wrapped with ClipboardCopyAction. */ additionalActions?: React.ReactNode; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; @@ -88,12 +89,12 @@ class ClipboardCopy extends React.Component { if (prevProps.children !== this.props.children) { - this.setState({ text: this.props.children as string | number }); + this.setState({ text: this.props.children as string }); } }; @@ -136,11 +137,16 @@ class ClipboardCopy extends React.Component { + updateText = (event: React.FormEvent, text: string) => { this.setState({ text }); this.props.onChange(event, text); }; + updateTextWhenExpanded = (event: React.FormEvent, text: string) => { + this.setState({ textWhenExpanded: text }); + this.props.onChange(event, text); + }; + render = () => { const { /* eslint-disable @typescript-eslint/no-unused-vars */ @@ -229,7 +235,14 @@ class ClipboardCopy extends React.Component { + this.expandContent(_event); + if (this.state.expanded) { + this.setState({ text: this.state.textWhenExpanded }); + } else { + this.setState({ textWhenExpanded: this.state.text }); + } + }} id={`${toggleIdPrefix}${id}`} textId={`${textIdPrefix}${id}`} contentId={`${contentIdPrefix}${id}`} @@ -239,7 +252,7 @@ class ClipboardCopy extends React.Component { - onCopy(event, this.state.text); + onCopy(event, this.state.expanded ? this.state.textWhenExpanded : this.state.text); this.setState({ copied: true }); }} onTooltipHidden={() => this.setState({ copied: false })} @@ -266,7 +279,7 @@ class ClipboardCopy extends React.Component {this.state.text} diff --git a/packages/react-core/src/components/ClipboardCopy/ClipboardCopyExpanded.tsx b/packages/react-core/src/components/ClipboardCopy/ClipboardCopyExpanded.tsx index 8a82c3e0001..0c805495078 100644 --- a/packages/react-core/src/components/ClipboardCopy/ClipboardCopyExpanded.tsx +++ b/packages/react-core/src/components/ClipboardCopy/ClipboardCopyExpanded.tsx @@ -6,7 +6,6 @@ import { PickOptional } from '../../helpers/typeUtils'; export interface ClipboardCopyExpandedProps extends Omit { className?: string; - children: React.ReactNode; onChange?: (e: React.FormEvent, text: string) => void; isReadOnly?: boolean; isCode?: boolean; diff --git a/packages/react-core/src/components/ClipboardCopy/__tests__/ClipboardCopyToggle.test.tsx b/packages/react-core/src/components/ClipboardCopy/__tests__/ClipboardCopyToggle.test.tsx index bb6a297c470..49bc2b64c1b 100644 --- a/packages/react-core/src/components/ClipboardCopy/__tests__/ClipboardCopyToggle.test.tsx +++ b/packages/react-core/src/components/ClipboardCopy/__tests__/ClipboardCopyToggle.test.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { screen, render } from '@testing-library/react'; import { ClipboardCopyToggle } from '../ClipboardCopyToggle'; -import styles from '@patternfly/react-styles/css/components/ClipboardCopy/clipboard-copy'; import userEvent from '@testing-library/user-event'; const onClickMock = jest.fn(); diff --git a/packages/react-core/src/components/DataList/DataList.tsx b/packages/react-core/src/components/DataList/DataList.tsx index 5b2a82a738c..817fb1c6875 100644 --- a/packages/react-core/src/components/DataList/DataList.tsx +++ b/packages/react-core/src/components/DataList/DataList.tsx @@ -73,6 +73,7 @@ class DataList extends React.Component { const { className, children, + 'aria-label': ariaLabel, onSelectDataListItem, selectedDataListItemId, isCompact, @@ -106,6 +107,7 @@ class DataList extends React.Component { )} style={props.style} role="list" + aria-label={ariaLabel} {...props} ref={this.ref} > diff --git a/packages/react-core/src/components/DataList/DataListAction.tsx b/packages/react-core/src/components/DataList/DataListAction.tsx index 807bf915691..ea38de0e3e7 100644 --- a/packages/react-core/src/components/DataList/DataListAction.tsx +++ b/packages/react-core/src/components/DataList/DataListAction.tsx @@ -35,8 +35,8 @@ export const DataListAction: React.FunctionComponent = ({ id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, + /* eslint-disable @typescript-eslint/no-unused-vars */ isPlainButtonAction, - /* eslint-enable @typescript-eslint/no-unused-vars */ ...props }: DataListActionProps) => (
diff --git a/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx index a7a5bc878c1..f28b8cd6f2c 100644 --- a/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx +++ b/packages/react-core/src/components/DataList/__tests__/DataList.test.tsx @@ -5,346 +5,182 @@ import userEvent from '@testing-library/user-event'; import { DataList } from '../DataList'; import { DataListItem } from '../DataListItem'; -import { DataListAction } from '../DataListAction'; -import { DataListCell } from '../DataListCell'; -import { DataListToggle } from '../DataListToggle'; -import { DataListItemCells } from '../DataListItemCells'; import { DataListItemRow } from '../DataListItemRow'; -import { DataListContent } from '../DataListContent'; -import { Button } from '../../Button'; -import { Dropdown, DropdownList, DropdownItem } from '../../Dropdown'; -import { MenuToggle } from '../../MenuToggle'; -import styles from '@patternfly/react-styles/css/components/DataList/data-list'; -describe('DataList', () => { - test('List default', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; - test('List compact', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test('Renders to match snapshot', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); - describe('DataList variants', () => { - ['none', 'always', 'sm', 'md', 'lg', 'xl', '2xl'].forEach((oneBreakpoint) => { - test(`Breakpoint - ${oneBreakpoint}`, () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); - }); - }); +test(`Renders with default class ${styles.dataList}`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.dataList); +}); - test('List draggable', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders with custom class when className is passed`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass('custom'); +}); - test('List', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders with spread props`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveAttribute('id', 'test'); +}); - test('List renders with a hidden input to improve a11y when selectableRow is passed', () => { - render( - {}}> - - -

Test

-
-
-
- ); +test(`Renders with aria-label when aria-label is passed`, () => { + render(test); + expect(screen.getByText('test')).toHaveAccessibleName('list'); +}); - const selectableInput = screen.getByRole('radio', { hidden: true }); +test(`Renders ${styles.modifiers.compact} when isCompact = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.compact); +}); - expect(selectableInput).toBeInTheDocument(); +['nowrap', 'truncate', 'breakWord'].forEach((wrap) => { + test(`Renders with class ${styles.modifiers[wrap]} when wrapModifier = ${wrap} is pased`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers[wrap]); }); +}); - test('List does not render with a hidden input to improve a11y when selectableRow is not passed', () => { - render( - - - -

Test

-
-
-
- ); - - const selectableInput = screen.queryByRole('radio', { hidden: true }); - - expect(selectableInput).not.toBeInTheDocument(); +const gridBreakpointClasses = { + none: styles.modifiers.gridNone, + always: 'pf-m-grid', + sm: styles.modifiers.gridSm, + md: styles.modifiers.gridMd, + lg: styles.modifiers.gridLg, + xl: styles.modifiers.gridXl, + '2xl': styles.modifiers.grid_2xl +}; + +['none', 'always', 'sm', 'md', 'lg', 'xl', '2xl'].forEach((oneBreakpoint) => { + test(`Has breakpoint - ${oneBreakpoint} when gridBreakpoint is pased`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(gridBreakpointClasses[oneBreakpoint]); }); +}); - test('List calls selectableRow.onChange when the selectable input changes', async () => { - const mock = jest.fn(); - const user = userEvent.setup(); - - render( - - - -

Test

-
-
-
- ); - - const selectableInput = screen.getByRole('radio', { hidden: true }); - await user.click(selectableInput); +test(`Renders default class ${styles.dataList}`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.dataList); +}); - expect(mock).toHaveBeenCalled(); - }); +test('Renders custom class when passed', () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass('data-list-custom'); +}); - test('List does not call selectableRow.onChange when the selectable input is not changed', () => { - const mock = jest.fn(); +test('Renders with a hidden input to improve a11y when onSelectableRowChange is passed', () => { + render( + {}}> + + +

Test

+
+
+
+ ); - render( - - - -

Test

-
-
-
- ); + const selectableInput = screen.getByRole('radio', { hidden: true }); - expect(mock).not.toHaveBeenCalled(); - }); - - test('Item applies selectableInputAriaLabel to the hidden input', () => { - render( - {}}> - - -

Test

-
-
-
- ); + expect(selectableInput).toBeInTheDocument(); +}); - const selectableInput = screen.getByRole('radio', { hidden: true }); +test('Does not render with a hidden input to improve a11y when onSelectableRowChange is not passed', () => { + render( + + + +

Test

+
+
+
+ ); - expect(selectableInput).toHaveAccessibleName('Data list item label test'); - }); + const selectableInput = screen.queryByRole('radio', { hidden: true }); - test('Item defaults to labelling its input using its aria-labelledby prop', () => { - render( - {}}> - -

Test cell content

-
-
- ); + expect(selectableInput).not.toBeInTheDocument(); +}); - const selectableInput = screen.getByRole('radio', { hidden: true }); +test('Calls onSelectableRowChange when the selectable input changes', async () => { + const mock = jest.fn(); + const user = userEvent.setup(); - expect(selectableInput).toHaveAccessibleName('Test cell content'); - }); + render( + + + +

Test

+
+
+
+ ); - test('Item prioritizes selectableInputAriaLabel over aria-labelledby prop', () => { - render( - {}}> - -

Test cell content

-
-
- ); + const selectableInput = screen.getByRole('radio', { hidden: true }); + await user.click(selectableInput); - const selectableInput = screen.getByRole('radio', { hidden: true }); + expect(mock).toHaveBeenCalled(); +}); - expect(selectableInput).toHaveAccessibleName('Data list item label test'); - }); +test('Does not call onSelectableRowChange when the selectable input is not changed', () => { + const mock = jest.fn(); - test('Item default', () => { - const { asFragment } = render( - - test + render( + + + +

Test

+
- ); - expect(asFragment()).toMatchSnapshot(); - }); +
+ ); - test('Item expanded', () => { - render( - - test - - ); - expect(screen.getByRole('listitem')).toHaveClass(`${styles.dataListItem} ${styles.modifiers.expanded}`); - }); + expect(mock).not.toHaveBeenCalled(); +}); - test('Item', () => { - const { asFragment } = render( - - test +test('Applies selectableInputAriaLabel to the hidden input', () => { + render( + {}}> + + +

Test

+
- ); - expect(asFragment()).toMatchSnapshot(); - }); - - test('item row default', () => { - const { asFragment } = render(test); - expect(asFragment()).toMatchSnapshot(); - }); - - test('Cell default', () => { - const { asFragment } = render(Secondary); - expect(asFragment()).toMatchSnapshot(); - }); - - test('Cells', () => { - const { asFragment } = render( - - Primary Id - , - - Primary Id 2 - - ]} - /> - ); - expect(asFragment()).toMatchSnapshot(); - }); - - test('Cell with width modifier', () => { - [ - { width: 1, class: '' }, - { width: 2, class: 'pf-m-flex-2' }, - { width: 3, class: 'pf-m-flex-3' }, - { width: 4, class: 'pf-m-flex-4' }, - { width: 5, class: 'pf-m-flex-5' } - ].forEach((testCase, index) => { - const testId = `cell-test-id-${index}`; - - render( - - Primary Id - - ); - - const dataListCell = screen.getByTestId(testId); - - testCase.class === '' - ? expect(dataListCell).toHaveClass(styles.dataListCell) - : expect(dataListCell).toHaveClass(`${styles.dataListCell} ${testCase.class}`); - }); - }); +
+ ); - test('Cell with text modifiers', () => { - [ - { wrapModifier: null as any, class: '' }, - { wrapModifier: 'breakWord', class: 'pf-m-break-word' }, - { wrapModifier: 'nowrap', class: 'pf-m-nowrap' }, - { wrapModifier: 'truncate', class: 'pf-m-truncate' } - ].forEach((testCase, index) => { - const testId = `cell-test-id-${index}`; - - render( - - Primary Id - - ); - - const dataListCell = screen.getByTestId(testId); - - testCase.class === '' - ? expect(dataListCell).toHaveClass(styles.dataListCell) - : expect(dataListCell).toHaveClass(`${styles.dataListCell} ${testCase.class}`); - }); - }); - - test('Toggle default with aria label', () => { - render(); + const selectableInput = screen.getByRole('radio', { hidden: true }); - expect(screen.getByRole('button')).not.toHaveAttribute('aria-labelledby'); - expect(screen.getByRole('button')).toHaveAttribute('aria-label', 'Toggle details for'); - expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false'); - }); + expect(selectableInput).toHaveAccessibleName('Data list item label test'); +}); - test('Toggle expanded', () => { - render(); - expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'); - }); +test('Defaults to labelling its input using its aria-labelledby prop', () => { + render( + {}}> + +

Test cell content

+
+
+ ); - test('DataListAction dropdown', () => { - const { asFragment } = render( - - }> - - - action-1 - - , - - action-2 - - - - - ); - expect(asFragment()).toMatchSnapshot(); - }); + const selectableInput = screen.getByRole('radio', { hidden: true }); - test('DataListAction button', () => { - const { asFragment } = render( - - - - ); - expect(asFragment()).toMatchSnapshot(); - }); - - test('DataListAction visibility - show button when lg', () => { - render( - - - - ); - - expect(screen.getByRole('button').parentElement).toHaveClass('pf-m-hidden'); - expect(screen.getByRole('button').parentElement).toHaveClass('pf-m-visible-on-lg'); - }); + expect(selectableInput).toHaveAccessibleName('Test cell content'); +}); - test('DataListAction visibility - hide button on 2xl', () => { - render( - - - - ); - - expect(screen.getByRole('button').parentElement).toHaveClass('pf-m-hidden-on-2xl'); - }); +test('Prioritizes selectableInputAriaLabel over aria-labelledby prop', () => { + render( + {}}> + +

Test cell content

+
+
+ ); - test('DataListContent', () => { - const { asFragment } = render( test); - expect(asFragment()).toMatchSnapshot(); - }); + const selectableInput = screen.getByRole('radio', { hidden: true }); - test('DataListContent hasNoPadding', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); + expect(selectableInput).toHaveAccessibleName('Data list item label test'); }); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListAction.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListAction.test.tsx new file mode 100644 index 00000000000..38745263caa --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListAction.test.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListAction } from '../DataListAction'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render( + + test + + ); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListItemAction}`, () => { + render( + + test + + ); + expect(screen.getByText('test')).toHaveClass(styles.dataListItemAction, { exact: true }); +}); + +test(`Renders with custom class when className is passed`, () => { + render( + + test + + ); + expect(screen.getByText('test')).toHaveClass('test-class'); +}); + +test(`Renders with spread props`, () => { + render( + + test + + ); + expect(screen.getByText('test')).toHaveAttribute('dir', 'rtl'); +}); + +test(`Renders with class ${styles.dataListAction} when isPlainButtonAction = true`, () => { + render( + + test + + ); + expect(screen.getByText('test')).toHaveClass(styles.dataListAction); +}); + +['hidden', 'visible'].forEach((vis) => { + const visMod = vis as 'hidden' | 'visible'; + test(`Has visibility - ${vis} for every breakpoint`, () => { + render( + + test + + ); + + if (visMod === 'hidden') { + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}`]); + } + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}OnSm`]); + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}OnMd`]); + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}OnLg`]); + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}OnXl`]); + expect(screen.getByText('test')).toHaveClass(styles.modifiers[`${visMod}On_2xl`]); + }); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListCell.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListCell.test.tsx new file mode 100644 index 00000000000..6e5954384fa --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListCell.test.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListCell } from '../DataListCell'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Cell renders to match snapshot', () => { + const { asFragment } = render(Secondary); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.dataListCell}`, () => { + render( + + Primary Id + + ); + expect(screen.getByTestId('test')).toHaveClass(styles.dataListCell, { exact: true }); +}); + +test(`Renders custom class when className is passed`, () => { + render( + + Primary Id + + ); + expect(screen.getByTestId('test')).toHaveClass('test-class'); +}); + +test(`Renders with spread props`, () => { + render( + + Primary Id + + ); + expect(screen.getByText('Primary Id')).toHaveAttribute('id', 'test'); +}); + +test('Renders width modifier when width is passed', () => { + [ + { width: 1, class: '' }, + { width: 2, class: styles.modifiers.flex_2 }, + { width: 3, class: styles.modifiers.flex_3 }, + { width: 4, class: styles.modifiers.flex_4 }, + { width: 5, class: styles.modifiers.flex_5 } + ].forEach((testCase, index) => { + const testId = `cell-test-id-${index}`; + + render( + + Primary Id + + ); + + const dataListCell = screen.getByTestId(testId); + + testCase.class === '' + ? expect(dataListCell).not.toHaveClass( + styles.modifiers.flex_2, + styles.modifiers.flex_3, + styles.modifiers.flex_4, + styles.modifiers.flex_5 + ) + : expect(dataListCell).toHaveClass(`pf-v5-c-data-list__cell ${testCase.class}`, { exact: true }); + }); +}); + +test('Has text wrap modifiers when wrapModifier is passed', () => { + [ + { wrapModifier: null as any, class: '' }, + { wrapModifier: 'breakWord', class: styles.modifiers.breakWord }, + { wrapModifier: 'nowrap', class: styles.modifiers.nowrap }, + { wrapModifier: 'truncate', class: styles.modifiers.truncate } + ].forEach((testCase, index) => { + const testId = `cell-test-id-${index}`; + + render( + + Primary Id + + ); + + const dataListCell = screen.getByTestId(testId); + + testCase.class === '' + ? expect(dataListCell).not.toHaveClass( + styles.modifiers.breakWord, + styles.modifiers.nowrap, + styles.modifiers.truncate + ) + : expect(dataListCell).toHaveClass(`${testCase.class}`); + }); +}); + +test(`Renders with class ${styles.modifiers.alignRight} when alignRight is passed`, () => { + render( + + Primary Id + + ); + expect(screen.getByTestId('test')).toHaveClass(styles.modifiers.alignRight); +}); + +test(`Renders with class ${styles.modifiers.icon} when isIcon is passed`, () => { + render( + + Primary Id + + ); + expect(screen.getByTestId('test')).toHaveClass(styles.modifiers.icon); +}); + +test(`Renders with class ${styles.modifiers.noFill} when isFilled = false`, () => { + render( + + Primary Id + + ); + expect(screen.getByTestId('test')).toHaveClass(styles.modifiers.noFill); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListCheck.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListCheck.test.tsx index 9e69ff734e8..fa1424c746f 100644 --- a/packages/react-core/src/components/DataList/__tests__/DataListCheck.test.tsx +++ b/packages/react-core/src/components/DataList/__tests__/DataListCheck.test.tsx @@ -3,6 +3,11 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { DataListCheck } from '../DataListCheck'; +test(`Renders with spread props`, () => { + render(); + expect(screen.getByRole('checkbox')).toHaveAttribute('id', 'test'); +}); + it('does not throw a "A component is changing an uncontrolled input of type checkbox to be controlled" error when changed if using isChecked', async () => { const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const user = userEvent.setup(); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListContent.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListContent.test.tsx new file mode 100644 index 00000000000..912bb48f0de --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListContent.test.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListContent } from '../DataListContent'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render( test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListExpandableContent}`, () => { + render( + + test + + ); + expect(screen.getByTestId('test-id')).toHaveClass(styles.dataListExpandableContent, { exact: true }); +}); + +test(`Renders with default class ${styles.dataListExpandableContentBody}`, () => { + render( + + test + + ); + expect(screen.getByText('test')).toHaveClass(styles.dataListExpandableContentBody, { exact: true }); +}); + +test(`Renders with custom class when className is passed`, () => { + render( + + test + + ); + expect(screen.getByTestId('test-id')).toHaveClass('test-class'); +}); + +test(`Renders with id when id is passed`, () => { + render( + + test + + ); + expect(screen.getByTestId('test-id')).toHaveAttribute('id', 'idProp'); +}); + +test(`Renders with spread props`, () => { + render( + + test + + ); + expect(screen.getByTestId('test-id')).toHaveAttribute('dir', 'rtl'); +}); + +test(`Renders with class ${styles.modifiers.noPadding} when hasNoPadding is passed`, () => { + render( + + ); + expect(screen.getByText('test')).toHaveClass(styles.modifiers.noPadding); +}); + +test(`Renders with hidden property when isHidden is passed`, () => { + render( + + test + + ); + expect(screen.getByTestId('test-id')).toHaveAttribute('hidden'); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListItem.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListItem.test.tsx new file mode 100644 index 00000000000..54f358c8e83 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListItem.test.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListItem } from '../DataListItem'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render( + + test + + ); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListItem}`, () => { + render(test); + expect(screen.getByRole('listitem')).toHaveClass(styles.dataListItem, { exact: true }); +}); + +test('Renders with custom class name', () => { + render( + + test + + ); + expect(screen.getByRole('listitem')).toHaveClass('data-list-item-custom'); +}); + +test('Renders with spread props', () => { + render( + + test + + ); + expect(screen.getByRole('listitem')).toHaveAttribute('dir', 'rtl'); +}); + +test(`Renders class ${styles.modifiers.expanded} when isExpanded is passed`, () => { + render( + + test + + ); + expect(screen.getByRole('listitem')).toHaveClass(styles.modifiers.expanded); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListItemCells.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListItemCells.test.tsx new file mode 100644 index 00000000000..e8419f2b361 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListItemCells.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListItemCells } from '../DataListItemCells'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Cells renders to match snapshot', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListItemContent}`, () => { + render(); + expect(screen.getByText('test')).toHaveClass(styles.dataListItemContent, { exact: true }); +}); + +test(`Renders with custom class when className is passed`, () => { + render(); + expect(screen.getByText('test')).toHaveClass('custom'); +}); + +test(`Renders with spread props`, () => { + render(); + expect(screen.getByText('test')).toHaveAttribute('dir', 'rtl'); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListItemRow.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListItemRow.test.tsx new file mode 100644 index 00000000000..74ec2e6fafc --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListItemRow.test.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListItemRow } from '../DataListItemRow'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Item row renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListItemRow}`, () => { + render(test); + expect(screen.getByTestId('test')).toHaveClass(styles.dataListItemRow, { exact: true }); +}); + +test(`Renders with custom class when className is passed`, () => { + render( + + test + + ); + expect(screen.getByTestId('test')).toHaveClass('custom'); +}); + +test(`Renders with spread props`, () => { + render( + + test + + ); + expect(screen.getByTestId('test')).toHaveAttribute('dir', 'rtl'); +}); + +['nowrap', 'truncate', 'breakWord'].forEach((wrap) => { + test(`Renders with class ${styles.modifiers[wrap]} when wrapModifier = ${wrap} is pased`, () => { + render( + + test + + ); + expect(screen.getByTestId('test')).toHaveClass(styles.modifiers[wrap]); + }); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/DataListToggle.test.tsx b/packages/react-core/src/components/DataList/__tests__/DataListToggle.test.tsx new file mode 100644 index 00000000000..8f7f8b4cd9b --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/DataListToggle.test.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DataListToggle } from '../DataListToggle'; + +import styles from '@patternfly/react-styles/css/components/DataList/data-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders with default class ${styles.dataListToggle}`, () => { + render(); + expect(screen.getByRole('button').parentElement).toHaveClass(styles.dataListToggle); +}); + +test(`Renders with default class ${styles.dataListItemControl}`, () => { + render(); + expect(screen.getByRole('button').parentElement?.parentElement).toHaveClass(styles.dataListItemControl, { + exact: true + }); +}); + +test(`Renders with custom class when className is passed`, () => { + render(); + expect(screen.getByRole('button').parentElement?.parentElement).toHaveClass('custom'); +}); + +test(`Renders with spread props`, () => { + render(); + expect(screen.getByRole('button').parentElement?.parentElement).toHaveAttribute('dir', 'rtl'); +}); + +test(`Renders with spread buttonProps`, () => { + render(); + expect(screen.getByRole('button')).toHaveAttribute('disabled'); +}); + +test('Renders aria-labelledby by default when no custom aria-label is passed', () => { + render(); + + expect(screen.getByRole('button')).toHaveAttribute('aria-labelledby', 'row ex-toggle2'); +}); + +test('Does not render aria-labelledby when custom aria-label is passed', () => { + render(); + + expect(screen.getByRole('button')).not.toHaveAttribute('aria-labelledby'); + expect(screen.getByRole('button')).toHaveAccessibleName('Toggle details for'); +}); + +test(`Renders with ariaControls when ariaControls is passed`, () => { + render(); + expect(screen.getByRole('button')).toHaveAttribute('aria-controls', 'control'); +}); + +test('Renders with aria-expanded when isExpanded = true', () => { + render(); + + expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'); +}); diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap index ee9d1720bb9..c8bebb7725c 100644 --- a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataList.test.tsx.snap @@ -1,332 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`DataList Cell default 1`] = ` - -
- Secondary -
-
-`; - -exports[`DataList Cells 1`] = ` - -
-
- Primary Id -
-
- Primary Id 2 -
-
-
-`; - -exports[`DataList DataList variants Breakpoint - 2xl 1`] = ` - -
    - -`; - -exports[`DataList DataList variants Breakpoint - always 1`] = ` - -
      - -`; - -exports[`DataList DataList variants Breakpoint - lg 1`] = ` - -
        - -`; - -exports[`DataList DataList variants Breakpoint - md 1`] = ` - -
          - -`; - -exports[`DataList DataList variants Breakpoint - none 1`] = ` - -
            - -`; - -exports[`DataList DataList variants Breakpoint - sm 1`] = ` - -
              - -`; - -exports[`DataList DataList variants Breakpoint - xl 1`] = ` - -
                - -`; - -exports[`DataList DataListAction button 1`] = ` - -
                - -
                -
                -`; - -exports[`DataList DataListAction dropdown 1`] = ` - -
                -
                - -
                -
                - -
                -
                -
                -
                -
                -`; - -exports[`DataList DataListContent 1`] = ` - -
                -
                - test -
                -
                -
                -`; - -exports[`DataList DataListContent hasNoPadding 1`] = ` - - - -`; - -exports[`DataList Item 1`] = ` - -
              • - -`; - -exports[`DataList Item default 1`] = ` - -
              • - -`; - -exports[`DataList List 1`] = ` - -
                  - -`; - -exports[`DataList List compact 1`] = ` +exports[`Renders to match snapshot 1`] = `
                    - -`; - -exports[`DataList List default 1`] = ` - -
                      `; - -exports[`DataList List draggable 1`] = ` - -
                        - -`; - -exports[`DataList item row default 1`] = ` - -
                        - -`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListAction.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListAction.test.tsx.snap new file mode 100644 index 00000000000..cf61bf5eabf --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListAction.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        + test +
                        +
                        +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListCell.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListCell.test.tsx.snap new file mode 100644 index 00000000000..8dfb9393730 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListCell.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Cell renders to match snapshot 1`] = ` + +
                        + Secondary +
                        +
                        +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListContent.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListContent.test.tsx.snap new file mode 100644 index 00000000000..15736a7aa11 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListContent.test.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        +
                        + test +
                        +
                        +
                        +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItem.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItem.test.tsx.snap new file mode 100644 index 00000000000..1f0da0b84eb --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItem.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                      • + +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemCells.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemCells.test.tsx.snap new file mode 100644 index 00000000000..05d99f283e7 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemCells.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Cells renders to match snapshot 1`] = ` + +
                        + +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemRow.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemRow.test.tsx.snap new file mode 100644 index 00000000000..bacaa0a7320 --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListItemRow.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Item row renders to match snapshot 1`] = ` + +
                        + +`; diff --git a/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListToggle.test.tsx.snap b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListToggle.test.tsx.snap new file mode 100644 index 00000000000..cd3276482cf --- /dev/null +++ b/packages/react-core/src/components/DataList/__tests__/__snapshots__/DataListToggle.test.tsx.snap @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        +
                        + +
                        +
                        +
                        +`; diff --git a/packages/react-core/src/components/DataList/examples/DataListCheckboxes.tsx b/packages/react-core/src/components/DataList/examples/DataListCheckboxes.tsx index c4eb52d718c..8f3ca384ddd 100644 --- a/packages/react-core/src/components/DataList/examples/DataListCheckboxes.tsx +++ b/packages/react-core/src/components/DataList/examples/DataListCheckboxes.tsx @@ -166,8 +166,8 @@ export const DataListCheckboxes: React.FunctionComponent = () => { @@ -192,7 +192,7 @@ export const DataListCheckboxes: React.FunctionComponent = () => { @@ -231,8 +231,8 @@ export const DataListCheckboxes: React.FunctionComponent = () => { diff --git a/packages/react-core/src/components/DataList/examples/DataListMixedExpandable.tsx b/packages/react-core/src/components/DataList/examples/DataListMixedExpandable.tsx index 87648fdc0ed..7f6a33c6b9b 100644 --- a/packages/react-core/src/components/DataList/examples/DataListMixedExpandable.tsx +++ b/packages/react-core/src/components/DataList/examples/DataListMixedExpandable.tsx @@ -162,7 +162,7 @@ export const DataListMixedExpandable: React.FunctionComponent = () => { ]} /> val.split('-').length === 3 && new Date(`${val}T00:00:00`), + dateParse = (val: string) => (val.split('-').length === 3 ? new Date(`${val}T00:00:00`) : new Date(undefined)), isDisabled = false, placeholder = 'YYYY-MM-DD', value: valueProp = '', @@ -230,7 +230,7 @@ const DatePickerBase = ( return (
                        - + { test('Date picker with multiple validators does not show invalid icon on valid input', async () => { const user = userEvent.setup(); - const rangeValidator = (date: Date) => { - return ''; - }; + const rangeValidator = (_date: Date) => ''; - const rangeValidatorB = (date: Date) => { - return ''; - }; + const rangeValidatorB = (_date: Date) => ''; render(); @@ -119,7 +115,7 @@ test('Does not render emptyDateText when requiredDateOptions.isRequired is false await user.click(screen.getByRole('textbox')); await user.click(document.body); - expect(screen.queryByText('Date cannot be blank')).not.toBeInTheDocument; + expect(screen.queryByText('Date cannot be blank')).not.toBeInTheDocument(); }); test('Renders text input as invalid on blur when requiredDateOptions.isRequired is true', async () => { diff --git a/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap b/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap index ca761a7a7ef..6091153f111 100644 --- a/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +++ b/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap @@ -13,7 +13,7 @@ exports[`With popover opened 1`] = ` class="pf-v5-c-input-group" >
                        { - test('default', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); - test('1 col on all breakpoints', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; - test('2 col on all breakpoints', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test('Renders to match snapshot', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); - test('3 col on all breakpoints', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders default class ${styles.descriptionList}`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.descriptionList, { exact: true }); +}); - test('Horizontal Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test('Renders custom className', () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass('custom'); +}); - test('Compact Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); +Object.values(['1Col', '2Col', '3Col']).forEach((_col) => { + const col = _col as '1Col' | '2Col' | '3Col'; + test(`Renders ${col} on all breakpoints`, () => { + render( + + ); + expect(screen.getByLabelText('list')).toHaveClass( + styles.modifiers[col], + styles.modifiers[`${col}OnSm`], + styles.modifiers[`${col}OnMd`], + styles.modifiers[`${col}OnLg`], + styles.modifiers[`${col}OnXl`], + styles.modifiers[`${col}On_2xl`] + ); }); +}); - test('Compact Horizontal Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.horizontal} when isHorizontal = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.horizontal); +}); - test('Fluid Horizontal Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.compact} when isCompact = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.compact); +}); + +test(`Renders ${styles.modifiers.horizontal} and ${styles.modifiers.fluid} when isFluid = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.fluid, styles.modifiers.horizontal); +}); - test('alignment breakpoints', () => { - const { asFragment } = render( +Object.values(['horizontal', 'vertical']).forEach((_align) => { + const align = _align as 'horizontal' | 'vertical'; + test(`Renders ${align} on all breakpoints`, () => { + render( ); - expect(asFragment()).toMatchSnapshot(); + expect(screen.getByLabelText('list')).toHaveClass( + styles.modifiers[`${align}OnSm`], + styles.modifiers[`${align}OnMd`], + styles.modifiers[`${align}OnLg`], + styles.modifiers[`${align}OnXl`], + styles.modifiers[`${align}On_2xl`] + ); }); +}); - test('Auto Column Widths Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.autoColumnWidths} when isAutoColumnWidths = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.autoColumnWidths); +}); - test('Inline Grid Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.inlineGrid} when isInlineGrid = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.inlineGrid); +}); - test('Auto fit Description List', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.autoFit} when isAutoFit = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.autoFit); +}); - test('Auto fit with responsive grid Description List', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.fillColumns} when isFillColumns = true`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.fillColumns); +}); - test('Term default', () => { - const { asFragment } = render( - - test - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.displayLg} when displaySize = lg`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.displayLg); +}); - test('Term helper text', () => { - const { asFragment } = render( - - test - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test(`Renders ${styles.modifiers.display_2xl} when displaySize = 2xl`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveClass(styles.modifiers.display_2xl); +}); - test('Group', () => { - const { asFragment } = render( - - test - - ); - expect(asFragment()).toMatchSnapshot(); +test(`Renders style when isHorizontal and horizontalTermWidthModifier is set`, () => { + render( + + ); + expect(screen.getByLabelText('list')).toHaveStyle({ + '--pf-v5-c-description-list--m-horizontal__term--width': '12ch', + '--pf-v5-c-description-list--m-horizontal__term--width-on-sm': '15ch', + '--pf-v5-c-description-list--m-horizontal__term--width-on-md': '20ch', + '--pf-v5-c-description-list--m-horizontal__term--width-on-lg': '28ch', + '--pf-v5-c-description-list--m-horizontal__term--width-on-xl': '30ch', + '--pf-v5-c-description-list--m-horizontal__term--width-on-2xl': '35ch' }); +}); - test('Description', () => { - const { asFragment } = render( - - test - - ); - expect(asFragment()).toMatchSnapshot(); +test(`Renders style when termWidth is set`, () => { + render(); + expect(screen.getByLabelText('list')).toHaveStyle({ + '--pf-v5-c-description-list__term--width': '30px' }); }); + +test(`Renders style when isAutoFit and horizontalTermWidthModifier is set`, () => { + render( + + ); + expect(screen.getByLabelText('list')).toHaveAttribute( + 'style', + '--pf-v5-c-description-list--GridTemplateColumns--min: 50px; --pf-v5-c-description-list--GridTemplateColumns--min-on-sm: 50px; --pf-v5-c-description-list--GridTemplateColumns--min-on-md: 100px; --pf-v5-c-description-list--GridTemplateColumns--min-on-lg: 150px; --pf-v5-c-description-list--GridTemplateColumns--min-on-xl: 200px; --pf-v5-c-description-list--GridTemplateColumns--min-on-2xl: 300px;' + ); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListDescription.test.tsx b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListDescription.test.tsx new file mode 100644 index 00000000000..65367307167 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListDescription.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DescriptionListDescription } from '../DescriptionListDescription'; + +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.descriptionListDescription}`, () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveClass(styles.descriptionListDescription, { exact: true }); +}); + +test('Renders custom className', () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveClass('custom'); +}); + +test('Renders spread props', () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveAttribute('id', 'id'); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListGroup.test.tsx b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListGroup.test.tsx new file mode 100644 index 00000000000..53e84b545ff --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListGroup.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DescriptionListGroup } from '../DescriptionListGroup'; + +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.descriptionListGroup}`, () => { + render(test); + expect(screen.getByText('test')).toHaveClass(styles.descriptionListGroup, { exact: true }); +}); + +test('Renders custom className', () => { + render(test); + expect(screen.getByText('test')).toHaveClass('custom'); +}); + +test('Renders spread props', () => { + render(test); + expect(screen.getByText('test')).toHaveAttribute('id', 'id'); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListHelpTextButton.test.tsx b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListHelpTextButton.test.tsx new file mode 100644 index 00000000000..bb49c585450 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListHelpTextButton.test.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DescriptionListTermHelpTextButton } from '../DescriptionListTermHelpTextButton'; + +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.descriptionListText}`, () => { + render(test); + expect(screen.getByText('test')).toHaveClass(`${styles.descriptionListText} ${styles.modifiers.helpText}`, { + exact: true + }); +}); + +test('Renders custom className', () => { + render(test); + expect(screen.getByText('test')).toHaveClass('custom'); +}); + +test('Renders spread props', () => { + render(test); + expect(screen.getByText('test')).toHaveAttribute('id', 'id'); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTerm.test.tsx b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTerm.test.tsx new file mode 100644 index 00000000000..840db5199ea --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTerm.test.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DescriptionListTerm } from '../DescriptionListTerm'; + +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.descriptionListTerm}`, () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveClass(styles.descriptionListTerm, { exact: true }); +}); + +test(`Renders default class ${styles.descriptionListText}`, () => { + render(test); + expect(screen.getByText('test')).toHaveClass(styles.descriptionListText, { exact: true }); +}); + +test('Renders custom className', () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveClass('custom'); +}); + +test('Renders icon', () => { + render(icon
                        }>test); + expect(screen.getByText('icon').parentElement).toHaveClass(styles.descriptionListTermIcon); +}); + +test('Renders spread props', () => { + render(test); + expect(screen.getByText('test').parentElement).toHaveAttribute('id', 'id'); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTermHelpText.test.tsx b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTermHelpText.test.tsx new file mode 100644 index 00000000000..1bd9779d379 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/DescriptionListTermHelpText.test.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { DescriptionListTermHelpText } from '../DescriptionListTermHelpText'; + +import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list'; + +test('Renders to match snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); + +test(`Renders default class ${styles.descriptionListTerm}`, () => { + render(test); + expect(screen.getByText('test')).toHaveClass(styles.descriptionListTerm, { exact: true }); +}); + +test('Renders custom className', () => { + render(test); + expect(screen.getByText('test')).toHaveClass('custom'); +}); + +test('Renders spread props', () => { + render(test); + expect(screen.getByText('test')).toHaveAttribute('id', 'id'); +}); diff --git a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionList.test.tsx.snap b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionList.test.tsx.snap index b9bde9f6974..e59055aa1af 100644 --- a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionList.test.tsx.snap +++ b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionList.test.tsx.snap @@ -1,162 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Description List 1 col on all breakpoints 1`] = ` - -
                        - -`; - -exports[`Description List 2 col on all breakpoints 1`] = ` - -
                        - -`; - -exports[`Description List 3 col on all breakpoints 1`] = ` - -
                        - -`; - -exports[`Description List Auto Column Widths Description List 1`] = ` - -
                        - -`; - -exports[`Description List Auto fit Description List 1`] = ` - -
                        - -`; - -exports[`Description List Auto fit with responsive grid Description List 1`] = ` - -
                        - -`; - -exports[`Description List Compact Description List 1`] = ` - -
                        - -`; - -exports[`Description List Compact Horizontal Description List 1`] = ` - -
                        - -`; - -exports[`Description List Description 1`] = ` - -
                        -
                        - test -
                        -
                        -
                        -`; - -exports[`Description List Fluid Horizontal Description List 1`] = ` - -
                        - -`; - -exports[`Description List Group 1`] = ` - -
                        - test -
                        -
                        -`; - -exports[`Description List Horizontal Description List 1`] = ` - -
                        - -`; - -exports[`Description List Inline Grid Description List 1`] = ` - -
                        - -`; - -exports[`Description List Term default 1`] = ` - -
                        - - test - -
                        -
                        -`; - -exports[`Description List Term helper text 1`] = ` - -
                        - - test - -
                        -
                        -`; - -exports[`Description List alignment breakpoints 1`] = ` - -
                        - -`; - -exports[`Description List default 1`] = ` +exports[`Renders to match snapshot 1`] = `
                        +
                        +
                        + test +
                        +
                        + +`; diff --git a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListGroup.test.tsx.snap b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListGroup.test.tsx.snap new file mode 100644 index 00000000000..73b0656b755 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListGroup.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        + test +
                        +
                        +`; diff --git a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListHelpTextButton.test.tsx.snap b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListHelpTextButton.test.tsx.snap new file mode 100644 index 00000000000..1d85b2b7303 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListHelpTextButton.test.tsx.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + + + test + + +`; diff --git a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTerm.test.tsx.snap b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTerm.test.tsx.snap new file mode 100644 index 00000000000..a99897481de --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTerm.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        + + test + +
                        +
                        +`; diff --git a/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTermHelpText.test.tsx.snap b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTermHelpText.test.tsx.snap new file mode 100644 index 00000000000..883c9a40ad7 --- /dev/null +++ b/packages/react-core/src/components/DescriptionList/__tests__/__snapshots__/DescriptionListTermHelpText.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        + test +
                        +
                        +`; diff --git a/packages/react-core/src/components/Divider/__tests__/Divider.test.tsx b/packages/react-core/src/components/Divider/__tests__/Divider.test.tsx index 6b940d6841c..680e164373b 100644 --- a/packages/react-core/src/components/Divider/__tests__/Divider.test.tsx +++ b/packages/react-core/src/components/Divider/__tests__/Divider.test.tsx @@ -1,34 +1,98 @@ -import { Divider } from '../Divider'; -import { Flex, FlexItem } from '../../../layouts/Flex'; import * as React from 'react'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import { Divider } from '../Divider'; +import styles from '@patternfly/react-styles/css/components/Divider/divider'; -test('divider using hr', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); +test(`Renders with only the class name ${styles.divider} by default`, () => { + render(); + expect(screen.getByRole('separator')).toHaveClass(styles.divider, { exact: true }); }); -test('divider using li', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); +test('Renders with horizontal rule by default', () => { + render(); + expect(screen.getByRole('separator')).toContainHTML('
                        '); }); -test('divider using div', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); +test('Renders with element passed to component prop', () => { + render(); + expect(screen.getByRole('separator')?.tagName).toBe('LI'); +}); + +test('Test default orientation (vertical divider)', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-vertical'); +}); + +test('Test sm orientation', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-horizontal-on-sm'); +}); + +test('Test md orientation', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-vertical-on-md'); +}); + +test('Test lg orientation', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-horizontal-on-lg'); +}); + +test('Test xl orientation', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-vertical-on-xl'); +}); + +test('Test 2xl orientation', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-horizontal-on-2xl'); +}); + +test('Test default inset', () => { + render(); + expect(screen.getByRole('separator')).toHaveClass('pf-m-inset-none'); }); -test('vertical divider', () => { - const { asFragment } = render( - - first item +test(`Test all insets`, () => { + const insetValues = Object.values([ + 'insetNone', + 'insetXs', + 'insetSm', + 'insetMd', + 'insetLg', + 'insetXl', + 'inset2xl', + 'inset3xl' + ] as ['insetNone', 'insetXs', 'insetSm', 'insetMd', 'insetLg', 'insetXl', 'inset2xl', 'inset3xl']); + + insetValues.forEach((insetValue) => { + render( - second item - - ); + ); + }); + const modifiers = ['none', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl']; + + modifiers.forEach((modifier, index) => { + const smClass = `pf-m-inset-${modifier}-on-sm`; + const mdClass = `pf-m-inset-${modifier}-on-md`; + const lgClass = `pf-m-inset-${modifier}-on-lg`; + const xlClass = `pf-m-inset-${modifier}-on-xl`; + const xl2Class = `pf-m-inset-${modifier}-on-2xl`; + + expect(screen.getAllByRole('separator')[index]).toHaveClass(smClass, mdClass, lgClass, xlClass, xl2Class); + }); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap b/packages/react-core/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap index 03b490d6b5b..1821213154b 100644 --- a/packages/react-core/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap +++ b/packages/react-core/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap @@ -1,49 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`divider using div 1`] = ` - - }>help test text); + expect(screen.getByText('test').parentElement).toHaveClass(styles.helperTextItemIcon); +}); + +test('Renders default icon when hasIcon = true and icon is not passed', () => { + render(help test text); + expect(screen.getByText('help test text').parentElement?.querySelector('span')).toHaveClass( + styles.helperTextItemIcon + ); +}); + +test('Renders custom icon when icon is passed and hasIcon = true', () => { + render( + test
                        }> + help test text + + ); + expect(screen.getByText('test').parentElement).toHaveClass(styles.helperTextItemIcon); +}); + +test('Renders dynamic helper text', () => { + render(help test text); + expect(screen.getByText('help test text').parentElement).toHaveClass(styles.modifiers.dynamic); + expect(screen.getByText('help test text').querySelector('span')).toHaveClass('pf-v5-screen-reader'); +}); + +test('Renders custom screenreader text when isDynamic = true and screenReaderText is passed', () => { + render( + + help test text + + ); + expect(screen.getByText('help test text').querySelector('span')).toHaveTextContent('sr test'); +}); diff --git a/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperText.test.tsx.snap b/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperText.test.tsx.snap index bc7fa094120..80d9d88b05f 100644 --- a/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperText.test.tsx.snap +++ b/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperText.test.tsx.snap @@ -1,230 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`HelperText default helper text variant applies successfully 1`] = ` +exports[`Renders to match snapshot 1`] = `
                        - - default help test text - -
                        -
                        -`; - -exports[`HelperText dynamic helper text renders successfully 1`] = ` - -
                        -
                        - - - help test text - - : default status; - - -
                        -
                        -
                        -`; - -exports[`HelperText helper text block renders successfully 1`] = ` - -
                        -
                        - - help test text 1 - -
                        -
                        - - help test text 2 - -
                        -
                        - - help test text 3 - -
                        -
                        -
                        -`; - -exports[`HelperText icon helper text renders properly 1`] = ` - -
                        -
                        - - - help test text - -
                        -
                        -
                        -`; - -exports[`HelperText indeterminate helper text variant applies successfully 1`] = ` - -
                        - - indeterminate help test text - -
                        -
                        -`; - -exports[`HelperText invalid helper text variant applies successfully 1`] = ` - -
                        - - invalid help test text - -
                        -
                        -`; - -exports[`HelperText simple helper text renders successfully 1`] = ` - -
                        -
                        - - help test text - -
                        -
                        -
                        -`; - -exports[`HelperText success helper text variant applies successfully 1`] = ` - -
                        - - success help test text - -
                        -
                        -`; - -exports[`HelperText variant comonent helper text renders properly 1`] = ` - -
                          -
                        • - - help test text 1 - -
                        • -
                        • - - help test text 2 - -
                        • -
                        -
                        -`; - -exports[`HelperText warning helper text variant applies successfully 1`] = ` - -
                        - - warning help test text - -
                        + />
                        `; diff --git a/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperTextItem.test.tsx.snap b/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperTextItem.test.tsx.snap new file mode 100644 index 00000000000..a06fcc63aaa --- /dev/null +++ b/packages/react-core/src/components/HelperText/__tests__/__snapshots__/HelperTextItem.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Renders to match snapshot 1`] = ` + +
                        + + help test text + +
                        +
                        +`; diff --git a/packages/react-core/src/components/Icon/__tests__/Icon.test.tsx b/packages/react-core/src/components/Icon/__tests__/Icon.test.tsx index b2f2e67de4f..54b56a0ea81 100644 --- a/packages/react-core/src/components/Icon/__tests__/Icon.test.tsx +++ b/packages/react-core/src/components/Icon/__tests__/Icon.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { render, screen } from '@testing-library/react'; import { Icon } from '../Icon'; -import { CheckIcon } from '@patternfly/react-icons'; +import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon'; import styles from '@patternfly/react-styles/css/components/Icon/icon'; test('renders basic icon successfully', () => { @@ -14,7 +14,7 @@ test('renders basic icon successfully', () => { }); test('checks basic icon structure', () => { - const { asFragment } = render( + render( diff --git a/packages/react-core/src/components/InputGroup/__tests__/InputGroup.test.tsx b/packages/react-core/src/components/InputGroup/__tests__/InputGroup.test.tsx index dd35dd426f7..0c9b1534937 100644 --- a/packages/react-core/src/components/InputGroup/__tests__/InputGroup.test.tsx +++ b/packages/react-core/src/components/InputGroup/__tests__/InputGroup.test.tsx @@ -23,7 +23,7 @@ describe('InputGroup', () => {
                        ); - const formControl = screen.getByLabelText("User password"); - expect(formControl).not.toHaveAttribute("aria-describedby"); + const formControl = screen.getByLabelText('User password'); + expect(formControl).not.toHaveAttribute('aria-describedby'); }); }); diff --git a/packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx b/packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx index ef95c453749..df7b7cc1a35 100644 --- a/packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx +++ b/packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx @@ -62,7 +62,7 @@ describe('Masthead', () => { 'insetXl', 'inset2xl', 'inset3xl' - ]).forEach(inset => { + ]).forEach((inset) => { test(`verify ${inset} inset breakpoints`, () => { const { asFragment } = render( test diff --git a/packages/react-core/src/components/Menu/__tests__/Menu.test.tsx b/packages/react-core/src/components/Menu/__tests__/Menu.test.tsx index 83627d08d58..b230896c249 100644 --- a/packages/react-core/src/components/Menu/__tests__/Menu.test.tsx +++ b/packages/react-core/src/components/Menu/__tests__/Menu.test.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; -import userEvent from '@testing-library/user-event'; import { Menu } from '../Menu'; import { MenuItem } from '../MenuItem'; @@ -54,7 +53,7 @@ describe('Menu', () => { describe('with hasCheckbox', () => { test('should render Menu with checkbox items', () => { - const { asFragment } = render( + render( @@ -67,7 +66,7 @@ describe('Menu', () => { ); const checkbox1 = screen.getAllByRole('checkbox')[0]; expect(checkbox1).not.toBeChecked(); - expect(screen.getByText("Checkbox 1")).toBeInTheDocument(); + expect(screen.getByText('Checkbox 1')).toBeInTheDocument(); }); }); }); diff --git a/packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx b/packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx index 55b75090b57..b56971f6ffd 100644 --- a/packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx +++ b/packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx @@ -5,7 +5,7 @@ import { Badge } from '../../Badge'; import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import userEvent from '@testing-library/user-event'; -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; describe('menu toggle', () => { test('renders successfully', () => { @@ -61,21 +61,23 @@ describe('menu toggle', () => { const mockClick = jest.fn(); const user = userEvent.setup(); - render( - 10 selected - - ] - }} - aria-label="Menu toggle with checkbox split button and text" - />); + render( + + 10 selected + + ] + }} + aria-label="Menu toggle with checkbox split button and text" + /> + ); await user.click(screen.getByRole(`button`) as Element); expect(mockClick).toHaveBeenCalled(); diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatus.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatus.test.tsx index f3c18f5e1ad..1c7db785c4b 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatus.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatus.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { MultipleFileUploadStatus } from '../MultipleFileUploadStatus'; import InProgressIcon from '@patternfly/react-icons/dist/esm/icons/in-progress-icon'; diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx index 7f59631f14c..e0e03319fb4 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx @@ -48,7 +48,7 @@ describe('MultipleFileUploadStatusItem', () => { fileName="testCustomFileName.txt" fileSize={42} progressId="test-progress-id" - progressAriaLiveMessage={loadPercentage => `test message ${loadPercentage}`} + progressAriaLiveMessage={(loadPercentage) => `test message ${loadPercentage}`} /> ); diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitle.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitle.test.tsx index dce9b52bb21..c75908c453f 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitle.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitle.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { MultipleFileUploadTitle } from '../MultipleFileUploadTitle'; describe('MultipleFileUploadTitle', () => { diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleIcon.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleIcon.test.tsx index 192dfd8e49b..6a8c81d7a52 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleIcon.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleIcon.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { MultipleFileUploadTitleIcon } from '../MultipleFileUploadTitleIcon'; describe('MultipleFileUploadTitleIcon', () => { diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleText.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleText.test.tsx index ec683fc5199..5fb79577157 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleText.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleText.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { MultipleFileUploadTitleText } from '../MultipleFileUploadTitleText'; describe('MultipleFileUploadTitleText', () => { diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleTextSeparator.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleTextSeparator.test.tsx index b9db99b59be..c2f8fd39cf2 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleTextSeparator.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleTextSeparator.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { MultipleFileUploadTitleTextSeparator } from '../MultipleFileUploadTitleTextSeparator'; describe('MultipleFileUploadTitleTextSeparator', () => { diff --git a/packages/react-core/src/components/Nav/__tests__/Nav.test.tsx b/packages/react-core/src/components/Nav/__tests__/Nav.test.tsx index 7af2ea1ab5e..cfe972719eb 100644 --- a/packages/react-core/src/components/Nav/__tests__/Nav.test.tsx +++ b/packages/react-core/src/components/Nav/__tests__/Nav.test.tsx @@ -30,7 +30,7 @@ describe('Nav', () => { const { asFragment } = renderNav(
                      • ); diff --git a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx index 9db5ee24483..64e6514124d 100644 --- a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx +++ b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerGroup.test.tsx @@ -12,7 +12,9 @@ describe('NotificationDrawerGroup', () => { }); test('renders correct heading level', () => { - const { asFragment } = render(); + const { asFragment } = render( + + ); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx index 88685ae0149..2f184432325 100644 --- a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx +++ b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx @@ -21,8 +21,19 @@ describe('NotificationDrawerListItem', () => { expect(screen.getByRole('listitem')).toHaveClass('pf-m-hoverable'); }); - test('drawer list item with isRead applied', () => { + test('drawer list item with isRead applied and screen reader text is set to read', () => { render(); expect(screen.getByRole('listitem')).toHaveClass('pf-m-read'); + expect(screen.getByRole('listitem')).toContainHTML('read'); + }); + + test('drawer list item has screen reader text set to unread by default', () => { + render(); + expect(screen.getByRole('listitem')).toContainHTML('unread'); + }); + + test('drawer list item screen reader textcan be customized', () => { + render(); + expect(screen.getByRole('listitem')).toContainHTML('was read'); }); }); diff --git a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx index 40060a4f504..c164a3ee93e 100644 --- a/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx +++ b/packages/react-core/src/components/NotificationDrawer/__tests__/NotificationDrawerListItemHeader.test.tsx @@ -13,7 +13,7 @@ describe('NotificationDrawerListItemHeader', () => { }); test('renders with correct heading level', () => { - const { asFragment } = render(); + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap b/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap index 97afe7f43bb..a5fa337375c 100644 --- a/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap +++ b/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap @@ -15,6 +15,7 @@ exports[`NotificationDrawerHeader drawer header with count applied 1`] = ` Notifications 2 unread @@ -38,6 +39,7 @@ exports[`NotificationDrawerHeader drawer header with custom unread text applied Notifications 2 unread alerts diff --git a/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap b/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap index 42ca7cf796d..b2eb9ebf325 100644 --- a/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap +++ b/packages/react-core/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap @@ -5,6 +5,12 @@ exports[`NotificationDrawerListItem renders with PatternFly Core styles 1`] = `
                      • + > + + unread + +
                      • `; diff --git a/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx b/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx index 84006073ef0..7506929d2d0 100644 --- a/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx +++ b/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx @@ -212,13 +212,13 @@ describe('numberInput', () => { expect(input).toHaveDisplayValue(''); }); - test('does not throw an error if onChange is passed via inputProps as well as the onChange prop', () => { + test('does not throw an error if onChange is passed via inputProps as well as the onChange prop', async () => { const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const NumberInputWrapper = () => { const [value, setValue] = React.useState(0); - const onChange = event => setValue(event.currentTarget.value); - const inputProps = { onChange: onChange }; + const onChange = (event) => setValue(event.currentTarget.value); + const inputProps = { onChange }; return ; }; @@ -226,20 +226,20 @@ describe('numberInput', () => { render(); const input = screen.getByRole('spinbutton'); - userEvent.type(input, '0'); + await userEvent.type(input, '0'); expect(consoleSpy).not.toHaveBeenCalled(); }); test('input is read only if onChange not passed ', () => { - render(); + render(); const input = screen.getByLabelText('readonly input'); expect(input).toHaveAttribute('readOnly'); }); test('input is not read only if onChange passed ', () => { const onChangeMock = jest.fn(); - render(); + render(); const input = screen.getByLabelText('not readonly input'); expect(input).not.toHaveAttribute('readOnly'); }); diff --git a/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx b/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx index ad6cdc3100e..111618eb136 100644 --- a/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx +++ b/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx @@ -340,10 +340,12 @@ describe('Pagination', () => { 'insetLg', 'insetXl', 'inset2xl' - ]).forEach(inset => { + ]).forEach((inset) => { test(`verify ${inset} inset breakpoints`, () => { const { asFragment } = render( - test + + test + ); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx index d44f130352d..7298b129a51 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx @@ -27,8 +27,8 @@ export const PaginationSticky: React.FunctionComponent = () => { const buildCards = () => { const numberOfCards = (page - 1) * perPage + perPage - 1 >= itemCount ? itemCount - (page - 1) * perPage : perPage; - return Array.apply(0, Array(numberOfCards)).map((x, i) => ( - + return Array.from({ length: numberOfCards }).map((_value, index) => ( + This is a card diff --git a/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx b/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx index e117286864f..e3b535658cd 100644 --- a/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx +++ b/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx @@ -85,9 +85,9 @@ test('Renders with ref', async () => { render(); await user.click(document.body); - expect(screen.getByText('Last click was in panel: false')).toBeVisible; + expect(screen.getByText('Last click was in panel: false')).toBeVisible(); await user.click(screen.getByText('Main content')); - expect(screen.getByText('Last click was in panel: true')).toBeVisible; + expect(screen.getByText('Last click was in panel: true')).toBeVisible(); }); test('Renders with the inherited element props spread to the component', () => { diff --git a/packages/react-core/src/components/Popover/__tests__/Popover.test.tsx b/packages/react-core/src/components/Popover/__tests__/Popover.test.tsx index fff0765e7b8..e24cf0f7404 100644 --- a/packages/react-core/src/components/Popover/__tests__/Popover.test.tsx +++ b/packages/react-core/src/components/Popover/__tests__/Popover.test.tsx @@ -70,7 +70,7 @@ test('popover can close from content (uncontrolled)', () => { aria-label="Popover with button in the body that can close it" isVisible headerContent={
                        Popover header
                        } - bodyContent={hide => ( + bodyContent={(hide) => (
                        All the content props (headerContent, bodyContent, footerContent) can take a function which the Popover diff --git a/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx b/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx index 1d666155b1a..24194cb6e7b 100644 --- a/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx +++ b/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx @@ -49,7 +49,7 @@ test('value scaled between minValue and maxValue', () => { }); describe('Progress size', () => { - Object.keys(ProgressSize).forEach(oneSize => { + Object.keys(ProgressSize).forEach((oneSize) => { test(oneSize, () => { const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); @@ -58,7 +58,7 @@ describe('Progress size', () => { }); describe('Progress variant', () => { - Object.keys(ProgressVariant).forEach(oneVariant => { + Object.keys(ProgressVariant).forEach((oneVariant) => { test(oneVariant, () => { const { asFragment } = render( @@ -69,7 +69,7 @@ describe('Progress variant', () => { }); describe('Progress measure location', () => { - Object.keys(ProgressMeasureLocation).forEach(oneLocation => { + Object.keys(ProgressMeasureLocation).forEach((oneLocation) => { test(oneLocation, () => { const { asFragment } = render( @@ -99,10 +99,10 @@ test('progress component generates console warning when no accessible name is pr }); test('Does not render helper text by default', () => { - render(); + render(); expect(screen.queryByText('Test helper text')).not.toBeInTheDocument(); -}) +}); test('Renders passed helper text', () => { render(); diff --git a/packages/react-core/src/components/ProgressStepper/__tests__/ProgressStep.test.tsx b/packages/react-core/src/components/ProgressStepper/__tests__/ProgressStep.test.tsx index a493d3d2d5a..1fb64297dee 100644 --- a/packages/react-core/src/components/ProgressStepper/__tests__/ProgressStep.test.tsx +++ b/packages/react-core/src/components/ProgressStepper/__tests__/ProgressStep.test.tsx @@ -150,7 +150,7 @@ test('Does not renders with aria-labelledBy by default on Component element', () test('Renders with an accessible name that matches children', () => { render( -
                        Popover content
                        } id="test-id" titleId="title-id"> +
                        Popover content
                        } id="test-id" titleId="title-id"> Test
                        ); diff --git a/packages/react-core/src/components/SearchInput/__tests__/SearchInput.test.tsx b/packages/react-core/src/components/SearchInput/__tests__/SearchInput.test.tsx index df074772b64..b60eb19d9a8 100644 --- a/packages/react-core/src/components/SearchInput/__tests__/SearchInput.test.tsx +++ b/packages/react-core/src/components/SearchInput/__tests__/SearchInput.test.tsx @@ -6,10 +6,12 @@ import userEvent from '@testing-library/user-event'; import { SearchInput } from '../SearchInput'; import { FormGroup } from '../../Form'; import { Button } from '../../Button'; -import { ExternalLinkSquareAltIcon } from '@patternfly/react-icons'; +import ExternalLinkSquareAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-square-alt-icon'; import badgeStyles from '@patternfly/react-styles/css/components/Badge/badge'; import textInputGroupStyles from '@patternfly/react-styles/css/components/TextInputGroup/text-input-group'; +jest.mock('../../../helpers/OUIA/ouia'); + const props = { onChange: jest.fn(), value: 'test input', @@ -80,9 +82,9 @@ describe('SearchInput', () => { }); test('hide clear button', () => { - const { onClear, ...testProps } = props; - - render(); + render( + + ); expect(screen.queryByRole('button', { name: 'Reset' })).not.toBeInTheDocument(); }); @@ -146,9 +148,7 @@ describe('SearchInput', () => { test('advanced search with custom attributes and appendTo="inline', async () => { const user = userEvent.setup(); - const { container } = render( - - ); + render(); await user.click(screen.getByRole('button', { name: 'Open advanced search' })); @@ -158,7 +158,7 @@ describe('SearchInput', () => { test('advanced search with custom attributes and appendTo external DOM element', async () => { const user = userEvent.setup(); - const { container } = render( + render( ); @@ -252,9 +252,6 @@ test('toggleAriaLabel is applied to the expandable toggle', () => { }); test('Utilities are rendered when areUtilitiesDisplayed is set', () => { - render( - - ); + render(); expect(screen.getByLabelText('test-util-display')).toBeVisible(); }); - diff --git a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap index 24719463b95..2a687388f8f 100644 --- a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap +++ b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap @@ -52,9 +52,6 @@ exports[`SearchInput advanced search 1`] = ` aria-disabled="false" aria-label="Reset" class="pf-v5-c-button pf-m-plain" - data-ouia-component-id="OUIA-Generated-Button-plain-17" - data-ouia-component-type="PF5/Button" - data-ouia-safe="true" type="button" > Link @@ -463,9 +433,6 @@ exports[`SearchInput advanced search with custom attributes 1`] = ` ) : ( @@ -197,7 +198,7 @@ const TreeViewListItemBase: React.FunctionComponent = ({
                      • @@ -230,6 +231,7 @@ const TreeViewListItemBase: React.FunctionComponent = ({ }} {...(hasCheckbox && { htmlFor: randomId })} {...((hasCheckbox || (isSelectable && children)) && { id: `label-${randomId}` })} + {...(Component === 'button' && { type: 'button' })} > {children && renderToggle(randomId)} diff --git a/packages/react-core/src/components/TreeView/__tests__/TreeView.test.tsx b/packages/react-core/src/components/TreeView/__tests__/TreeView.test.tsx index 9b893398742..cfdb202370f 100644 --- a/packages/react-core/src/components/TreeView/__tests__/TreeView.test.tsx +++ b/packages/react-core/src/components/TreeView/__tests__/TreeView.test.tsx @@ -1,243 +1,316 @@ import React from 'react'; -import { render, screen, fireEvent } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { TreeView } from '../TreeView'; -import { Button } from '@patternfly/react-core'; -import { FolderIcon, FolderOpenIcon } from '@patternfly/react-icons'; -import { TreeViewSearch } from '../TreeViewSearch'; - -const options = [ - { - name: 'ApplicationLauncher', - id: 'AppLaunch', - children: [ - { - name: 'Application 1', - id: 'App1', - children: [ - { name: 'Settings', id: 'App1Settings' }, - { name: 'Current', id: 'App1Current' } - ] - }, - { - name: 'Application 2', - id: 'App2', - children: [ - { name: 'Settings', id: 'App2Settings' }, - { - name: 'Loader', - id: 'App2Loader', - children: [ - { name: 'Loading App 1', id: 'LoadApp1' }, - { name: 'Loading App 2', id: 'LoadApp2' }, - { name: 'Loading App 3', id: 'LoadApp3' } - ] - } - ] - } - ], - defaultExpanded: true - }, - { - name: 'Cost Management', - id: 'Cost', - children: [ - { - name: 'Application 3', - id: 'App3', - children: [ - { name: 'Settings', id: 'App3Settings' }, - { name: 'Current', id: 'App3Current' } - ] - } - ] - }, - { - name: 'Sources', - id: 'Sources', - children: [{ name: 'Application 4', id: 'App4', children: [{ name: 'Settings', id: 'App4Settings' }] }] - }, - { - name: 'Really really really long folder name that overflows the container it is in', - id: 'Long', - children: [{ name: 'Application 5', id: 'App5' }] - } -]; - -const flagOptions = [ - { - name: 'ApplicationLauncher', - id: 'AppLaunch', - hasCheckbox: true, - icon: , - expandedIcon: , - children: [ - { - name: 'Application 1', - id: 'App1', - children: [ - { name: 'Settings', id: 'App1Settings' }, - { name: 'Current', id: 'App1Current' } - ] - }, - { - name: 'Application 2', - id: 'App2', - hasBadge: true, - children: [ - { name: 'Settings', id: 'App2Settings', hasCheckbox: true }, - { - name: 'Loader', - id: 'App2Loader', - children: [ - { name: 'Loading App 1', id: 'LoadApp1' }, - { name: 'Loading App 2', id: 'LoadApp2' }, - { name: 'Loading App 3', id: 'LoadApp3' } - ] - } - ] - } - ], - defaultExpanded: true - }, - { - name: 'Cost Management', - id: 'Cost', - hasBadge: true, - action: ( - - ), - children: [ - { - name: 'Application 3', - id: 'App3', - children: [ - { name: 'Settings', id: 'App3Settings' }, - { name: 'Current', id: 'App3Current' } - ] - } - ] - }, - { - name: 'Sources', - id: 'Sources', - children: [{ name: 'Application 4', id: 'App4', children: [{ name: 'Settings', id: 'App4Settings' }] }] - }, - { - name: 'Really really really long folder name that overflows the container it is in', - id: 'Long', - children: [{ name: 'Application 5', id: 'App5' }] - } -]; - -const active = [ - { - name: 'Application 1', - id: 'App1', - children: [ - { name: 'Settings', id: 'App1Settings' }, - { name: 'Current', id: 'App1Current' } - ] - } -]; - -describe('tree view', () => { - test('renders basic successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); - test('calls onExpand and onCollapse appropriately', () => { - const onExpand = jest.fn(); - const onCollapse = jest.fn(); - const { asFragment } = render( - - ); - expect(onExpand).not.toHaveBeenCalled(); - expect(onCollapse).not.toHaveBeenCalled(); - expect(screen.queryByText('Application 3')).toBeNull(); - expect(screen.getByText('Cost Management')).toBeInTheDocument(); - fireEvent( - screen.getByText('Cost Management'), - new MouseEvent('click', { - bubbles: true, - cancelable: true - }) - ); - expect(onExpand).toHaveBeenCalled(); - expect(onCollapse).not.toHaveBeenCalled(); - expect(screen.getByText('Application 3')).toBeInTheDocument(); - fireEvent( - screen.getByText('Cost Management'), - new MouseEvent('click', { - bubbles: true, - cancelable: true - }) - ); - expect(onCollapse).toHaveBeenCalled(); - expect(screen.queryByText('Application 3')).toBeNull(); - }); +jest.mock('../TreeViewList', () => ({ + TreeViewList: ({ children, isNested, toolbar }) => ( +
                        +

                        {`TreeViewList isNested: ${isNested}`}

                        +

                        {`TreeViewList toolbar: ${toolbar}`}

                        +
                        {children}
                        +
                        + ) +})); +jest.mock('../TreeViewListItem', () => ({ + TreeViewListItem: ({ + action, + activeItems, + badgeProps, + checkProps, + children, + compareItems, + customBadgeContent, + defaultExpanded, + expandedIcon, + hasBadge, + hasCheckbox, + icon, + id, + isCompact, + isExpanded, + isSelectable, + itemData, + name, + onCheck, + onSelect, + onExpand, + onCollapse, + parentItem, + title, + useMemo + }) => ( +
                        +

                        {`TreeViewListItem action: ${action}`}

                        +
                        {activeItems && activeItems[0].name}
                        +

                        {`TreeViewListItem badgeProps: ${badgeProps?.id}`}

                        +

                        {`TreeViewListItem checkProps: ${checkProps?.checked}`}

                        +

                        {`TreeViewListItem customBadgeContent: ${customBadgeContent}`}

                        +

                        {`TreeViewListItem defaultExpanded: ${defaultExpanded}`}

                        +

                        {`TreeViewListItem expandedIcon: ${expandedIcon}`}

                        +

                        {`TreeViewListItem hasBadge: ${hasBadge}`}

                        +

                        {`TreeViewListItem hasCheckbox: ${hasCheckbox}`}

                        +

                        {`TreeViewListItem icon: ${icon}`}

                        +

                        {`TreeViewListItem id: ${id}`}

                        +

                        {`TreeViewListItem isCompact: ${isCompact}`}

                        +

                        {`TreeViewListItem isExpanded: ${isExpanded}`}

                        +

                        {`TreeViewListItem isSelectable: ${isSelectable}`}

                        +

                        {`TreeViewListItem itemData: ${itemData.name}`}

                        +

                        {`TreeViewListItem name: ${name}`}

                        +

                        {`TreeViewListItem parentItem: ${parentItem?.name}`}

                        +

                        {`TreeViewListItem title: ${title}`}

                        +

                        {`TreeViewListItem useMemo: ${useMemo}`}

                        + + + + + +
                        {children}
                        +
                        + ) +})); +jest.mock('../TreeViewRoot', () => ({ + TreeViewRoot: ({ children, hasCheckboxes, hasGuides, hasSelectableNodes, variant, className }) => ( +
                        +

                        {`TreeViewRoot hasCheckboxes: ${hasCheckboxes}`}

                        +

                        {`TreeViewRoot hasGuides: ${hasGuides}`}

                        +

                        {`TreeViewRoot hasSelectableNodes: ${hasSelectableNodes}`}

                        +

                        {`TreeViewRoot variant: ${variant}`}

                        +

                        {`TreeViewRoot className: ${className}`}

                        +
                        {children}
                        +
                        + ) +})); - test('renders active successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); +const basicData = { + name: 'Basic data name' +}; - test('renders search successfully', () => { - const { asFragment } = render( - - ); - expect(asFragment()).toMatchSnapshot(); - }); +test('Passes hasSelectableNodes to TreeViewRoot', () => { + render(); + + expect(screen.getByText('TreeViewRoot hasSelectableNodes: true')).toBeVisible(); +}); +test('Passes hasCheckboxes to TreeViewRoot', () => { + render(); + + expect(screen.getByText('TreeViewRoot hasCheckboxes: true')).toBeVisible(); +}); +test('Passes hasGuides to TreeViewRoot', () => { + render(); + + expect(screen.getByText('TreeViewRoot hasGuides: true')).toBeVisible(); +}); +test('Passes variant to TreeViewRoot', () => { + render(); + + expect(screen.getByText('TreeViewRoot variant: compact')).toBeVisible(); +}); +test('Passes className to TreeViewRoot', () => { + render(); + + expect(screen.getByText('TreeViewRoot className: test-class')).toBeVisible(); +}); +test('Passes data as children TreeViewRoot', () => { + render(); + + expect(screen.getByTestId('TreeViewRoot-children')).toContainHTML('TreeViewListItem name: Basic data name'); +}); +test('Does not render TreeViewRoot when parentItem is passed', () => { + render(); + + expect(screen.queryByTestId('TreeViewRoot-mock')).not.toBeInTheDocument(); +}); + +test('Passes isNested to TreeViewList', () => { + render(); + + expect(screen.getByText('TreeViewList isNested: true')).toBeVisible(); +}); +test('Passes toolbar to TreeViewList', () => { + render(); + + expect(screen.getByText('TreeViewList toolbar: Toolbar content')).toBeVisible(); +}); +test('Passes data as children TreeViewList', () => { + render(); - test('renders toolbar successfully', () => { - const { asFragment } = render( - test
                      • } /> - ); - expect(asFragment()).toMatchSnapshot(); + expect(screen.getByTestId('TreeViewList-children')).toContainHTML('TreeViewListItem name: Basic data name'); +}); + +test('Passes data action to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem action: Item action')).toBeVisible(); +}); +test('Passes activeItems to TreeViewListItem', () => { + render(); + + expect(screen.getByTestId('TreeViewListItem-activeItems')).toHaveTextContent('Active item name'); +}); +test('Passes data badgeProps to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem badgeProps: test-id')).toBeVisible(); +}); +test('Passes data checkProps to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem checkProps: true')).toBeVisible(); +}); +test('Passes data customBadgeContent to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem customBadgeContent: Custom badge')).toBeVisible(); +}); +test('Passes data defaultExpanded to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem defaultExpanded: true')).toBeVisible(); +}); +test('Passes defaultAllExpanded to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem defaultExpanded: true')).toBeVisible(); +}); +test('Passes data expandedIcon to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem expandedIcon: Expanded icon')).toBeVisible(); +}); +test('Passes expandedIcon to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem expandedIcon: Expanded icon')).toBeVisible(); +}); +test('Passes data hasBadge to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem hasBadge: true')).toBeVisible(); +}); +test('Passes hasBadges to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem hasBadge: true')).toBeVisible(); +}); +test('Passes data hasCheckbox to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem hasCheckbox: true')).toBeVisible(); +}); +test('Passes hasCheckboxes to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem hasCheckbox: true')).toBeVisible(); +}); +test('Passes data icon to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem icon: Icon content')).toBeVisible(); +}); +test('Passes icon to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem icon: Icon content')).toBeVisible(); +}); +test('Passes data id to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem id: test-id')).toBeVisible(); +}); + +['default', 'compact', 'compactNoBackground'].forEach((variant) => { + test(`Passes isCompact to TreeViewListItem when variant=${variant}`, () => { + render(); + + expect(screen.getByText(`TreeViewListItem isCompact: ${variant === 'default' ? 'false' : 'true'}`)).toBeVisible(); }); +}); + +test('Passes allExpanded to TreeViewListItem isExpanded prop', () => { + render(); + + expect(screen.getByText('TreeViewListItem isExpanded: true')).toBeVisible(); +}); +test('Passes hasSelectableNodes to TreeViewListItem isSelectable prop', () => { + render(); + + expect(screen.getByText('TreeViewListItem isSelectable: true')).toBeVisible(); +}); +test('Passes data to TreeViewListItem itemData prop', () => { + render(); + + expect(screen.getByText('TreeViewListItem itemData: itemData name')).toBeVisible(); +}); +test('Passes data.name to TreeViewListItem name prop', () => { + render(); - test('renders checkboxes successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); + expect(screen.getByText('TreeViewListItem name: Basic data name')).toBeVisible(); +}); +test('Passes parentItem to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem parentItem: Parent name')).toBeVisible(); +}); +test('Passes data.title to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem title: Basic data title')).toBeVisible(); +}); +test('Passes useMemo to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem useMemo: true')).toBeVisible(); +}); +test('Passes data.children to TreeViewListItem', () => { + render(); + + expect(screen.getByText('TreeViewListItem name: Child 1')).toBeVisible(); +}); + +describe('Passes callback props to TreeViewListItem', () => { + const user = userEvent.setup(); + const callbackMock = jest.fn(); + + test('Passes compareItems', async () => { + render(); + + await user.click(screen.getByRole('button', { name: 'compareItems clicker' })); + + expect(callbackMock).toHaveBeenCalledTimes(1); }); + test('Passes onCheck', async () => { + render(); + + await user.click(screen.getByRole('button', { name: 'onCheck clicker' })); - test('renders icons successfully', () => { - const { asFragment } = render( - } - expandedIcon={} - /> - ); - expect(asFragment()).toMatchSnapshot(); + expect(callbackMock).toHaveBeenCalledTimes(1); }); + test('Passes onSelect', async () => { + render(); - test('renders badges successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); + await user.click(screen.getByRole('button', { name: 'onSelect clicker' })); + + expect(callbackMock).toHaveBeenCalledTimes(1); }); + test('Passes onExpand', async () => { + render(); + + await user.click(screen.getByRole('button', { name: 'onExpand clicker' })); - test('renders individual flag options successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); + expect(callbackMock).toHaveBeenCalledTimes(1); }); -}); + test('Passes onCollapse', async () => { + render(); -test('renders guides successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); -}); + await user.click(screen.getByRole('button', { name: 'onCollapse clicker' })); -test('renders compact successfully', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); + expect(callbackMock).toHaveBeenCalledTimes(1); + }); }); -test('renders compact no background successfully', () => { - const { asFragment } = render(); +test('Matches snapshot', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/TreeView/__tests__/TreeViewList.test.tsx b/packages/react-core/src/components/TreeView/__tests__/TreeViewList.test.tsx new file mode 100644 index 00000000000..496d8cc6b08 --- /dev/null +++ b/packages/react-core/src/components/TreeView/__tests__/TreeViewList.test.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TreeViewList } from '../TreeViewList'; +import styles from '@patternfly/react-styles/css/components/TreeView/tree-view'; + +test(`Renders with class ${styles.treeView}__list by default`, () => { + render(Content); + + expect(screen.getByRole('tree')).toHaveClass(`${styles.treeView}__list`, { exact: true }); +}); + +test(`Renders with role="tree" by default`, () => { + render(Content); + + expect(screen.getByRole('tree')).toHaveTextContent('Content'); +}); + +test(`Renders with role="group" when isNested is true`, () => { + render(Content); + + expect(screen.getByRole('group')).toHaveTextContent('Content'); +}); + +test(`Spreads additional props`, () => { + render(Content); + + expect(screen.getByRole('tree')).toHaveAttribute('id', 'test-id'); +}); + +test(`Renders toolbar content when toolbar prop is passed`, () => { + render(Content); + + expect(screen.getByText('Toolbar content')).toBeInTheDocument(); +}); + +test(`Does not render toolbar content when toolbar prop is not passed`, () => { + render(Content); + + expect(screen.queryByRole('separator')).not.toBeInTheDocument(); +}); + +test('Matches snapshot by default', () => { + const { asFragment } = render(Content); + + expect(asFragment()).toMatchSnapshot(); +}); + +test('Matches snapshot when toolbar is passed', () => { + const { asFragment } = render(Toolbar content
                        }>Content); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/TreeView/__tests__/TreeViewListItem.test.tsx b/packages/react-core/src/components/TreeView/__tests__/TreeViewListItem.test.tsx new file mode 100644 index 00000000000..2451c90c041 --- /dev/null +++ b/packages/react-core/src/components/TreeView/__tests__/TreeViewListItem.test.tsx @@ -0,0 +1,708 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TreeViewListItem } from '../TreeViewListItem'; +import { TreeView } from '../TreeView'; +import userEvent from '@testing-library/user-event'; +import styles from '@patternfly/react-styles/css/components/TreeView/tree-view'; + +const requiredProps = { + name: 'Item name', + title: 'Item title' +}; + +test(`Renders without children`, () => { + render( +
                        + +
                        + ); + + expect(screen.getByTestId('container').firstChild).toBeVisible(); +}); + +test(`Does not render children by default`, () => { + render(Content); + + expect(screen.queryByText('Content')).not.toBeInTheDocument(); +}); + +test(`Renders children if defaultExpanded is true`, () => { + render( + + Content + + ); + + expect(screen.getByText('Content')).toBeVisible(); +}); + +test(`Renders children if isExpanded is true`, () => { + render( + + Content + + ); + + expect(screen.getByText('Content')).toBeVisible(); +}); + +test(`Renders children when toggle is clicked`, async () => { + const user = userEvent.setup(); + render(Content); + + await user.click(screen.getByRole('button')); + + expect(screen.getByText('Content')).toBeVisible(); +}); + +test(`Renders with class ${styles.treeViewListItem} and aria-expanded=false by default`, () => { + render(); + + expect(screen.getByRole('treeitem')).toHaveClass(styles.treeViewListItem, { exact: true }); + expect(screen.getByRole('treeitem')).toHaveAttribute('aria-expanded', 'false'); +}); + +test(`Renders with class ${styles.modifiers.expanded} and aria-expanded=true when defaultExpanded is true`, () => { + render(); + + expect(screen.getByRole('treeitem')).toHaveClass(styles.modifiers.expanded); + expect(screen.getByRole('treeitem')).toHaveAttribute('aria-expanded', 'true'); +}); + +test(`Renders with class ${styles.modifiers.expanded} and aria-expanded=true when isExpanded is true`, () => { + render(); + + expect(screen.getByRole('treeitem')).toHaveClass(styles.modifiers.expanded); + expect(screen.getByRole('treeitem')).toHaveAttribute('aria-expanded', 'true'); +}); + +test('Renders with id when passed', () => { + render(); + + expect(screen.getByRole('treeitem')).toHaveAttribute('id', 'test-id'); +}); + +test('Does not render expandable toggle if children are not passed', () => { + render(); + + expect(screen.queryByText(requiredProps.name)?.previousSibling).not.toBeInTheDocument(); +}); + +test(`Renders expandable toggle with class ${styles.treeViewNodeToggle} if children are passed`, () => { + render(Content); + + expect(screen.getByText(requiredProps.name).previousElementSibling).toHaveClass(styles.treeViewNodeToggle); +}); + +test(`Renders expandable toggle without aria-labelledby as span by default`, () => { + render(Content); + const toggle = screen.getByText(requiredProps.name).previousElementSibling; + + expect(toggle?.tagName).toBe('SPAN'); + expect(toggle).not.toHaveAccessibleName(); +}); + +test(`Renders expandable toggle as button with aria-labelledby when hasCheckbox is passed`, () => { + render( + + Content + + ); + const toggle = screen.getByRole('button'); + + expect(toggle).toHaveClass(styles.treeViewNodeToggle); + expect(toggle).toHaveAccessibleName(requiredProps.name); +}); + +test(`Renders expandable toggle as button with aria-labelledby when isSelectable is passed`, () => { + render( + + Content + + ); + const toggle = screen.getByText(requiredProps.name).previousElementSibling; + + expect(toggle?.tagName).toBe('BUTTON'); + expect(toggle).toHaveAccessibleName(requiredProps.name); +}); + +test(`Renders name prop with class ${styles.treeViewNodeText}`, () => { + render(); + + expect(screen.getByText(requiredProps.name)).toHaveClass(styles.treeViewNodeText); +}); + +test(`Renders name prop in span by default`, () => { + render(); + + expect(screen.getByText(requiredProps.name).tagName).toBe('SPAN'); +}); + +test(`Renders name prop in button when isSelectable is passed`, () => { + render(); + + expect(screen.getByText(requiredProps.name).tagName).toBe('BUTTON'); +}); + +test('Does not render title prop by default', () => { + render(); + + expect(screen.queryByText(requiredProps.title)).not.toBeInTheDocument(); +}); + +test(`Renders title prop with class ${styles.treeViewNodeTitle} when isCompact is passed`, () => { + render(); + + expect(screen.getByText(requiredProps.title)).toHaveClass(styles.treeViewNodeTitle); +}); + +test(`Does not render name in ${styles.treeViewNodeContent} wrapper by default`, () => { + render(); + + expect(screen.getByText(requiredProps.name).parentElement).not.toHaveClass(styles.treeViewNodeContent); +}); + +test(`Renders name and title in ${styles.treeViewNodeContent} wrapper when isCompact is passed`, () => { + render(); + + expect(screen.getByText(requiredProps.name).parentElement).toHaveClass(styles.treeViewNodeContent); + expect(screen.getByText(requiredProps.title).parentElement).toHaveClass(styles.treeViewNodeContent); +}); + +test('Does not render checkbox by default', () => { + render(); + + expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); +}); + +test('Renders checkbox when hasCheckbox is passed', () => { + render(); + + expect(screen.getByRole('checkbox')).toBeInTheDocument(); +}); + +test('Passes checkProps to checkbox', () => { + render(); + + // Want to check that checkProps.checked as well as additional spread props are passed + expect(screen.getByRole('checkbox')).toBeChecked(); + expect(screen.getByRole('checkbox')).toHaveClass('test-class'); +}); + +test('Does not render icon by default', () => { + render(Content); + + // + expect(screen.getByText(requiredProps.name).previousElementSibling).not.toHaveClass(styles.treeViewNodeIcon); +}); + +test(`Renders icon with class ${styles.treeViewNodeIcon} when prop is passed`, () => { + render( + + Content + + ); + + expect(screen.getByText('Icon content')).toHaveClass(styles.treeViewNodeIcon); + // Check that previous test isn't a false positive + expect(screen.getByText(requiredProps.name).previousElementSibling).toHaveClass(styles.treeViewNodeIcon); +}); + +test('Does not render expandedIcon if list item is not expanded', () => { + render( + + Content + + ); + + expect(screen.queryByText('Expanded icon content')).not.toBeInTheDocument(); +}); + +test('Renders expandedIcon instead of icon if list item is expanded', () => { + render( + + Content + + ); + + expect(screen.getByText('Expanded icon content')).toBeInTheDocument(); + expect(screen.queryByText('Icon content')).not.toBeInTheDocument(); +}); + +test('Does not render badge by default', () => { + render(); + + expect(screen.queryByText(requiredProps.name)?.nextElementSibling).not.toBeInTheDocument(); +}); + +test('Does not render badge if hasBadge is passed but children and customBadgeContent are not passed', () => { + render(); + + expect(screen.queryByText(requiredProps.name)?.nextElementSibling).not.toBeInTheDocument(); +}); + +test('Renders badge with count by default when hasBadge and children are passed', () => { + render( + + + + ); + + expect(screen.getByText(requiredProps.name).nextElementSibling).toHaveTextContent('2'); +}); + +test('Renders badge with customBadgeContent when hasBadge and children are passed', () => { + render( + + + + ); + + expect(screen.getByText(requiredProps.name).nextElementSibling).toHaveTextContent('Custom badge'); +}); + +test('Renders badge with customBadgeContent when hasBadge is passed and children are not passed', () => { + render(); + + expect(screen.getByText(requiredProps.name).nextElementSibling).toHaveTextContent('Custom badge'); +}); + +test(`Renders badge with class ${styles.treeViewNodeCount} when hasBadge and children passed`, () => { + render( + + + + ); + + expect(screen.getByText('2').parentElement).toHaveClass(styles.treeViewNodeCount); +}); + +test(`Renders badge with class ${styles.treeViewNodeCount} when hasBadge is passed and children are not passed`, () => { + render(); + + expect(screen.getByText('Custom badge').parentElement).toHaveClass(styles.treeViewNodeCount); +}); + +test('Passes badgeProps when hasBadge and children are passed', () => { + render( + + + + ); + + expect(screen.getByText('2')).toHaveClass('test-class'); +}); + +test('Passes badgeProps when hasBadge and customBadgeContent are passed', () => { + render( + + ); + + expect(screen.getByText('Badge content')).toHaveClass('test-class'); +}); + +test(`Renders ${styles.treeViewNode} element as button by default`, () => { + render(); + + expect(screen.getByRole('button')).toHaveClass(styles.treeViewNode); +}); + +test(`Renders ${styles.treeViewNode} element as label when hasCheckbox is passed`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode?.tagName).toBe('LABEL'); +}); + +test(`Renders ${styles.treeViewNode} element as div when isSelectable is passed`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode?.tagName).toBe('DIV'); +}); + +test(`Does not render ${styles.treeViewNode} element with for or id attributes by default`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).not.toHaveAttribute('for'); + expect(treeViewNode).not.toHaveAttribute('id'); +}); + +test(`Renders ${styles.treeViewNode} element with for and id attributes when hasCheckbox is passed`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveAttribute('for'); + expect(treeViewNode).toHaveAttribute('id'); +}); + +test(`Renders ${styles.treeViewNode} element with id attribute when isSelectable and children are passed`, () => { + render( + + Content + + ); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveAttribute('id'); +}); + +test(`Does not render ${styles.treeViewNode} element with additional classes by default`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveClass(styles.treeViewNode, { exact: true }); +}); + +test(`Renders ${styles.treeViewNode} element with ${styles.modifiers.selectable} class when hasCheckbox and children are passed`, () => { + render( + + Content + + ); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveClass(styles.modifiers.selectable); +}); + +test(`Renders ${styles.treeViewNode} element with ${styles.modifiers.selectable} class when isSelectable and children are passed`, () => { + render( + + Content + + ); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveClass(styles.modifiers.selectable); +}); + +test(`Does not render ${styles.treeViewNode} element with ${styles.modifiers.selectable} if children are not passed`, () => { + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).not.toHaveClass(styles.modifiers.selectable); +}); + +test(`Renders ${styles.treeViewNode} element with ${styles.modifiers.current} class when isSelectable and activeItems are passed`, () => { + render( + true} isSelectable activeItems={[{ name: 'Active item' }]} {...requiredProps}> + Content + + ); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveClass(styles.modifiers.current); +}); + +test(`Renders ${styles.treeViewNode} element with ${styles.modifiers.current} class when children are not passed`, () => { + render( true} activeItems={[{ name: 'Active item' }]} {...requiredProps} />); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).toHaveClass(styles.modifiers.current); +}); + +test(`Does not render ${styles.treeViewNode} element with ${styles.modifiers.current} class when children are passed`, () => { + render( + true} activeItems={[{ name: 'Active item' }]} {...requiredProps}> + Content + + ); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + + expect(treeViewNode).not.toHaveClass(styles.modifiers.current); +}); + +describe('compareItems callback', () => { + const compareItemsMock = jest.fn(); + const activeItems = [{ name: 'Active item' }]; + const itemData = { name: 'Item data' }; + + test('Not called by default', () => { + render(Content); + + expect(compareItemsMock).not.toHaveBeenCalled(); + }); + + test('Called when isSelectable and activeItems are passed', () => { + render( + + Content + + ); + + expect(compareItemsMock).toHaveBeenCalledTimes(1); + expect(compareItemsMock).toHaveBeenCalledWith( + expect.objectContaining(activeItems[0]), + expect.objectContaining(itemData) + ); + }); + + test('Not called when isSelectable is passed but activeItems is not passed', () => { + render( + + Content + + ); + + expect(compareItemsMock).not.toHaveBeenCalled(); + }); + + test('Called when children and activeItems are passed', () => { + render( + + ); + + expect(compareItemsMock).toHaveBeenCalledTimes(1); + expect(compareItemsMock).toHaveBeenCalledWith( + expect.objectContaining(activeItems[0]), + expect.objectContaining(itemData) + ); + }); +}); + +test('Does not call onCheck by default', async () => { + const user = userEvent.setup(); + const onCheckMock = jest.fn(); + + render(); + + await user.click(screen.getByRole('checkbox')); + + expect(onCheckMock).not.toHaveBeenCalled(); +}); + +test('Calls onCheck callback when checkbox is clicked', async () => { + const user = userEvent.setup(); + const onCheckMock = jest.fn(); + + render(); + + await user.click(screen.getByRole('checkbox')); + + expect(onCheckMock).toHaveBeenCalledTimes(1); + expect(onCheckMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test('Does not call onSelect by default', async () => { + const user = userEvent.setup(); + const onSelectMock = jest.fn(); + + render(); + + await user.click(screen.getByRole('button')); + + expect(onSelectMock).not.toHaveBeenCalled(); +}); + +test(`Calls onSelect when ${styles.treeViewNode} is clicked`, async () => { + const user = userEvent.setup(); + const onSelectMock = jest.fn(); + + render(); + + await user.click(screen.getByRole('button')); + + expect(onSelectMock).toHaveBeenCalledTimes(1); + expect(onSelectMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test('Does not call onSelect when hasCheckbox is passed', async () => { + const user = userEvent.setup(); + const onSelectMock = jest.fn(); + + render(); + + const treeViewNode = screen.getByRole('treeitem').querySelector(`.${styles.treeViewNode}`); + await user.click(treeViewNode as Element); + + expect(onSelectMock).not.toHaveBeenCalled(); +}); + +test('Does not call onExpand by default', async () => { + const user = userEvent.setup(); + const onExpandMock = jest.fn(); + + render(Content); + + await user.click(screen.getByRole('button')); + + expect(onExpandMock).not.toHaveBeenCalled(); +}); + +test(`Calls onExpand when ${styles.treeViewNode} is collapsed and clicked`, async () => { + const user = userEvent.setup(); + const onExpandMock = jest.fn(); + + render( + + Content + + ); + + await user.click(screen.getByRole('button')); + + expect(onExpandMock).toHaveBeenCalledTimes(1); + expect(onExpandMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test(`Calls onExpand when ${styles.treeViewNodeToggle} is clicked and isSelectable is passed`, async () => { + const user = userEvent.setup(); + const onExpandMock = jest.fn(); + + render( + + Content + + ); + + const toggle = screen.getByText(requiredProps.name).previousElementSibling; + await user.click(toggle as Element); + + expect(onExpandMock).toHaveBeenCalledTimes(1); + expect(onExpandMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test(`Calls onExpand when ${styles.treeViewNodeToggle} is clicked and hasCheckbox is passed`, async () => { + const user = userEvent.setup(); + const onExpandMock = jest.fn(); + + render( + + Content + + ); + + const toggle = screen.getByText(requiredProps.name).previousElementSibling?.previousElementSibling; + await user.click(toggle as Element); + + expect(onExpandMock).toHaveBeenCalledTimes(1); + expect(onExpandMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test('Does not call onCollapse by default', async () => { + const user = userEvent.setup(); + const onCollapseMock = jest.fn(); + + render( + + Content + + ); + + await user.click(screen.getByRole('button')); + + expect(onCollapseMock).not.toHaveBeenCalled(); +}); + +test(`Calls onCollapse when ${styles.treeViewNode} is expanded and clicked`, async () => { + const user = userEvent.setup(); + const onCollapseMock = jest.fn(); + + render( + + Content + + ); + + await user.click(screen.getByRole('button')); + + expect(onCollapseMock).toHaveBeenCalledTimes(1); + expect(onCollapseMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test(`Calls onCollapse when ${styles.treeViewNodeToggle} is clicked and isSelectable is passed`, async () => { + const user = userEvent.setup(); + const onCollapseMock = jest.fn(); + + render( + + Content + + ); + + const toggle = screen.getByText(requiredProps.name).previousElementSibling; + await user.click(toggle as Element); + + expect(onCollapseMock).toHaveBeenCalledTimes(1); + expect(onCollapseMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test(`Calls onCollapse when ${styles.treeViewNodeToggle} is clicked and hasCheckbox is passed`, async () => { + const user = userEvent.setup(); + const onCollapseMock = jest.fn(); + + render( + + Content + + ); + + const toggle = screen.getByText(requiredProps.name).previousElementSibling?.previousElementSibling; + await user.click(toggle as Element); + + expect(onCollapseMock).toHaveBeenCalledTimes(1); + expect(onCollapseMock).toHaveBeenCalledWith(expect.any(Object), undefined, undefined); +}); + +test(`Does not render ${styles.treeViewAction} element by default`, () => { + render(); + + expect(screen.queryByRole('treeitem')?.querySelector(`.${styles.treeViewAction}`)).not.toBeInTheDocument(); +}); + +test(`Renders action with ${styles.treeViewAction} class when action is passed`, () => { + render(); + + expect(screen.getByText('Action content')).toHaveClass(styles.treeViewAction); +}); + +test('Matches snapshot without children', () => { + const { asFragment } = render(); + + expect(asFragment()).toMatchSnapshot(); +}); + +test('Matches snapshot with children', () => { + const { asFragment } = render(Content); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/TreeView/__tests__/TreeViewRoot.test.tsx b/packages/react-core/src/components/TreeView/__tests__/TreeViewRoot.test.tsx new file mode 100644 index 00000000000..097bf3d77fa --- /dev/null +++ b/packages/react-core/src/components/TreeView/__tests__/TreeViewRoot.test.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TreeViewRoot } from '../TreeViewRoot'; +import styles from '@patternfly/react-styles/css/components/TreeView/tree-view'; + +test('Renders children', () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content')).toBeVisible(); +}); + +test(`Renders with class ${styles.treeView} by default`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass(styles.treeView, { exact: true }); +}); + +test(`Renders with custom class when className is passed`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass('test-class'); +}); + +test(`Renders with class ${styles.modifiers.guides} when hasGuides is passed`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass(styles.modifiers.guides); +}); + +test(`Does not render with additional classes when variant="default"`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass(styles.treeView, { exact: true }); +}); + +test(`Renders with class ${styles.modifiers.compact} when variant="compact"`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass(styles.modifiers.compact); +}); + +test(`Renders with classes ${styles.modifiers.compact} and ${styles.modifiers.noBackground} when variant="compactNoBackground"`, () => { + render( + +
                        Content
                        +
                        + ); + + expect(screen.getByText('Content').parentElement).toHaveClass( + styles.modifiers.compact, + styles.modifiers.noBackground + ); +}); + +test('Matches snapshot', () => { + const { asFragment } = render( + +
                        Content
                        +
                        + ); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/TreeView/__tests__/TreeViewSearch.test.tsx b/packages/react-core/src/components/TreeView/__tests__/TreeViewSearch.test.tsx new file mode 100644 index 00000000000..049a4d49a4c --- /dev/null +++ b/packages/react-core/src/components/TreeView/__tests__/TreeViewSearch.test.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TreeViewSearch } from '../TreeViewSearch'; +import userEvent from '@testing-library/user-event'; +import styles from '@patternfly/react-styles/css/components/TreeView/tree-view'; + +test(`Renders with ${styles.treeViewSearch} by default`, () => { + render(); + + expect(screen.getByRole('searchbox').parentElement?.parentElement).toHaveClass(styles.treeViewSearch, { + exact: true + }); +}); + +test(`Renders with custom class when className is passed`, () => { + render(); + + expect(screen.getByRole('searchbox').parentElement?.parentElement).toHaveClass('test-class'); +}); + +test(`Renders with id when passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).toHaveAttribute('id', 'test-id'); +}); + +test(`Does not render with id when it is not passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).not.toHaveAttribute('id'); +}); + +test(`Renders with name when passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).toHaveAttribute('name', 'testName'); +}); + +test(`Does not render with name when it is not passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).not.toHaveAttribute('name'); +}); + +test(`Renders with aria-label when passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).toHaveAccessibleName('test label'); +}); + +test(`Does not render with aria-label when it is not passed`, () => { + render(); + + expect(screen.getByRole('searchbox')).not.toHaveAccessibleName(); +}); + +test(`Spreads additional props`, () => { + render(); + + expect(screen.getByRole('searchbox')).toHaveAttribute('data-testprop', 'test-value'); +}); + +test(`Calls onSearch when input is typed into`, async () => { + const user = userEvent.setup(); + const onSearchMock = jest.fn(); + render(); + + await user.type(screen.getByRole('searchbox'), 'a'); + + expect(onSearchMock).toHaveBeenCalledTimes(1); +}); + +test(`Does not call onSearch when input is not typed into`, async () => { + const user = userEvent.setup(); + const onSearchMock = jest.fn(); + + render( + <> + + + + ); + + await user.type(screen.getByRole('textbox'), 'a'); + + expect(onSearchMock).not.toHaveBeenCalled(); +}); + +test('Matches snapshot', () => { + const { asFragment } = render(); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap b/packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap index 3da0823e398..960322b8685 100644 --- a/packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap +++ b/packages/react-core/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap @@ -1,3366 +1,122 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders compact no background successfully 1`] = ` +exports[`Matches snapshot 1`] = `
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`renders compact successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`renders guides successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders active successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders badges successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders basic successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders checkboxes successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders icons successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders individual flag options successfully 1`] = ` - -
                        -
                          -
                        • -
                          - -
                          -
                            -
                          • -
                            - -
                            -
                          • -
                          • -
                            - -
                            -
                          • -
                          -
                        • -
                        • -
                          - -
                          - -
                          -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        • -
                          - -
                          -
                        • -
                        -
                        -
                        -`; - -exports[`tree view renders search successfully 1`] = ` - -