Skip to content

Commit

Permalink
[core] Use describeTreeView for focus tests (#12698)
Browse files Browse the repository at this point in the history
  • Loading branch information
flaviendelangle authored Apr 19, 2024
1 parent fb8f3da commit f3b5f1b
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 288 deletions.
139 changes: 0 additions & 139 deletions packages/x-tree-view/src/SimpleTreeView/SimpleTreeView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import Portal from '@mui/material/Portal';
import { SimpleTreeView, simpleTreeViewClasses as classes } from '@mui/x-tree-view/SimpleTreeView';
import { TreeItem } from '@mui/x-tree-view/TreeItem';
import { describeConformance } from 'test/utils/describeConformance';
import { useTreeViewApiRef } from '../hooks';
import { SimpleTreeViewApiRef } from './SimpleTreeView.types';

describe('<SimpleTreeView />', () => {
const { render } = createRenderer();
Expand Down Expand Up @@ -244,143 +242,6 @@ describe('<SimpleTreeView />', () => {
expect(onSelectedItemsChange.lastCall.args[1]).to.deep.equal(['1', '3']);
});

describe('onItemFocus', () => {
it('should be called when an item is focused', () => {
const onFocus = spy();
const { getByTestId } = render(
<SimpleTreeView onItemFocus={onFocus}>
<TreeItem itemId="one" data-testid="one" />
</SimpleTreeView>,
);

act(() => {
getByTestId('one').focus();
});

expect(onFocus.callCount).to.equal(1);
expect(onFocus.args[0][1]).to.equal('one');
});
});

describe('useTreeViewFocus', () => {
it('should set tabIndex={0} on the selected item', () => {
const { getByTestId } = render(
<SimpleTreeView selectedItems="one">
<TreeItem itemId="one" data-testid="one" />
<TreeItem itemId="two" data-testid="two" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(0);
expect(getByTestId('two').tabIndex).to.equal(-1);
});

it('should set tabIndex={0} on the selected item (multi select)', () => {
const { getByTestId } = render(
<SimpleTreeView multiSelect selectedItems={['one']}>
<TreeItem itemId="one" data-testid="one" />
<TreeItem itemId="two" data-testid="two" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(0);
expect(getByTestId('two').tabIndex).to.equal(-1);
});

it('should set tabIndex={0} on the first visible selected item (multi select)', () => {
const { getByTestId } = render(
<SimpleTreeView multiSelect selectedItems={['two', 'three']}>
<TreeItem itemId="one" data-testid="one">
<TreeItem itemId="two" data-testid="two" />
</TreeItem>
<TreeItem itemId="three" data-testid="three" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(-1);
expect(getByTestId('three').tabIndex).to.equal(0);
});

it('should set tabIndex={0} on the first item if the selected item is not visible', () => {
const { getByTestId } = render(
<SimpleTreeView selectedItems="two">
<TreeItem itemId="one" data-testid="one">
<TreeItem itemId="two" data-testid="two" />
</TreeItem>
<TreeItem itemId="three" data-testid="three" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(0);
expect(getByTestId('three').tabIndex).to.equal(-1);
});

it('should set tabIndex={0} on the first item if no selected item is visible (multi select)', () => {
const { getByTestId } = render(
<SimpleTreeView multiSelect selectedItems={['two']}>
<TreeItem itemId="one" data-testid="one">
<TreeItem itemId="two" data-testid="two" />
</TreeItem>
<TreeItem itemId="three" data-testid="three" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(0);
expect(getByTestId('three').tabIndex).to.equal(-1);
});

it('should focus specific item using `apiRef`', () => {
let apiRef: SimpleTreeViewApiRef;
const onItemFocus = spy();

function TestCase() {
apiRef = useTreeViewApiRef();
return (
<SimpleTreeView apiRef={apiRef} onItemFocus={onItemFocus}>
<TreeItem itemId="one" data-testid="one">
<TreeItem itemId="two" data-testid="two" />
</TreeItem>
<TreeItem itemId="three" data-testid="three" />
</SimpleTreeView>
);
}

const { getByTestId } = render(<TestCase />);

act(() => {
apiRef.current?.focusItem({} as React.SyntheticEvent, 'three');
});

expect(getByTestId('three')).toHaveFocus();
expect(onItemFocus.lastCall.lastArg).to.equal('three');
});

it('should not focus item if parent is collapsed', () => {
let apiRef: SimpleTreeViewApiRef;
const onItemFocus = spy();

function TestCase() {
apiRef = useTreeViewApiRef();
return (
<SimpleTreeView apiRef={apiRef} onItemFocus={onItemFocus}>
<TreeItem itemId="1" label="1">
<TreeItem itemId="1.1" label="1.1" />
</TreeItem>
<TreeItem itemId="2" label="2" />
</SimpleTreeView>
);
}

const { getByRole } = render(<TestCase />);

act(() => {
apiRef.current?.focusItem({} as React.SyntheticEvent, '1.1');
});

expect(getByRole('tree')).not.toHaveFocus();
});
});

describe('Accessibility', () => {
it('(TreeView) should have the role `tree`', () => {
const { getByRole } = render(<SimpleTreeView />);
Expand Down
148 changes: 0 additions & 148 deletions packages/x-tree-view/src/TreeItem/TreeItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,82 +284,6 @@ describe('<TreeItem />', () => {
});
});

describe('when an item receives focus', () => {
it('should focus the first item if none of the items are selected before the tree receives focus', () => {
const { getByTestId, queryAllByRole } = render(
<SimpleTreeView>
<TreeItem itemId="1" label="one" data-testid="one" />
<TreeItem itemId="2" label="two" />
<TreeItem itemId="3" label="three" />
</SimpleTreeView>,
);

expect(queryAllByRole('treeitem', { selected: true })).to.have.length(0);

act(() => {
getByTestId('one').focus();
});

expect(getByTestId('one')).toHaveFocus();
});

it('should work with programmatic focus', () => {
const { getByTestId } = render(
<SimpleTreeView>
<TreeItem itemId="one" data-testid="one" />
<TreeItem itemId="two" data-testid="two" />
</SimpleTreeView>,
);

act(() => {
getByTestId('one').focus();
});

expect(getByTestId('one')).toHaveFocus();

act(() => {
getByTestId('two').focus();
});
expect(getByTestId('two')).toHaveFocus();
});

it('should work when focused item is removed', () => {
let removeActiveItem;
// a TreeItem which can remove from the tree by calling `removeActiveItem`
function ControlledTreeItem(props) {
const [mounted, setMounted] = React.useReducer(() => false, true);
removeActiveItem = setMounted;

if (!mounted) {
return null;
}
return <TreeItem {...props} />;
}

const { getByTestId } = render(
<SimpleTreeView defaultExpandedItems={['one']}>
<TreeItem itemId="one" data-testid="one">
<TreeItem itemId="two" data-testid="two" />
<ControlledTreeItem itemId="three" data-testid="three" />
</TreeItem>
</SimpleTreeView>,
);

act(() => {
getByTestId('three').focus();
});
expect(getByTestId('three')).toHaveFocus();

// generic action that removes an item.
// Could be promise based, or timeout, or another user interaction
act(() => {
removeActiveItem();
});

expect(getByTestId('one')).toHaveFocus();
});
});

describe('Navigation', () => {
describe('right arrow interaction', () => {
it('should open the item and not move the focus if focus is on a closed item', () => {
Expand Down Expand Up @@ -1625,33 +1549,6 @@ describe('<TreeItem />', () => {

describe('focus', () => {
describe('`disabledItemsFocusable={true}`', () => {
it('should prevent focus by mouse', () => {
const onItemFocus = spy();
const { getByText } = render(
<SimpleTreeView disabledItemsFocusable onItemFocus={onItemFocus}>
<TreeItem itemId="one" label="one" data-testid="one" />
<TreeItem itemId="two" label="two" disabled data-testid="two" />
</SimpleTreeView>,
);

fireEvent.click(getByText('two'));
expect(onItemFocus.callCount).to.equal(0);
});

it('should not prevent programmatic focus', () => {
const { getByTestId } = render(
<SimpleTreeView disabledItemsFocusable>
<TreeItem itemId="one" label="one" disabled data-testid="one" />
<TreeItem itemId="two" label="two" data-testid="two" />
</SimpleTreeView>,
);

act(() => {
getByTestId('one').focus();
});
expect(getByTestId('one')).toHaveFocus();
});

it('should not prevent focus by type-ahead', () => {
const { getByTestId } = render(
<SimpleTreeView disabledItemsFocusable>
Expand Down Expand Up @@ -1688,39 +1585,6 @@ describe('<TreeItem />', () => {
});

describe('`disabledItemsFocusable=false`', () => {
it('should prevent focus by mouse', () => {
const onItemFocus = spy();
const { getByText } = render(
<SimpleTreeView onItemFocus={onItemFocus}>
<TreeItem itemId="one" label="one" data-testid="one" />
<TreeItem itemId="two" label="two" disabled data-testid="two" />
</SimpleTreeView>,
);

fireEvent.click(getByText('two'));
expect(onItemFocus.callCount).to.equal(0);
});

it('should prevent focus when clicking', () => {
const handleMouseDown = spy();

const { getByText } = render(
<SimpleTreeView>
<TreeItem
itemId="one"
label="one"
disabled
data-testid="one"
ContentProps={{ onMouseDown: handleMouseDown }}
/>
<TreeItem itemId="two" label="two" data-testid="two" />
</SimpleTreeView>,
);

fireEvent.mouseDown(getByText('one'));
expect(handleMouseDown.lastCall.firstArg.defaultPrevented).to.equal(true);
});

it('should prevent focus by type-ahead', () => {
const { getByTestId } = render(
<SimpleTreeView>
Expand Down Expand Up @@ -1755,18 +1619,6 @@ describe('<TreeItem />', () => {
fireEvent.keyDown(getByTestId('one'), { key: 'ArrowDown' });
expect(getByTestId('three')).toHaveFocus();
});

it('should set tabIndex={-1} and tabIndex={0} on next item', () => {
const { getByTestId } = render(
<SimpleTreeView>
<TreeItem itemId="one" label="one" disabled data-testid="one" />
<TreeItem itemId="two" label="two" data-testid="two" />
</SimpleTreeView>,
);

expect(getByTestId('one').tabIndex).to.equal(-1);
expect(getByTestId('two').tabIndex).to.equal(0);
});
});
});

Expand Down
Loading

0 comments on commit f3b5f1b

Please sign in to comment.