Ensure tooltip contents is linked via aria to the target element (#10729)

* Ensure tooltip contents is linked via aria to the target element

* Iterate

* Fix tests

* Fix tests

* Update snapshot

* Fix missing aria labels for more tooltips

* Iterate

* Update snapshots
This commit is contained in:
Michael Telatynski 2023-05-05 09:26:11 +01:00 committed by GitHub
parent 8e962f6897
commit 99ac9e5029
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 133 additions and 43 deletions

View file

@ -117,6 +117,12 @@ describe("<Pill>", () => {
jest.spyOn(dis, "dispatch");
pillParentClickHandler = jest.fn();
jest.spyOn(global.Math, "random").mockReturnValue(0.123456);
});
afterEach(() => {
jest.spyOn(global.Math, "random").mockRestore();
});
describe("when rendering a pill for a room", () => {

View file

@ -11,6 +11,7 @@ exports[`<Pill> should not render an avatar or link when called with inMessage =
<div>
<bdi>
<span
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_RoomPill"
>
<span
@ -29,6 +30,7 @@ exports[`<Pill> should render the expected pill for @room 1`] = `
<div>
<bdi>
<span
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_AtRoomPill"
>
<span
@ -68,6 +70,7 @@ exports[`<Pill> should render the expected pill for a known user not in the room
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_UserPill"
href="https://matrix.to/#/@user2:example.com"
>
@ -108,6 +111,7 @@ exports[`<Pill> should render the expected pill for a message in another room 1`
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/$123-456"
>
@ -148,6 +152,7 @@ exports[`<Pill> should render the expected pill for a message in the same room 1
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/$123-456"
>
@ -188,6 +193,7 @@ exports[`<Pill> should render the expected pill for a room alias 1`] = `
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_RoomPill"
href="https://matrix.to/#/#room1:example.com"
>
@ -228,6 +234,7 @@ exports[`<Pill> should render the expected pill for a space 1`] = `
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_RoomPill"
href="https://matrix.to/#/!space1:example.com"
>
@ -268,6 +275,7 @@ exports[`<Pill> should render the expected pill for an uknown user not in the ro
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_UserPill"
href="https://matrix.to/#/@user3:example.com"
>
@ -290,6 +298,7 @@ exports[`<Pill> when rendering a pill for a room should render the expected pill
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_RoomPill"
href="https://matrix.to/#/!room1:example.com"
>
@ -330,6 +339,7 @@ exports[`<Pill> when rendering a pill for a user in the room should render as ex
<div>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_UserPill"
href="https://matrix.to/#/@user1:example.com"
>

View file

@ -3,6 +3,7 @@
exports[`<TooltipTarget /> displays Bottom aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; top: 6px; transform: translate(max(10px, min(calc(0px - 50%), calc(100vw - 100% - 10px))));"
>
@ -16,6 +17,7 @@ exports[`<TooltipTarget /> displays Bottom aligned tooltip on mouseover 1`] = `
exports[`<TooltipTarget /> displays InnerBottom aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; top: -50px; transform: translate(max(10px, min(calc(0px - 50%), calc(100vw - 100% - 10px))));"
>
@ -29,6 +31,7 @@ exports[`<TooltipTarget /> displays InnerBottom aligned tooltip on mouseover 1`]
exports[`<TooltipTarget /> displays Left aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; right: 1030px; top: 0px; transform: translateY(-50%);"
>
@ -42,6 +45,7 @@ exports[`<TooltipTarget /> displays Left aligned tooltip on mouseover 1`] = `
exports[`<TooltipTarget /> displays Natural aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; left: 6px; top: 0px; transform: translateY(-50%);"
>
@ -55,6 +59,7 @@ exports[`<TooltipTarget /> displays Natural aligned tooltip on mouseover 1`] = `
exports[`<TooltipTarget /> displays Right aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; left: 6px; top: 0px; transform: translateY(-50%);"
>
@ -68,6 +73,7 @@ exports[`<TooltipTarget /> displays Right aligned tooltip on mouseover 1`] = `
exports[`<TooltipTarget /> displays Top aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; top: -6px; transform: translate(max(10px, min(calc(0px - 50%), calc(100vw - 100% - 10px))), -100%);"
>
@ -81,6 +87,7 @@ exports[`<TooltipTarget /> displays Top aligned tooltip on mouseover 1`] = `
exports[`<TooltipTarget /> displays TopRight aligned tooltip on mouseover 1`] = `
<div
class="mx_Tooltip test tooltipClassName mx_Tooltip_visible"
id="test id"
role="tooltip"
style="display: block; top: -6px; right: 1024px; transform: translateY(-100%);"
>

View file

@ -60,6 +60,7 @@ const mkFormattedMessage = (body: string, formattedBody: string): MatrixEvent =>
describe("<TextualBody />", () => {
afterEach(() => {
jest.spyOn(MatrixClientPeg, "get").mockRestore();
jest.spyOn(global.Math, "random").mockRestore();
});
const defaultRoom = mkStubRoom(room1Id, "test room", undefined);
@ -98,6 +99,7 @@ describe("<TextualBody />", () => {
if (eventId === defaultEvent.getId()) return defaultEvent;
return undefined;
});
jest.spyOn(global.Math, "random").mockReturnValue(0.123456);
});
const defaultProps = {
@ -197,7 +199,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Chat with <span><bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com"><img class="mx_BaseAvatar mx_BaseAvatar_image" src="mxc://avatar.url/image.png" style="width: 16px; height: 16px;" alt="" data-testid="avatar-img" aria-hidden="true"><span class="mx_Pill_text">Member</span></a></bdi></span>"`,
`"Chat with <span><bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com" aria-describedby="mx_Pill_0.123456"><img class="mx_BaseAvatar mx_BaseAvatar_image" src="mxc://avatar.url/image.png" style="width: 16px; height: 16px;" alt="" data-testid="avatar-img" aria-hidden="true"><span class="mx_Pill_text">Member</span></a></bdi></span>"`,
);
});
@ -215,7 +217,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Visit <span><bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com"><div class="mx_Pill_LinkIcon mx_BaseAvatar mx_BaseAvatar_image"></div><span class="mx_Pill_text">#room:example.com</span></a></bdi></span>"`,
`"Visit <span><bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com" aria-describedby="mx_Pill_0.123456"><div class="mx_Pill_LinkIcon mx_BaseAvatar mx_BaseAvatar_image"></div><span class="mx_Pill_text">#room:example.com</span></a></bdi></span>"`,
);
});

View file

@ -50,6 +50,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
<span>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_UserPill"
href="https://matrix.to/#/@user:example.com"
>
@ -85,6 +86,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for eve
<span>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com"
>
@ -122,6 +124,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for roo
<span>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_RoomPill"
href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com?via=example.com&via=bob.com"
>
@ -218,6 +221,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills get injected c
<span>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_UserPill"
href="https://matrix.to/#/@user:server"
>
@ -247,6 +251,7 @@ exports[`<TextualBody /> renders plain-text m.text correctly should pillify a pe
><a
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/%event_id%"
aria-describedby="mx_Pill_0.123456"
><img
class="mx_BaseAvatar mx_BaseAvatar_image"
src="mxc://avatar.url/image.png"
@ -268,6 +273,7 @@ exports[`<TextualBody /> renders plain-text m.text correctly should pillify a pe
><a
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room2:example.com/%event_id%"
aria-describedby="mx_Pill_0.123456"
><img
class="mx_BaseAvatar mx_BaseAvatar_image"
src="mxc://avatar.url/room.png"
@ -291,6 +297,7 @@ exports[`<TextualBody /> renders plain-text m.text correctly should pillify a pe
<span>
<bdi>
<a
aria-describedby="mx_Pill_0.123456"
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/!abc123"
>

View file

@ -322,7 +322,7 @@ describe("<UserInfo />", () => {
renderComponent({ room: mockRoom });
await act(flushPromises);
const userHeading = screen.getByRole("heading", { name: defaultUserId });
const userHeading = screen.getByRole("heading", { name: /@user:example.com/ });
// there should be a "normal" E2E padlock
expect(userHeading.getElementsByClassName("mx_E2EIcon_normal")).toHaveLength(1);
@ -333,7 +333,7 @@ describe("<UserInfo />", () => {
renderComponent({ room: mockRoom });
await act(flushPromises);
const userHeading = screen.getByRole("heading", { name: defaultUserId });
const userHeading = screen.getByRole("heading", { name: /@user:example.com/ });
// there should be a "verified" E2E padlock
expect(userHeading.getElementsByClassName("mx_E2EIcon_verified")).toHaveLength(1);
@ -368,7 +368,7 @@ describe("<UserInfoHeader />", () => {
it("renders an e2e icon in the header if e2eStatus prop is defined", () => {
renderComponent({ e2eStatus: E2EStatus.Normal });
const header = screen.getByRole("heading", { name: defaultUserId });
const header = screen.getByRole("heading");
expect(header.getElementsByClassName("mx_E2EIcon")).toHaveLength(1);
});

View file

@ -40,6 +40,7 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
/>
</span>
<div
aria-label="Not encrypted"
class="mx_TextWithTooltip_target mx_RoomSummaryCard_e2ee"
tabindex="0"
/>