import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { createRenderer, isJsdom } from '@mui/internal-test-utils';
import Collapse from '@mui/material/Collapse';
import Fade from '@mui/material/Fade';
import Grow from '@mui/material/Grow';
import Slide from '@mui/material/Slide';
import Zoom from '@mui/material/Zoom';
import Popper from '@mui/material/Popper';
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
describe.skipIf(isJsdom())('', () => {
const { render } = createRenderer();
let originalScrollX;
let originalScrollY;
beforeEach(() => {
originalScrollX = window.screenX;
originalScrollY = window.scrollY;
});
afterEach(() => {
window.scrollTo(originalScrollX, originalScrollY);
});
describe('children layout integration', () => {
function BottomAnchoredPopper(props) {
const [anchorEl, anchorElRef] = React.useState(null);
React.useEffect(() => {
if (anchorEl !== null) {
window.scrollTo(0, anchorEl.getBoundingClientRect().top);
}
}, [anchorEl]);
return (
Spacer
);
}
it('autoFocus does not scroll', () => {
const handleFocus = spy();
const { setProps } = render(
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
});
it('focus during layout effect does not scroll', () => {
const handleFocus = spy();
function LayoutEffectFocusButton(props) {
const buttonRef = React.useRef(null);
React.useLayoutEffect(() => {
buttonRef.current.focus();
}, []);
return ;
}
const { setProps } = render(
will be focused
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
});
it('focus during passive effects do not scroll', () => {
const handleFocus = spy();
function EffectFocusButton(props) {
const buttonRef = React.useRef(null);
React.useEffect(() => {
buttonRef.current.focus();
}, []);
return ;
}
const { setProps } = render(
will be focused
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
if (isSafari) {
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
} else {
// FIXME: should equal
expect(window.scrollY, 'focus caused scroll').not.to.equal(scrollYBeforeOpen);
}
});
[
[Collapse, 'Collapse'],
[Fade, 'Fade'],
[Grow, 'Grow'],
[Slide, 'Slide'],
[Zoom, 'Zoom'],
].forEach(([TransitionComponent, name]) => {
describe(`in TransitionComponent ${name}`, () => {
it('autoFocus does not scroll', () => {
const handleFocus = spy();
const { setProps } = render(
{({ TransitionProps }) => {
return (
);
}}
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
});
it('focus during layout effect does not scroll', () => {
const handleFocus = spy();
function LayoutEffectFocusButton(props) {
const buttonRef = React.useRef(null);
React.useLayoutEffect(() => {
buttonRef.current.focus();
}, []);
return ;
}
const { setProps } = render(
{({ TransitionProps }) => {
return (
will be focused
);
}}
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
});
it('focus during passive effects do not scroll', () => {
const handleFocus = spy();
function EffectFocusButton(props) {
const buttonRef = React.useRef(null);
React.useEffect(() => {
buttonRef.current.focus();
}, []);
return ;
}
const { setProps } = render(
{({ TransitionProps }) => {
return (
will be focused
);
}}
,
);
expect(handleFocus.callCount).to.equal(0);
const scrollYBeforeOpen = window.scrollY;
setProps({ open: true });
expect(handleFocus.callCount).to.equal(1);
expect(window.scrollY, 'focus caused scroll').to.equal(scrollYBeforeOpen);
});
});
});
});
});