kopia lustrzana https://github.com/wagtail/wagtail
Minor accessibility fixes to new slim sidebar menu items (#8015)
* Consistently set `aria-haspopup="menu"` for all sidebar menu items that have sub-menus (LB (Ben Johnston)) * Make sure `aria-expanded` is always explicitly set as a string in sidebar (LB (Ben Johnston)) * Use a button element instead of a link for page explorer menu item, for the correct semantics and behavior (LB (Ben Johnston))pull/8132/head
rodzic
14280ad7ea
commit
042d077fc1
|
@ -28,6 +28,9 @@ Changelog
|
|||
* Fix: Improve the contrast of the “Remember me” checkbox against the login page’s background (Steven Steinwand)
|
||||
* Fix: Group permission rows with custom permissions no longer have extra padding (Steven Steinwand)
|
||||
* Fix: Make sure the focus outline of checkboxes is fully around the outer border (Steven Steinwand)
|
||||
* Fix: Consistently set `aria-haspopup="menu"` for all sidebar menu items that have sub-menus (LB (Ben Johnston))
|
||||
* Fix: Make sure `aria-expanded` is always explicitly set as a string in sidebar (LB (Ben Johnston))
|
||||
* Fix: Use a button element instead of a link for page explorer menu item, for the correct semantics and behavior (LB (Ben Johnston))
|
||||
|
||||
|
||||
2.16.2 (xx.xx.xxxx) - IN DEVELOPMENT
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Sidebar } from './Sidebar';
|
||||
|
||||
describe('Sidebar', () => {
|
||||
const strings = {};
|
||||
|
||||
it('should render with the minimum required props', () => {
|
||||
const wrapper = shallow(<Sidebar modules={[]} strings={strings} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should toggle the slim mode in the sidebar when outer button clicked', () => {
|
||||
const onExpandCollapse = jest.fn();
|
||||
|
||||
const wrapper = shallow(
|
||||
<Sidebar
|
||||
modules={[]}
|
||||
onExpandCollapse={onExpandCollapse}
|
||||
strings={strings}
|
||||
/>,
|
||||
);
|
||||
|
||||
// default expanded (non-slim)
|
||||
expect(
|
||||
wrapper.find('.sidebar__collapse-toggle').prop('aria-expanded'),
|
||||
).toEqual('true');
|
||||
expect(wrapper.find('.sidebar--slim')).toHaveLength(0);
|
||||
expect(onExpandCollapse).not.toHaveBeenCalled();
|
||||
|
||||
// toggle slim mode
|
||||
wrapper.find('.sidebar__collapse-toggle').simulate('click');
|
||||
|
||||
expect(
|
||||
wrapper.find('.sidebar__collapse-toggle').prop('aria-expanded'),
|
||||
).toEqual('false');
|
||||
expect(wrapper.find('.sidebar--slim')).toHaveLength(1);
|
||||
expect(onExpandCollapse).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should toggle the sidebar visibility on click (used on mobile)', () => {
|
||||
const onExpandCollapse = jest.fn();
|
||||
|
||||
const wrapper = shallow(
|
||||
<Sidebar
|
||||
modules={[]}
|
||||
onExpandCollapse={onExpandCollapse}
|
||||
strings={strings}
|
||||
/>,
|
||||
);
|
||||
|
||||
// default not expanded
|
||||
expect(wrapper.find('.sidebar-nav-toggle').prop('aria-expanded')).toEqual(
|
||||
'false',
|
||||
);
|
||||
expect(wrapper.find('.sidebar-nav-toggle--open')).toHaveLength(0);
|
||||
|
||||
// toggle expanded mode
|
||||
wrapper.find('.sidebar-nav-toggle').simulate('click');
|
||||
|
||||
// check it is expanded
|
||||
expect(wrapper.find('.sidebar-nav-toggle').prop('aria-expanded')).toEqual(
|
||||
'true',
|
||||
);
|
||||
expect(wrapper.find('.sidebar-nav-toggle--open')).toHaveLength(1);
|
||||
});
|
||||
});
|
|
@ -38,7 +38,7 @@ export interface SidebarProps {
|
|||
export const Sidebar: React.FunctionComponent<SidebarProps> = ({
|
||||
modules,
|
||||
currentPath,
|
||||
collapsedOnLoad,
|
||||
collapsedOnLoad = false,
|
||||
strings,
|
||||
navigate,
|
||||
onExpandCollapse,
|
||||
|
@ -104,8 +104,7 @@ export const Sidebar: React.FunctionComponent<SidebarProps> = ({
|
|||
};
|
||||
}, [slim]);
|
||||
|
||||
const onClickCollapseToggle = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
const onClickCollapseToggle = () => {
|
||||
setCollapsed(!collapsed);
|
||||
|
||||
if (onExpandCollapse) {
|
||||
|
@ -113,8 +112,7 @@ export const Sidebar: React.FunctionComponent<SidebarProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const onClickOpenCloseToggle = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
const onClickOpenCloseToggle = () => {
|
||||
setVisibleOnMobile(!visibleOnMobile);
|
||||
setExpandingOrCollapsing(true);
|
||||
|
||||
|
@ -185,10 +183,11 @@ export const Sidebar: React.FunctionComponent<SidebarProps> = ({
|
|||
>
|
||||
<div className="sidebar__inner">
|
||||
<button
|
||||
className="button sidebar__collapse-toggle"
|
||||
onClick={onClickCollapseToggle}
|
||||
aria-label={strings.TOGGLE_SIDEBAR}
|
||||
aria-expanded={!slim}
|
||||
className="button sidebar__collapse-toggle"
|
||||
aria-expanded={slim ? 'false' : 'true'}
|
||||
type="button"
|
||||
>
|
||||
{collapsed ? (
|
||||
<Icon name="angle-double-right" />
|
||||
|
@ -211,12 +210,13 @@ export const Sidebar: React.FunctionComponent<SidebarProps> = ({
|
|||
<button
|
||||
onClick={onClickOpenCloseToggle}
|
||||
aria-label={strings.TOGGLE_SIDEBAR}
|
||||
aria-expanded={visibleOnMobile}
|
||||
aria-expanded={visibleOnMobile ? 'true' : 'false'}
|
||||
className={
|
||||
'button sidebar-nav-toggle' +
|
||||
(isMobile ? ' sidebar-nav-toggle--mobile' : '') +
|
||||
(visibleOnMobile ? ' sidebar-nav-toggle--open' : '')
|
||||
}
|
||||
type="button"
|
||||
>
|
||||
{visibleOnMobile ? <Icon name="cross" /> : <Icon name="bars" />}
|
||||
</button>
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Sidebar should render with the minimum required props 1`] = `
|
||||
<Fragment>
|
||||
<div
|
||||
className="sidebar"
|
||||
>
|
||||
<div
|
||||
className="sidebar__inner"
|
||||
>
|
||||
<button
|
||||
aria-expanded="true"
|
||||
className="button sidebar__collapse-toggle"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<Icon
|
||||
name="angle-double-left"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
className="sidebar__peek-hover-area"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
className="button sidebar-nav-toggle"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<Icon
|
||||
name="bars"
|
||||
/>
|
||||
</button>
|
||||
</Fragment>
|
||||
`;
|
|
@ -1,6 +1,5 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import Button from '../../Button/Button';
|
||||
import Icon from '../../Icon/Icon';
|
||||
import { MenuItemProps } from './MenuItem';
|
||||
import { LinkMenuItemDefinition } from './LinkMenuItem';
|
||||
|
@ -47,9 +46,7 @@ export const PageExplorerMenuItem: React.FunctionComponent<
|
|||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const onClick = () => {
|
||||
// Open/close explorer
|
||||
if (isOpen) {
|
||||
dispatch({
|
||||
|
@ -65,7 +62,7 @@ export const PageExplorerMenuItem: React.FunctionComponent<
|
|||
};
|
||||
|
||||
const className =
|
||||
'sidebar-menu-item' +
|
||||
'sidebar-menu-item sidebar-page-explorer-item' +
|
||||
(isActive ? ' sidebar-menu-item--active' : '') +
|
||||
(isInSubMenu ? ' sidebar-menu-item--in-sub-menu' : '');
|
||||
|
||||
|
@ -75,15 +72,17 @@ export const PageExplorerMenuItem: React.FunctionComponent<
|
|||
|
||||
return (
|
||||
<li className={className}>
|
||||
<Button
|
||||
dialogTrigger={true}
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="sidebar-menu-item__link"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={isOpen ? 'true' : 'false'}
|
||||
type="button"
|
||||
>
|
||||
<Icon name="folder-open-inverse" className="icon--menuitem" />
|
||||
<span className="menuitem-label">{item.label}</span>
|
||||
<Icon className={sidebarTriggerIconClassName} name="arrow-right" />
|
||||
</Button>
|
||||
</button>
|
||||
<div>
|
||||
<SidebarPanel
|
||||
isVisible={isVisible}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { PageExplorerMenuItem } from './PageExplorerMenuItem';
|
||||
|
||||
describe('PageExplorerMenuItem', () => {
|
||||
const state = { activePath: '.reports.workflows', navigationPath: '' };
|
||||
|
||||
it('should render with the minimum required props', () => {
|
||||
const wrapper = shallow(
|
||||
<PageExplorerMenuItem item={{}} path=".explorer" state={state} />,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should expand the explorer menu when clicked', () => {
|
||||
const dispatch = jest.fn();
|
||||
const preventDefault = jest.fn();
|
||||
|
||||
const wrapper = shallow(
|
||||
<PageExplorerMenuItem
|
||||
dispatch={dispatch}
|
||||
item={{}}
|
||||
path=".explorer"
|
||||
state={state}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper.find('.sidebar-menu-item__link').prop('aria-expanded'),
|
||||
).toEqual('false');
|
||||
expect(wrapper.find('SidebarPanel').prop('isOpen')).toBe(false);
|
||||
expect(dispatch).not.toHaveBeenCalled();
|
||||
expect(preventDefault).not.toHaveBeenCalled();
|
||||
|
||||
// click the button
|
||||
wrapper
|
||||
.find('.sidebar-menu-item__link')
|
||||
.simulate('click', { preventDefault });
|
||||
|
||||
expect(dispatch).toHaveBeenCalledWith({
|
||||
path: '.explorer',
|
||||
type: 'set-navigation-path',
|
||||
});
|
||||
expect(preventDefault).not.toHaveBeenCalled();
|
||||
|
||||
// manually update the state as if the redux action was dispatched
|
||||
wrapper.setProps({
|
||||
state: { activePath: '.reports.workflows', navigationPath: '.explorer' },
|
||||
});
|
||||
|
||||
// check that the expanded state is working
|
||||
expect(
|
||||
wrapper.find('.sidebar-menu-item__link').prop('aria-expanded'),
|
||||
).toEqual('true');
|
||||
expect(wrapper.find('SidebarPanel').prop('isOpen')).toBe(true);
|
||||
|
||||
// click the button to close
|
||||
wrapper
|
||||
.find('.sidebar-menu-item__link')
|
||||
.simulate('click', { preventDefault });
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenLastCalledWith({
|
||||
path: '',
|
||||
type: 'set-navigation-path',
|
||||
});
|
||||
expect(preventDefault).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { SubMenuItem } from './SubMenuItem';
|
||||
|
||||
describe('SubMenuItem', () => {
|
||||
const strings = {};
|
||||
const state = { activePath: '.reports.workflows', navigationPath: '' };
|
||||
|
||||
it('should render with the minimum required props', () => {
|
||||
const wrapper = shallow(
|
||||
<SubMenuItem
|
||||
item={{ classNames: '', menuItems: [] }}
|
||||
items={[]}
|
||||
state={state}
|
||||
path=".reports"
|
||||
strings={strings}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should provide a button to expand the sub-menu', () => {
|
||||
const dispatch = jest.fn();
|
||||
|
||||
const wrapper = shallow(
|
||||
<SubMenuItem
|
||||
dispatch={dispatch}
|
||||
item={{ classNames: '', menuItems: [] }}
|
||||
items={[]}
|
||||
state={state}
|
||||
path=".reports"
|
||||
strings={strings}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.sidebar-menu-item__link').prop('aria-expanded')).toBe(
|
||||
'false',
|
||||
);
|
||||
expect(dispatch).not.toHaveBeenCalled();
|
||||
expect(wrapper.find('.sidebar-sub-menu-item--open')).toHaveLength(0);
|
||||
|
||||
// click the sub menu item
|
||||
wrapper.find('.sidebar-menu-item__link').simulate('click');
|
||||
|
||||
// check the dispatch function (redux state) was called
|
||||
expect(dispatch).toHaveBeenCalledWith({
|
||||
path: '.reports',
|
||||
type: 'set-navigation-path',
|
||||
});
|
||||
|
||||
// manually update the state as if the redux action was dispatched
|
||||
wrapper.setProps({
|
||||
state: { navigationPath: '.reports', activePath: '.reports.workflows' },
|
||||
});
|
||||
|
||||
expect(wrapper.find('.sidebar-menu-item__link').prop('aria-expanded')).toBe(
|
||||
'true',
|
||||
);
|
||||
expect(wrapper.find('.sidebar-sub-menu-item--open')).toHaveLength(1);
|
||||
|
||||
// click a second time to 'close'
|
||||
wrapper.find('.sidebar-menu-item__link').simulate('click');
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenLastCalledWith({
|
||||
path: '',
|
||||
type: 'set-navigation-path',
|
||||
});
|
||||
});
|
||||
});
|
|
@ -37,7 +37,7 @@ export const SubMenuItem: React.FunctionComponent<SubMenuItemProps> = ({
|
|||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
const onClick = () => {
|
||||
if (isOpen) {
|
||||
const pathComponents = path.split('.');
|
||||
pathComponents.pop();
|
||||
|
@ -52,8 +52,6 @@ export const SubMenuItem: React.FunctionComponent<SubMenuItemProps> = ({
|
|||
path,
|
||||
});
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const className =
|
||||
|
@ -70,8 +68,9 @@ export const SubMenuItem: React.FunctionComponent<SubMenuItemProps> = ({
|
|||
<button
|
||||
onClick={onClick}
|
||||
className={`sidebar-menu-item__link ${item.classNames}`}
|
||||
aria-haspopup="true"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={isOpen ? 'true' : 'false'}
|
||||
type="button"
|
||||
>
|
||||
{item.iconName && (
|
||||
<Icon name={item.iconName} className="icon--menuitem" />
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PageExplorerMenuItem should render with the minimum required props 1`] = `
|
||||
<li
|
||||
className="sidebar-menu-item sidebar-page-explorer-item"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
className="sidebar-menu-item__link"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<Icon
|
||||
className="icon--menuitem"
|
||||
name="folder-open-inverse"
|
||||
/>
|
||||
<span
|
||||
className="menuitem-label"
|
||||
/>
|
||||
<Icon
|
||||
className="sidebar-sub-menu-trigger-icon"
|
||||
name="arrow-right"
|
||||
/>
|
||||
</button>
|
||||
<div>
|
||||
<SidebarPanel
|
||||
depth={2}
|
||||
isOpen={false}
|
||||
isVisible={false}
|
||||
widthPx={485}
|
||||
>
|
||||
<Provider
|
||||
store={
|
||||
Object {
|
||||
"@@observable": [Function],
|
||||
"dispatch": [Function],
|
||||
"getState": [Function],
|
||||
"replaceReducer": [Function],
|
||||
"subscribe": [Function],
|
||||
}
|
||||
}
|
||||
>
|
||||
<Connect(PageExplorer)
|
||||
isVisible={false}
|
||||
/>
|
||||
</Provider>
|
||||
</SidebarPanel>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
|
@ -0,0 +1,40 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SubMenuItem should render with the minimum required props 1`] = `
|
||||
<li
|
||||
className="sidebar-menu-item sidebar-sub-menu-item sidebar-menu-item--active"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
className="sidebar-menu-item__link "
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
className="menuitem-label"
|
||||
/>
|
||||
<Icon
|
||||
className="sidebar-sub-menu-trigger-icon"
|
||||
name="arrow-right"
|
||||
/>
|
||||
</button>
|
||||
<SidebarPanel
|
||||
depth={2}
|
||||
isOpen={false}
|
||||
isVisible={false}
|
||||
>
|
||||
<div
|
||||
className="sidebar-sub-menu-panel"
|
||||
>
|
||||
<h2
|
||||
className=""
|
||||
id="wagtail-sidebar-submenu-reports-title"
|
||||
/>
|
||||
<ul
|
||||
aria-labelledby="wagtail-sidebar-submenu-reports-title"
|
||||
/>
|
||||
</div>
|
||||
</SidebarPanel>
|
||||
</li>
|
||||
`;
|
|
@ -0,0 +1,45 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { Menu } from './MainMenu';
|
||||
|
||||
describe('Menu', () => {
|
||||
const strings = {};
|
||||
const user = { avatarUrl: 'https://gravatar/profile' };
|
||||
|
||||
it('should render with the minimum required props', () => {
|
||||
const wrapper = shallow(
|
||||
<Menu
|
||||
accountMenuItems={[]}
|
||||
menuItems={[]}
|
||||
strings={strings}
|
||||
user={user}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should toggle the sidebar footer (account) when clicked', () => {
|
||||
const wrapper = shallow(
|
||||
<Menu
|
||||
accountMenuItems={[]}
|
||||
menuItems={[]}
|
||||
strings={strings}
|
||||
user={user}
|
||||
/>,
|
||||
);
|
||||
|
||||
// default is closed
|
||||
expect(wrapper.find('.sidebar-footer__account').prop('aria-expanded')).toBe(
|
||||
'false',
|
||||
);
|
||||
expect(wrapper.find('.sidebar-footer--open')).toHaveLength(0);
|
||||
|
||||
wrapper.find('.sidebar-footer__account').simulate('click');
|
||||
|
||||
expect(wrapper.find('.sidebar-footer__account').prop('aria-expanded')).toBe(
|
||||
'true',
|
||||
);
|
||||
expect(wrapper.find('.sidebar-footer--open')).toHaveLength(1);
|
||||
});
|
||||
});
|
|
@ -170,9 +170,7 @@ export const Menu: React.FunctionComponent<MenuProps> = ({
|
|||
}
|
||||
}, [expandingOrCollapsing]);
|
||||
|
||||
const onClickAccountSettings = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const onClickAccountSettings = () => {
|
||||
if (accountSettingsOpen) {
|
||||
dispatch({
|
||||
type: 'set-navigation-path',
|
||||
|
@ -206,10 +204,11 @@ export const Menu: React.FunctionComponent<MenuProps> = ({
|
|||
<button
|
||||
className="sidebar-footer__account"
|
||||
title={strings.EDIT_YOUR_ACCOUNT}
|
||||
aria-label={strings.EDIT_YOUR_ACCOUNT}
|
||||
onClick={onClickAccountSettings}
|
||||
aria-haspopup="true"
|
||||
aria-label={strings.EDIT_YOUR_ACCOUNT}
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={accountSettingsOpen ? 'true' : 'false'}
|
||||
type="button"
|
||||
>
|
||||
<div className="avatar square avatar-on-dark">
|
||||
<img src={user.avatarUrl} alt="" />
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Menu should render with the minimum required props 1`] = `
|
||||
<Fragment>
|
||||
<nav
|
||||
className="sidebar-main-menu"
|
||||
>
|
||||
<ul
|
||||
className="sidebar-main-menu__list"
|
||||
/>
|
||||
</nav>
|
||||
<div
|
||||
className="sidebar-footer"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="menu"
|
||||
className="sidebar-footer__account"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
className="avatar square avatar-on-dark"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
src="https://gravatar/profile"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="sidebar-footer__account-toggle"
|
||||
>
|
||||
<div
|
||||
className="sidebar-footer__account-label"
|
||||
/>
|
||||
<Icon
|
||||
className="sidebar-footer__account-icon"
|
||||
name="arrow-up"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
<ul />
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
|
@ -18,7 +18,9 @@ describe('Homepage', () => {
|
|||
});
|
||||
|
||||
it('axe page explorer', async () => {
|
||||
const trigger = await page.$('[aria-haspopup="dialog"]');
|
||||
const trigger = await page.$(
|
||||
'.sidebar-page-explorer-item [aria-haspopup="menu"]',
|
||||
);
|
||||
await trigger.click();
|
||||
await expect(page).toPassAxeTests({
|
||||
include: '.sidebar-main-menu',
|
||||
|
@ -26,7 +28,9 @@ describe('Homepage', () => {
|
|||
});
|
||||
|
||||
it('axe sidebar sub-menu', async () => {
|
||||
const trigger = await page.$('[aria-haspopup="true"]');
|
||||
const trigger = await page.$(
|
||||
'.sidebar-sub-menu-item [aria-haspopup="menu"]',
|
||||
);
|
||||
await trigger.click();
|
||||
await expect(page).toPassAxeTests({
|
||||
include: '.sidebar-main-menu',
|
||||
|
|
|
@ -53,6 +53,9 @@ The panel types `StreamFieldPanel`, `RichTextFieldPanel`, `ImageChooserPanel`, `
|
|||
* Improve the contrast of the “Remember me” checkbox against the login page’s background (Steven Steinwand)
|
||||
* Group permission rows with custom permissions no longer have extra padding (Steven Steinwand)
|
||||
* Make sure the focus outline of checkboxes is fully around the outer border (Steven Steinwand)
|
||||
* Consistently set `aria-haspopup="menu"` for all sidebar menu items that have sub-menus (LB (Ben Johnston))
|
||||
* Make sure `aria-expanded` is always explicitly set as a string in sidebar (LB (Ben Johnston))
|
||||
* Use a button element instead of a link for page explorer menu item, for the correct semantics and behavior (LB (Ben Johnston))
|
||||
|
||||
|
||||
## Upgrade considerations
|
||||
|
|
Ładowanie…
Reference in New Issue