diff --git a/packages/react/src/components/TreeView/TreeView-test.js b/packages/react/src/components/TreeView/TreeView-test.js
index 1f246c1c4289..95e5574b5322 100644
--- a/packages/react/src/components/TreeView/TreeView-test.js
+++ b/packages/react/src/components/TreeView/TreeView-test.js
@@ -5,11 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
+import { fireEvent, render, screen, within } from '@testing-library/react';
+
import React from 'react';
-import TreeView from './TreeView';
import TreeNode from './TreeNode';
+import TreeView from './TreeView';
import userEvent from '@testing-library/user-event';
-import { fireEvent, render, screen, within } from '@testing-library/react';
const prefix = 'cds';
@@ -296,4 +297,247 @@ describe('TreeView', () => {
expect(parentNode).toHaveFocus();
});
});
+ it('should respect multiselect prop (deselecting nodes)', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+
+ );
+ const lists = screen.getAllByRole('treeitem');
+ await user.keyboard('[ControlLeft>]');
+ await user.click(lists[0]);
+ await user.click(lists[1]);
+ expect(lists[0]).toHaveAttribute('aria-selected', 'true');
+ expect(lists[1]).toHaveAttribute('aria-selected', 'true');
+ await user.keyboard('[ControlLeft>]');
+ await user.click(lists[0]);
+ expect(lists[0]).toHaveAttribute('aria-selected', 'false');
+ expect(lists[1]).toHaveAttribute('aria-selected', 'true');
+ });
+ it('should render tree with custom icons', () => {
+ const CustomIcon = () => ;
+ render(
+
+
+
+ );
+ expect(screen.getByTestId('test-icon')).toBeInTheDocument();
+ });
+
+ it('should expand a collapsed parent node when right arrow is pressed', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+
+
+ );
+ const parentNode = screen.getByTestId('parent-node');
+ expect(parentNode).not.toHaveAttribute('aria-expanded', 'true');
+ parentNode.focus();
+ expect(parentNode).toHaveFocus();
+ await user.keyboard('[ArrowRight]');
+ expect(parentNode).toHaveAttribute('aria-expanded', 'true');
+ const childNode = screen.getByTestId('child-node');
+ expect(childNode).toBeInTheDocument();
+ });
+ it('should navigate between nodes using ArrowUp and ArrowDown', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+
+ );
+ const node1 = screen.getByTestId('Node 1');
+ const node2 = screen.getByTestId('Node 2');
+ node1.focus();
+ expect(node1).toHaveFocus();
+ await user.keyboard('[ArrowDown]');
+ expect(node2).toHaveFocus();
+ await user.keyboard('[ArrowUp]');
+ expect(node1).toHaveFocus();
+ });
+
+ it('should not render label when hideLabel is true', () => {
+ render(
+
+
+
+ );
+ expect(screen.queryByText('Tree View')).not.toBeInTheDocument();
+ });
+
+ it('should render custom icons in TreeNode', () => {
+ const CustomIcon = () => ;
+
+ render(
+
+
+
+
+ );
+
+ const node1Icon = screen.getByTestId('custom-icon');
+ const node2 = screen.getByText('Node 2');
+
+ expect(node1Icon).toBeInTheDocument();
+ expect(node2.querySelector('svg')).toBeNull();
+ });
+ it('should render the label correctly', () => {
+ render(
+
+
+
+
+ );
+
+ expect(screen.getByLabelText('My Tree View')).toBeInTheDocument();
+ });
+
+ it('should collapse an expanded parent node when left arrow is pressed', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+
+
+ );
+
+ const parentNode = screen.getByTestId('parent-node');
+
+ // Initially, the parent node should be expanded
+ expect(parentNode).toHaveAttribute('aria-expanded', 'true');
+
+ // Focus on the parent node
+ parentNode.focus();
+ await user.keyboard('[ArrowLeft]');
+
+ // The parent node should now be collapsed
+ expect(parentNode).toHaveAttribute('aria-expanded', 'false');
+ });
+
+ it('should deselect a node when clicked again in multiselect mode', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+
+ );
+
+ const lists = screen.getAllByRole('treeitem');
+ await user.keyboard('[ControlLeft>]');
+ await user.click(lists[0]);
+ await user.click(lists[1]);
+
+ expect(lists[0]).toHaveAttribute('aria-selected', 'true');
+ expect(lists[1]).toHaveAttribute('aria-selected', 'true');
+
+ // Deselect Node 1
+ await user.keyboard('[ControlLeft>]');
+ await user.click(lists[0]);
+
+ expect(lists[0]).toHaveAttribute('aria-selected', 'false');
+ expect(lists[1]).toHaveAttribute('aria-selected', 'true');
+ });
+ it('should not allow interaction with disabled nodes', async () => {
+ const user = userEvent.setup();
+ render(
+
+
+
+
+ );
+
+ const node1 = screen.getByTestId('Node 1');
+ const node2 = screen.getByTestId('Node 2');
+
+ // The disabled node should not be focusable
+ await user.tab();
+ expect(node1).toHaveFocus();
+
+ // The disabled node should also not be clickable
+ fireEvent.click(node2);
+ expect(node2).not.toHaveClass(`${prefix}--tree-node--selected`);
+ });
+ it('should select nodes correctly when Home/End keys are used with multiselect and shiftKey+ctrlKey', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+
+
+ );
+
+ const node1 = screen.getByTestId('Node 1');
+ const node2 = screen.getByTestId('Node 2');
+ const node3 = screen.getByTestId('Node 3');
+
+ await user.click(node2);
+ expect(node2).toHaveFocus();
+ await user.keyboard('[ControlLeft>][ShiftLeft>][Home]');
+ expect(node1).toHaveClass(`${prefix}--tree-node--selected`);
+ expect(node2).toHaveClass(`${prefix}--tree-node--selected`);
+ });
+ it('should select nodes correctly when Home key is used with multiselect and shiftKey+ctrlKey', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+
+
+ );
+
+ const node1 = screen.getByTestId('Node 1');
+ const node2 = screen.getByTestId('Node 2');
+ const node3 = screen.getByTestId('Node 3');
+
+ await user.click(node2);
+ expect(node2).toHaveFocus();
+
+ await user.keyboard('[ControlLeft>][ShiftLeft>][Home]');
+
+ expect(node1).toHaveClass(`${prefix}--tree-node--selected`);
+ expect(node2).toHaveClass(`${prefix}--tree-node--selected`);
+ expect(node3).not.toHaveClass(`${prefix}--tree-node--selected`);
+ });
+
+ it('should select multiple nodes when Home key is pressed with Shift and Ctrl keys', async () => {
+ const user = userEvent.setup();
+
+ render(
+
+
+
+
+
+ );
+
+ const node1 = screen.getByTestId('Node 1');
+ const node2 = screen.getByTestId('Node 2');
+ const node3 = screen.getByTestId('Node 3');
+
+ await user.click(node2);
+ expect(node2).toHaveFocus();
+ await user.keyboard('[ControlLeft>][ShiftLeft>][Home]');
+ expect(node1).toHaveClass(`${prefix}--tree-node--selected`);
+ expect(node2).toHaveClass(`${prefix}--tree-node--selected`);
+ expect(node3).not.toHaveClass(`${prefix}--tree-node--selected`);
+ });
});