Skip to content

Commit

Permalink
add missing test
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Aug 31, 2020
1 parent 9ed548c commit 6ce9ad4
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 86 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ const theme = createMuiTheme({
- [ButtonBase] Reset box-sizing to border-box (#22316) @su8ru
- [Dialog] Fix unexpected close when releasing click on backdrop (#22310) @danbrud
- [Divider] Add text in divider (#22285) @ShehryarShoukat96
- [Slider] Respect disabled property when already focused (#22247) @pireads
- [Slider] Respect disabled property when already focused (#22247) @pireads
- [Tabs] Don't fire onChange if current value (#22381) @jjoselv
- [Tabs] Improve focus management on list with no active tabs (#22377) @alexmotoc
- [theme] Add theme.mixins.gutters() in adaptV4Theme (#22396) @mnajdova
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui/src/ButtonBase/ButtonBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const ButtonBase = React.forwardRef(function ButtonBase(props, ref) {
ref: focusVisibleRef,
} = useIsFocusVisible();
const [focusVisible, setFocusVisible] = React.useState(false);

if (disabled && focusVisible) {
setFocusVisible(false);
}
Expand Down
22 changes: 11 additions & 11 deletions packages/material-ui/src/ButtonBase/ButtonBase.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
act,
createClientRender,
fireEvent,
focusVisible,
screen,
dispatchFocusVisible,
simulatePointerDevice,
} from 'test/utils';
import * as PropTypes from 'prop-types';
Expand Down Expand Up @@ -198,7 +198,7 @@ describe('<ButtonBase />', () => {
const button = getByRole('button');
simulatePointerDevice();

focusVisible(button);
dispatchFocusVisible(button);

expect(button.querySelectorAll('.ripple-pulsate')).to.have.lengthOf(0);
});
Expand Down Expand Up @@ -458,7 +458,7 @@ describe('<ButtonBase />', () => {
const button = getByRole('button');

simulatePointerDevice();
focusVisible(button);
dispatchFocusVisible(button);

expect(button.querySelectorAll('.ripple-pulsate')).to.have.lengthOf(1);
});
Expand All @@ -477,7 +477,7 @@ describe('<ButtonBase />', () => {
const button = getByRole('button');

simulatePointerDevice();
focusVisible(button);
dispatchFocusVisible(button);
fireEvent.mouseLeave(button);

expect(button.querySelectorAll('.ripple-pulsate')).to.have.lengthOf(1);
Expand All @@ -499,7 +499,7 @@ describe('<ButtonBase />', () => {
const button = getByRole('button');

simulatePointerDevice();
focusVisible(button);
dispatchFocusVisible(button);
fireEvent.keyDown(button, { key: ' ' });

expect(button.querySelectorAll('.ripple-pulsate .child-leaving')).to.have.lengthOf(1);
Expand All @@ -522,7 +522,7 @@ describe('<ButtonBase />', () => {
const button = getByRole('button');

simulatePointerDevice();
focusVisible(button);
dispatchFocusVisible(button);
fireEvent.keyDown(button, { key: ' ' });
fireEvent.keyUp(button, { key: ' ' });

Expand All @@ -545,7 +545,7 @@ describe('<ButtonBase />', () => {
);
const button = getByRole('button');
simulatePointerDevice();
focusVisible(button);
dispatchFocusVisible(button);

act(() => {
button.blur();
Expand Down Expand Up @@ -575,7 +575,7 @@ describe('<ButtonBase />', () => {
const button = getByText('Hello');
simulatePointerDevice();

focusVisible(button);
dispatchFocusVisible(button);

expect(button).to.have.class(classes.focusVisible);

Expand Down Expand Up @@ -635,7 +635,7 @@ describe('<ButtonBase />', () => {
expect(button).not.to.have.class(classes.focusVisible);
button.focus();
expect(button).not.to.have.class(classes.focusVisible);
focusVisible(button);
dispatchFocusVisible(button);
expect(button).to.have.class(classes.focusVisible);
});

Expand Down Expand Up @@ -677,7 +677,7 @@ describe('<ButtonBase />', () => {
const focusRetarget = getByText('you cannot escape me');
simulatePointerDevice();

focusVisible(buttonBase);
dispatchFocusVisible(buttonBase);

expect(focusRetarget).toHaveFocus();
expect(eventLog).to.deep.equal(['focus-visible', 'focus', 'blur']);
Expand All @@ -693,7 +693,7 @@ describe('<ButtonBase />', () => {
);
simulatePointerDevice();

focusVisible(getByRole('button'));
dispatchFocusVisible(getByRole('button'));

expect(onFocusVisibleSpy.calledOnce).to.equal(true);
expect(onFocusVisibleSpy.firstCall.args).to.have.lengthOf(1);
Expand Down
41 changes: 8 additions & 33 deletions packages/material-ui/src/Chip/Chip.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { emphasize, fade } from '../styles/colorManipulator';
import useForkRef from '../utils/useForkRef';
import unsupportedProp from '../utils/unsupportedProp';
import capitalize from '../utils/capitalize';
import useEventCallback from '../utils/useEventCallback';
import useIsFocusVisible from '../utils/useIsFocusVisible';
import ButtonBase from '../ButtonBase';

export const styles = (theme) => {
Expand Down Expand Up @@ -298,36 +296,11 @@ const Chip = React.forwardRef(function Chip(props, ref) {
const chipRef = React.useRef(null);
const handleRef = useForkRef(chipRef, ref);

const {
isFocusVisibleRef,
onFocus: handleFocusVisible,
onBlur: handleBlurVisible,
} = useIsFocusVisible();
const [focusVisible, setFocusVisible] = React.useState(false);
if (disabled && focusVisible) {
setFocusVisible(false);
}
React.useEffect(() => {
isFocusVisibleRef.current = focusVisible;
}, [focusVisible, isFocusVisibleRef]);

const handleBlur = useEventCallback((event) => {
handleBlurVisible(event);
if (isFocusVisibleRef.current === false) {
setFocusVisible(false);
}
}, false);

const handleFocus = useEventCallback((event) => {
const handleFocus = (event) => {
if (!chipRef.current) {
chipRef.current = event.currentTarget;
}

handleFocusVisible(event);
if (isFocusVisibleRef.current === true) {
setFocusVisible(true);
}
});
};

const handleDeleteIconClick = (event) => {
// Stop the event from bubbling up to the `Chip`
Expand Down Expand Up @@ -369,7 +342,10 @@ const Chip = React.forwardRef(function Chip(props, ref) {
const small = size === 'small';

const Component = ComponentProp || (clickable ? ButtonBase : 'div');
const moreProps = Component === ButtonBase ? { component: 'div' } : {};
const moreProps =
Component === ButtonBase
? { component: 'div', focusVisibleClassName: classes.focusVisible }
: {};

let deleteIcon = null;
if (onDelete) {
Expand Down Expand Up @@ -450,16 +426,15 @@ const Chip = React.forwardRef(function Chip(props, ref) {
[classes[`clickableColor${capitalize(color)}`]]: clickable && color !== 'default',
[classes.deletable]: onDelete,
[classes[`deletableColor${capitalize(color)}`]]: onDelete && color !== 'default',
[classes.focusVisible]: focusVisible,
[classes.outlinedPrimary]: variant === 'outlined' && color === 'primary',
[classes.outlinedSecondary]: variant === 'outlined' && color === 'secondary',
},
themeVariantsClasses,
className,
)}
aria-disabled={disabled ? true : undefined}
aria-disabled={!clickable && disabled ? true : undefined}
disabled={clickable && disabled ? true : undefined}
tabIndex={clickable || onDelete ? 0 : undefined}
onBlur={handleBlur}
onClick={onClick}
onFocus={handleFocus}
onKeyDown={handleKeyDown}
Expand Down
20 changes: 17 additions & 3 deletions packages/material-ui/src/Chip/Chip.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
act,
createClientRender,
fireEvent,
focusVisible,
dispatchFocusVisible,
simulatePointerDevice,
} from 'test/utils';
import CheckBox from '../internal/svg-icons/CheckBox';
Expand All @@ -18,7 +18,7 @@ import Chip from './Chip';
describe('<Chip />', () => {
let classes;
const mount = createMount();
const render = createClientRender();
const render = createClientRender({ strict: false });

before(() => {
classes = getClasses(<Chip />);
Expand Down Expand Up @@ -550,9 +550,23 @@ describe('<Chip />', () => {
expect(chip).not.to.have.class(classes.focusVisible);
chip.focus();
expect(chip).not.to.have.class(classes.focusVisible);
focusVisible(chip);
dispatchFocusVisible(chip);

expect(chip).to.have.class(classes.focusVisible);
});

it('should reset the focused state', () => {
const { container, setProps } = render(<Chip label="Test Chip" onClick={() => {}} />);
const chip = container.querySelector(`.${classes.root}`);

simulatePointerDevice();
dispatchFocusVisible(chip);

expect(chip).to.have.class(classes.focusVisible);

setProps({ disabled: true });

expect(chip).not.to.have.class(classes.focusVisible);
});
});
});
26 changes: 7 additions & 19 deletions packages/material-ui/src/Tooltip/Tooltip.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,13 @@ import {
createClientRender,
fireEvent,
screen,
simulatePointerDevice,
dispatchFocusVisible,
} from 'test/utils';
import { camelCase } from 'lodash/string';
import Tooltip, { testReset } from './Tooltip';
import Input from '../Input';

function focusVisible(element) {
act(() => {
element.blur();
fireEvent.keyDown(document.activeElement || document.body, { key: 'Tab' });
element.focus();
});
}

function simulatePointerDevice() {
// first focus on a page triggers focus visible until a pointer event
// has been dispatched
document.dispatchEvent(new window.Event('pointerdown'));
}

describe('<Tooltip />', () => {
/**
* @type {ReturnType<typeof useFakeTimers>}
Expand Down Expand Up @@ -379,7 +367,7 @@ describe('<Tooltip />', () => {
);
simulatePointerDevice();

focusVisible(getByRole('button'));
dispatchFocusVisible(getByRole('button'));
expect(queryByRole('tooltip')).to.equal(null);

act(() => {
Expand Down Expand Up @@ -408,7 +396,7 @@ describe('<Tooltip />', () => {
</Tooltip>,
);
const children = getByRole('button');
focusVisible(children);
dispatchFocusVisible(children);

expect(queryByRole('tooltip')).to.equal(null);

Expand All @@ -430,7 +418,7 @@ describe('<Tooltip />', () => {

expect(queryByRole('tooltip')).to.equal(null);

focusVisible(children);
dispatchFocusVisible(children);
// Bypass `enterDelay` wait, use `enterNextDelay`.
expect(queryByRole('tooltip')).to.equal(null);

Expand Down Expand Up @@ -463,7 +451,7 @@ describe('<Tooltip />', () => {
);
simulatePointerDevice();

focusVisible(getByRole('button'));
dispatchFocusVisible(getByRole('button'));
act(() => {
clock.tick(enterDelay);
});
Expand Down Expand Up @@ -762,7 +750,7 @@ describe('<Tooltip />', () => {

expect(queryByRole('tooltip')).to.equal(null);

focusVisible(getByRole('button'));
dispatchFocusVisible(getByRole('button'));

expect(getByRole('tooltip')).toBeVisible();

Expand Down
20 changes: 5 additions & 15 deletions packages/material-ui/src/utils/useIsFocusVisible.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import { expect } from 'chai';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { createMount } from 'test/utils';
import { createClientRender, dispatchFocusVisible, simulatePointerDevice } from 'test/utils';
import useIsFocusVisible, { teardown as teardownFocusVisible } from './useIsFocusVisible';
import useForkRef from './useForkRef';

function dispatchFocusVisible(element) {
element.ownerDocument.dispatchEvent(new window.Event('keydown'));
element.focus();
}

function simulatePointerDevice() {
// first focus on a page triggers focus visible until a pointer event
// has been dispatched
document.dispatchEvent(new window.Event('pointerdown'));
}

const SimpleButton = React.forwardRef(function SimpleButton(props, ref) {
const {
isFocusVisibleRef,
Expand Down Expand Up @@ -55,7 +44,7 @@ const SimpleButton = React.forwardRef(function SimpleButton(props, ref) {
});

describe('focus-visible polyfill', () => {
const mount = createMount();
const render = createClientRender();

before(() => {
// isolate test from previous component test that use the polyfill in the document scope
Expand Down Expand Up @@ -85,12 +74,13 @@ describe('focus-visible polyfill', () => {

it('should set focus state for shadowRoot children', () => {
const buttonRef = React.createRef();
mount(
render(
<SimpleButton id="test-button" ref={buttonRef}>
Hello
</SimpleButton>,
{},
{
attachTo: rootElement.shadowRoot,
container: rootElement.shadowRoot,
},
);
simulatePointerDevice();
Expand Down
5 changes: 1 addition & 4 deletions test/utils/focusVisible.js → test/utils/focusVisible.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { act, fireEvent } from './createClientRender';

/**
* @param {HTMLElement} element
*/
export function focusVisible(element) {
export function dispatchFocusVisible(element: HTMLElement) {
act(() => {
element.blur();
fireEvent.keyDown(document.body, { key: 'Tab' });
Expand Down

0 comments on commit 6ce9ad4

Please sign in to comment.