mirror of
https://github.com/wassname/talk.git
synced 2026-08-02 13:10:23 +08:00
[CORL-720] Integratejest-axe (#2741)
* feat: axe checks for tests * test: add another axe check * fix: tests
This commit is contained in:
@@ -31,7 +31,9 @@ it("renders missing confirm token", async () => {
|
||||
replaceHistoryLocation("http://localhost/account/email/confirm");
|
||||
const { root } = await createTestRenderer();
|
||||
await waitForElement(() => within(root).getByTestID("invalid-link"));
|
||||
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("renders form", async () => {
|
||||
@@ -57,6 +59,7 @@ it("renders form", async () => {
|
||||
);
|
||||
});
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
restMock.verify();
|
||||
});
|
||||
|
||||
@@ -98,6 +101,7 @@ it("renders error from server", async () => {
|
||||
);
|
||||
});
|
||||
restMock.verify();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ it("renders missing reset token", async () => {
|
||||
const { root } = await createTestRenderer();
|
||||
await waitForElement(() => within(root).getByTestID("invalid-link"));
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("renders form", async () => {
|
||||
@@ -57,6 +58,7 @@ it("renders form", async () => {
|
||||
);
|
||||
});
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
restMock.verify();
|
||||
});
|
||||
|
||||
@@ -98,6 +100,7 @@ it("renders error from server", async () => {
|
||||
);
|
||||
});
|
||||
restMock.verify();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ it("renders missing confirm token", async () => {
|
||||
const { root } = await createTestRenderer();
|
||||
await waitForElement(() => within(root).getByTestID("invalid-link"));
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("renders form", async () => {
|
||||
@@ -53,6 +54,7 @@ it("renders form", async () => {
|
||||
await waitForElement(() => within(root).getByTestID("unsubscribe-form"));
|
||||
});
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
restMock.verify();
|
||||
});
|
||||
|
||||
@@ -93,6 +95,7 @@ it("renders error from server", async () => {
|
||||
);
|
||||
});
|
||||
restMock.verify();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ it("renders addEmailAddress view", async () => {
|
||||
expect(toJSON(root)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
|
||||
@@ -60,6 +60,7 @@ async function createTestRenderer(
|
||||
it("renders createPassword view", async () => {
|
||||
const { root } = await createTestRenderer();
|
||||
expect(toJSON(root)).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
|
||||
@@ -58,6 +58,7 @@ async function createTestRenderer(
|
||||
it("renders createUsername view", async () => {
|
||||
const { root } = await createTestRenderer();
|
||||
expect(toJSON(root)).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
|
||||
@@ -64,6 +64,7 @@ afterEach(async () => {
|
||||
it("renders forgot password view", async () => {
|
||||
const { testRenderer } = await createTestRenderer();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
|
||||
@@ -58,6 +58,7 @@ async function createTestRenderer(
|
||||
it("renders sign in view", async () => {
|
||||
const { testRenderer } = await createTestRenderer();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("renders sign in view with error", async () => {
|
||||
|
||||
@@ -53,6 +53,7 @@ async function createTestRenderer(customResolver: any = {}) {
|
||||
it("renders sign up form", async () => {
|
||||
const { testRenderer } = await createTestRenderer();
|
||||
expect(testRenderer.toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("shows error when submitting empty form", async () => {
|
||||
|
||||
@@ -48,7 +48,7 @@ export function denormalizeComments(commentList: Array<Fixture<GQLComment>>) {
|
||||
}
|
||||
|
||||
export function denormalizeStory(story: Fixture<GQLStory>) {
|
||||
const commentNodes =
|
||||
const commentEdges =
|
||||
(story.comments &&
|
||||
story.comments.edges &&
|
||||
story.comments.edges.map((edge: any) => ({
|
||||
@@ -61,20 +61,21 @@ export function denormalizeStory(story: Fixture<GQLStory>) {
|
||||
};
|
||||
if (commentsPageInfo.endCursor === undefined) {
|
||||
commentsPageInfo.endCursor =
|
||||
commentNodes.length > 0
|
||||
? commentNodes[commentNodes.length - 1].node.createdAt
|
||||
commentEdges.length > 0
|
||||
? commentEdges[commentEdges.length - 1].node.createdAt
|
||||
: null;
|
||||
}
|
||||
|
||||
const featuredCommentsCount = commentNodes.filter(
|
||||
n => n.tags && n.tags.some((t: GQLTag) => t.code === GQLTAG.FEATURED)
|
||||
const featuredCommentsCount = commentEdges.filter(
|
||||
e =>
|
||||
e.node.tags && e.node.tags.some((t: GQLTag) => t.code === GQLTAG.FEATURED)
|
||||
).length;
|
||||
return createFixture<GQLStory>({
|
||||
...story,
|
||||
comments: { edges: commentNodes, pageInfo: commentsPageInfo },
|
||||
comments: { edges: commentEdges, pageInfo: commentsPageInfo },
|
||||
commentCounts: {
|
||||
...story.commentCounts,
|
||||
totalPublished: commentNodes.length,
|
||||
totalPublished: commentEdges.length,
|
||||
tags: {
|
||||
...(story.commentCounts && story.commentCounts.tags),
|
||||
FEATURED: featuredCommentsCount,
|
||||
|
||||
@@ -46,3 +46,4 @@ export {
|
||||
default as overwriteQueryResolver,
|
||||
createQueryResolverOverwrite,
|
||||
} from "./overwriteQueryResolver";
|
||||
export { default as toHTML } from "./toHTML";
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
import { stripIndent } from "common-tags";
|
||||
import prettier from "prettier";
|
||||
import { ReactTestInstance } from "react-test-renderer";
|
||||
|
||||
import toJSON, { ReactTestRendererNode } from "./toJSON";
|
||||
|
||||
function convertPropertyToString(prop: string, value: any): string {
|
||||
let propOut = prop;
|
||||
let valueOut = "";
|
||||
|
||||
if (propOut === "dangerouslySetInnerHTML") {
|
||||
return "";
|
||||
}
|
||||
|
||||
// React uses `htmlFor` instead of `for` because of js restrictions.
|
||||
if (propOut === "htmlFor") {
|
||||
propOut = "for";
|
||||
}
|
||||
|
||||
switch (typeof value) {
|
||||
case "function":
|
||||
valueOut = "[Function]";
|
||||
break;
|
||||
case "string":
|
||||
valueOut = value;
|
||||
break;
|
||||
case "undefined":
|
||||
valueOut = propOut;
|
||||
return "";
|
||||
case "boolean":
|
||||
// Usually true means the property has been set without a value
|
||||
// and false the property is not set.
|
||||
// Exception: aria-labels need to be set to "true" / "false".
|
||||
if (!prop.startsWith("aria-")) {
|
||||
return value ? propOut : "";
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
valueOut = JSON.stringify(value);
|
||||
}
|
||||
valueOut = valueOut.replace('"', """);
|
||||
return `${propOut}="${valueOut}"`;
|
||||
}
|
||||
|
||||
function convertJSONToHTML(
|
||||
node: ReactTestRendererNode | ReactTestRendererNode[]
|
||||
): string {
|
||||
if (typeof node === "string") {
|
||||
return node;
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
return node.map(c => convertJSONToHTML(c)).join("\n");
|
||||
}
|
||||
|
||||
const props = Object.keys(node.props)
|
||||
.map(k => convertPropertyToString(k, node.props[k]))
|
||||
.join(" ");
|
||||
|
||||
let innerHTML = "";
|
||||
if ("dangerouslySetInnerHTML" in node.props) {
|
||||
innerHTML = node.props.dangerouslySetInnerHTML.__html;
|
||||
} else if (node.children) {
|
||||
innerHTML = convertJSONToHTML(node.children);
|
||||
}
|
||||
|
||||
if (innerHTML === "") {
|
||||
return `<${node.type} ${props} />`;
|
||||
}
|
||||
return stripIndent`
|
||||
<${node.type} ${props}>
|
||||
${innerHTML}
|
||||
</${node.type}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a ReactTestInstance into its HTML representation.
|
||||
*/
|
||||
export default function toHTML(
|
||||
inst: ReactTestInstance,
|
||||
options: { pretty?: boolean } = {}
|
||||
) {
|
||||
const result = toJSON(inst);
|
||||
if (result === null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const output = convertJSONToHTML(result);
|
||||
return options.pretty ? prettier.format(output, { parser: "html" }) : output;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ReactTestInstance } from "react-test-renderer";
|
||||
|
||||
interface ReactTestRendererJSON {
|
||||
export interface ReactTestRendererJSON {
|
||||
type: string;
|
||||
props: { [propName: string]: any };
|
||||
children: null | ReactTestRendererNode[];
|
||||
$$typeof?: symbol; // Optional because we add it with defineProperty().
|
||||
}
|
||||
type ReactTestRendererNode = ReactTestRendererJSON | string;
|
||||
export type ReactTestRendererNode = ReactTestRendererJSON | string;
|
||||
|
||||
export function toJSONRecursive(
|
||||
inst: ReactTestInstance
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { axe } from "jest-axe";
|
||||
import { ReactTestInstance } from "react-test-renderer";
|
||||
|
||||
import { getByID, queryByID } from "./byID";
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
queryByType,
|
||||
queryParentByType,
|
||||
} from "./byType";
|
||||
import toHTML from "./toHTML";
|
||||
import toJSON from "./toJSON";
|
||||
|
||||
type Func0<R> = () => R;
|
||||
@@ -68,6 +70,17 @@ export default function within(container: ReactTestInstance) {
|
||||
queryByType: applyContainer(container, queryByType),
|
||||
queryParentByType: applyContainer(container, queryParentByType),
|
||||
queryAllByType: applyContainer(container, queryAllByType),
|
||||
toJSON: () => toJSON(container),
|
||||
toJSON: applyContainer(container, toJSON),
|
||||
toHTML: applyContainer(container, toHTML),
|
||||
/**
|
||||
* Check for some accessibility violations
|
||||
*
|
||||
* Example use:
|
||||
* `expect(await within(container).axe()).toHaveNoViolations();`
|
||||
*/
|
||||
axe: () => axe(toHTML(container)),
|
||||
/** Output the html representation of the container */
|
||||
// eslint-disable-next-line no-console
|
||||
debug: () => console.log(toHTML(container, { pretty: true })),
|
||||
};
|
||||
}
|
||||
|
||||
+70
-1
@@ -253,6 +253,75 @@ exports[`renders comment stream 1`] = `
|
||||
className="TabBar-root TabBar-secondary coral coral-tabBarSecondary coral-tabBarComments StreamContainer-tabBarRoot"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
className="StreamContainer-featuredCommentsTabContainer"
|
||||
>
|
||||
<li
|
||||
className="Tab-root"
|
||||
id="tab-FEATURED_COMMENTS"
|
||||
role="presentation"
|
||||
>
|
||||
<button
|
||||
aria-controls="tabPane-FEATURED_COMMENTS"
|
||||
aria-selected={true}
|
||||
className="BaseButton-root Tab-button Tab-secondary StreamContainer-featuredCommentsTabButton Tab-active StreamContainer-fixedTab coral coral-tabBarSecondary-tab coral-tabBarComments-featured StreamContainer-featuredCommentsTab"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-alignCenter gutter Flex-spacing-1"
|
||||
>
|
||||
<span>
|
||||
Featured
|
||||
</span>
|
||||
<span
|
||||
className="Counter-root Counter-colorPrimary Counter-sizeSmall coral coral-counter"
|
||||
data-testid="comments-featuredCount"
|
||||
>
|
||||
<span
|
||||
className="Counter-text"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
<div
|
||||
className="Popover-root Tooltip-root StreamContainer-featuredCommentsInfo coral coral-tabBarComments-featuredTooltip"
|
||||
>
|
||||
<button
|
||||
aria-label="Toggle featured comments tooltip"
|
||||
className="BaseButton-root TooltipButton-button"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
aria-hidden="true"
|
||||
className="Icon-root Icon-sm Icon-colorPrimary"
|
||||
>
|
||||
info
|
||||
</i>
|
||||
</button>
|
||||
<div
|
||||
aria-hidden={true}
|
||||
aria-labelledby="comments-featuredCommentPopover-ariainfo"
|
||||
id="comments-featuredCommentPopover"
|
||||
role="dialog"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
className="Tab-root"
|
||||
id="tab-ALL_COMMENTS"
|
||||
@@ -261,7 +330,7 @@ exports[`renders comment stream 1`] = `
|
||||
<button
|
||||
aria-controls="tabPane-ALL_COMMENTS"
|
||||
aria-selected={false}
|
||||
className="BaseButton-root Tab-button Tab-secondary coral coral-tabBarSecondary-tab coral-tabBarComments-allComments"
|
||||
className="BaseButton-root Tab-button Tab-secondary StreamContainer-fixedTab coral coral-tabBarSecondary-tab coral-tabBarComments-allComments"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
|
||||
@@ -53,4 +53,5 @@ it("renders comment stream", async () => {
|
||||
within(testRenderer.root).getByTestID("comments-featuredComments-log")
|
||||
);
|
||||
expect(within(testRenderer.root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
@@ -93,6 +93,7 @@ it("renders permalink view", async () => {
|
||||
within(testRenderer.root).getByTestID("current-tab-pane")
|
||||
);
|
||||
expect(within(tabPane).toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("show all comments", async () => {
|
||||
|
||||
@@ -125,6 +125,8 @@ it("post a reply", async () => {
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await within(form).axe()).toHaveNoViolations();
|
||||
|
||||
// Write reply .
|
||||
act(() => rte.props.onChange({ html: "<b>Hello world!</b>" }));
|
||||
act(() => {
|
||||
|
||||
@@ -100,6 +100,7 @@ it("edit a comment", async () => {
|
||||
.props.onClick()
|
||||
);
|
||||
expect(within(comment).toJSON()).toMatchSnapshot("edit form");
|
||||
expect(await within(comment).axe()).toHaveNoViolations();
|
||||
|
||||
act(() =>
|
||||
testRenderer.root
|
||||
|
||||
@@ -119,6 +119,8 @@ it("loads more comments", async () => {
|
||||
within(testRenderer.root).getByTestID("comments-allComments-log")
|
||||
);
|
||||
|
||||
expect(await within(streamLog).axe()).toHaveNoViolations();
|
||||
|
||||
// Get amount of comments before.
|
||||
const commentsBefore = within(streamLog).getAllByTestID(/^comment-/).length;
|
||||
|
||||
|
||||
@@ -42,4 +42,5 @@ it("renders reply list", async () => {
|
||||
);
|
||||
// Wait for loading.
|
||||
expect(within(commentReplyList).toJSON()).toMatchSnapshot();
|
||||
expect(await within(commentReplyList).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
@@ -45,4 +45,5 @@ it("renders comment stream", async () => {
|
||||
within(testRenderer.root).getByTestID("comments-allComments-log")
|
||||
);
|
||||
expect(within(testRenderer.root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import sinon from "sinon";
|
||||
|
||||
import { act, wait, waitForElement, within } from "coral-framework/testHelpers";
|
||||
import { act, waitForElement, within } from "coral-framework/testHelpers";
|
||||
|
||||
import { moderators, settings, stories } from "../fixtures";
|
||||
import create from "./create";
|
||||
@@ -42,11 +42,7 @@ async function createTestRenderer(
|
||||
}
|
||||
|
||||
it("renders configure", async () => {
|
||||
const { tabPane } = await createTestRenderer();
|
||||
|
||||
await act(async () => {
|
||||
await wait(() => {
|
||||
expect(within(tabPane).toJSON()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
const { tabPane, testRenderer } = await createTestRenderer();
|
||||
expect(within(tabPane).toJSON()).toMatchSnapshot();
|
||||
expect(await within(testRenderer.root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
@@ -67,6 +67,7 @@ it("renders the empty settings pane", async () => {
|
||||
testRenderer: { root },
|
||||
} = await createTestRenderer();
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
expect(await within(root).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("doesn't show the change password pane when local auth is disabled", async () => {
|
||||
@@ -112,6 +113,7 @@ it("render password change form", async () => {
|
||||
const newPassword = await waitForElement(() =>
|
||||
within(form).getByID("newPassword", { exact: false })
|
||||
);
|
||||
expect(await within(changePassword).axe()).toHaveNoViolations();
|
||||
|
||||
// Submit an empty form.
|
||||
act(() => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
within,
|
||||
} from "coral-framework/testHelpers";
|
||||
|
||||
import { baseUser, settings, stories } from "../fixtures";
|
||||
import { settings, stories, userWithEmail } from "../fixtures";
|
||||
import create from "./create";
|
||||
|
||||
const story = stories[0];
|
||||
@@ -23,7 +23,7 @@ async function createTestRenderer(
|
||||
createResolversStub<GQLResolver>({
|
||||
Query: {
|
||||
settings: () => settings,
|
||||
viewer: () => baseUser,
|
||||
viewer: () => userWithEmail,
|
||||
stream: () => story,
|
||||
},
|
||||
}),
|
||||
@@ -49,7 +49,7 @@ describe("change email form", () => {
|
||||
const setup = await createTestRenderer({
|
||||
resolvers: createResolversStub<GQLResolver>({
|
||||
Query: {
|
||||
viewer: () => baseUser,
|
||||
viewer: () => userWithEmail,
|
||||
},
|
||||
Mutation: {
|
||||
updateEmail: ({ variables }) => {
|
||||
@@ -58,7 +58,7 @@ describe("change email form", () => {
|
||||
});
|
||||
return {
|
||||
user: {
|
||||
...baseUser,
|
||||
...userWithEmail,
|
||||
email: "updated_email@test.com",
|
||||
},
|
||||
};
|
||||
@@ -77,6 +77,7 @@ describe("change email form", () => {
|
||||
act(() => {
|
||||
editButton.props.onClick();
|
||||
});
|
||||
expect(await within(changeEmail).axe()).toHaveNoViolations();
|
||||
const form = within(changeEmail).getByType("form");
|
||||
act(() => {
|
||||
form.props.onSubmit();
|
||||
|
||||
@@ -76,7 +76,9 @@ describe("with recently changed username", () => {
|
||||
const form = within(changeUsername).queryByType("form");
|
||||
const message = within(changeUsername).queryByText(
|
||||
"Your username has been changed in the last 14 days",
|
||||
{ exact: false }
|
||||
{
|
||||
exact: false,
|
||||
}
|
||||
);
|
||||
expect(form).toBeNull();
|
||||
expect(message).toBeTruthy();
|
||||
@@ -106,10 +108,13 @@ describe("with new username", () => {
|
||||
act(() => {
|
||||
editButton.props.onClick();
|
||||
});
|
||||
expect(await within(changeUsername).axe()).toHaveNoViolations();
|
||||
within(changeUsername).getByType("form");
|
||||
const message = within(changeUsername).queryByText(
|
||||
"Your username has been changed in the last 14 days",
|
||||
{ exact: false }
|
||||
{
|
||||
exact: false,
|
||||
}
|
||||
);
|
||||
expect(message).toBeNull();
|
||||
});
|
||||
|
||||
@@ -109,6 +109,8 @@ describe("delete account steps", () => {
|
||||
nextButton.props.onClick();
|
||||
});
|
||||
}
|
||||
|
||||
expect(await within(modal).axe()).toHaveNoViolations();
|
||||
const form = within(modal).getByType("form");
|
||||
const confirm = within(modal).getByTestID("confirm-page-confirmation");
|
||||
const password = within(modal).getByTestID("confirm-page-password");
|
||||
|
||||
@@ -87,6 +87,7 @@ it("renders profile", async () => {
|
||||
within(testRenderer.root).getByTestID("profile-commentHistory")
|
||||
);
|
||||
expect(within(commentHistory).toJSON()).toMatchSnapshot();
|
||||
expect(await within(commentHistory).axe()).toHaveNoViolations();
|
||||
});
|
||||
|
||||
it("loads more comments", async () => {
|
||||
|
||||
@@ -73,6 +73,7 @@ it("render notifications form", async () => {
|
||||
const container = await waitForElement(() =>
|
||||
within(testRenderer.root).getByTestID("profile-account-notifications")
|
||||
);
|
||||
expect(await within(container).axe()).toHaveNoViolations();
|
||||
const form = within(container).getByType("form");
|
||||
|
||||
// Get the form fields.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { toHaveNoViolations } from "jest-axe";
|
||||
|
||||
import expectAndFail from "./expectAndFail";
|
||||
|
||||
// Automatically unmock console.
|
||||
@@ -17,3 +19,5 @@ process.on("unhandledRejection", err => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
expect.extend(toHaveNoViolations);
|
||||
|
||||
@@ -43,7 +43,7 @@ const Icon: FunctionComponent<Props> = props => {
|
||||
return (
|
||||
<i
|
||||
className={rootClassName}
|
||||
aria-hidden="true"
|
||||
aria-hidden={rest["aria-label"] ? "false" : "true"}
|
||||
{...rest}
|
||||
ref={forwardRef}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user