Spike AXE A11Y testing in Cypress (#9111)

* Spike AXE A11Y testing in Cypress

* Fix NewRoomIntro breaking html/aria list rules

* Fix HeaderButtons breaking aria role semantics rules

* missing type

* Switch left panel from aside to nav and include space panel

* Give the page a main heading of the room name when viewing a room

* Use header landmark on RoomHeader

* Improve aria attributes on composer when autocomplete is closed

* Fix aria-owns on RoomHeader

* Give Spinner an aria role

* Give server picker help button an aria label

* Improve auth aria attributes and semantics

* Improve heading semantics in use case selection screen

* Fix autocomplete attribute to be valid

* Fix heading semantics on login page

* Improve Cypress axe testing

* Add axe tests

* Stop synapse after the timeline tests

* Await spinners to fade before percy snapshotting timeline tests

* Improve naming of plugin

* Update snapshots

* Fix accidental heading change

* Fix double synapse stoppage

* Fix Cypress timeline avatar assertions to be DPI agnostic

* Fix aria attributes on date separators

* delint

* Update snapshots

* Revert style change

* Skip redundant call
This commit is contained in:
Michael Telatynski 2022-08-01 08:31:14 +01:00 committed by GitHub
parent 05cc5f62dd
commit d5db131eef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 244 additions and 83 deletions

View file

@ -45,6 +45,8 @@ import { NotificationStateEvents } from '../../../stores/notifications/Notificat
import RoomContext from "../../../contexts/RoomContext";
import RoomLiveShareWarning from '../beacon/RoomLiveShareWarning';
import { BetaPill } from "../beta/BetaCard";
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
export interface ISearchInfo {
searchTerm: string;
@ -71,6 +73,7 @@ interface IProps {
interface IState {
contextMenuPosition?: DOMRect;
rightPanelOpen: boolean;
}
export default class RoomHeader extends React.Component<IProps, IState> {
@ -89,23 +92,29 @@ export default class RoomHeader extends React.Component<IProps, IState> {
super(props, context);
const notiStore = RoomNotificationStateStore.instance.getRoomState(props.room);
notiStore.on(NotificationStateEvents.Update, this.onNotificationUpdate);
this.state = {};
this.state = {
rightPanelOpen: RightPanelStore.instance.isOpen,
};
}
public componentDidMount() {
const cli = MatrixClientPeg.get();
cli.on(RoomStateEvent.Events, this.onRoomStateEvents);
RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate);
}
public componentWillUnmount() {
const cli = MatrixClientPeg.get();
if (cli) {
cli.removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
}
cli?.removeListener(RoomStateEvent.Events, this.onRoomStateEvents);
const notiStore = RoomNotificationStateStore.instance.getRoomState(this.props.room);
notiStore.removeListener(NotificationStateEvents.Update, this.onNotificationUpdate);
RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate);
}
private onRightPanelStoreUpdate = () => {
this.setState({ rightPanelOpen: RightPanelStore.instance.isOpen });
};
private onRoomStateEvents = (event: MatrixEvent) => {
if (!this.props.room || event.getRoomId() !== this.props.room.roomId) {
return;
@ -230,7 +239,9 @@ export default class RoomHeader extends React.Component<IProps, IState> {
const roomName = <RoomName room={this.props.room}>
{ (name) => {
const roomName = name || oobName;
return <div dir="auto" className={textClasses} title={roomName}>{ roomName }</div>;
return <div dir="auto" className={textClasses} title={roomName} role="heading" aria-level={1}>
{ roomName }
</div>;
} }
</RoomName>;
@ -311,8 +322,11 @@ export default class RoomHeader extends React.Component<IProps, IState> {
) : null;
return (
<div className="mx_RoomHeader light-panel">
<div className="mx_RoomHeader_wrapper" aria-owns="mx_RightPanel">
<header className="mx_RoomHeader light-panel">
<div
className="mx_RoomHeader_wrapper"
aria-owns={this.state.rightPanelOpen ? "mx_RightPanel" : undefined}
>
<div className="mx_RoomHeader_avatar">{ roomAvatar }</div>
<div className="mx_RoomHeader_e2eIcon">{ e2eIcon }</div>
{ name }
@ -322,7 +336,7 @@ export default class RoomHeader extends React.Component<IProps, IState> {
{ buttons }
</div>
<RoomLiveShareWarning roomId={this.props.room.roomId} />
</div>
</header>
);
}
}