Skip to content

Commit

Permalink
feat: improve screen reader a11y
Browse files Browse the repository at this point in the history
Signed-off-by: rare-magma <[email protected]>
  • Loading branch information
rare-magma committed Oct 12, 2023
1 parent 48be6ba commit edc5bf5
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 107 deletions.
2 changes: 1 addition & 1 deletion src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe("App", () => {
render(comp);
expect(screen.getAllByText("guitos")[0]).toBeInTheDocument();
expect(screen.getByRole("status")).toBeInTheDocument();
expect(screen.getByText(/v[0-9.]/)).toBeInTheDocument();
expect(screen.getByLabelText("open guitos changelog")).toBeInTheDocument();
expect(budgetsDB.config("name")).toBe("guitos");
expect(budgetsDB.config("storeName")).toBe("budgets");
expect(optionsDB.config("name")).toBe("guitos");
Expand Down
81 changes: 29 additions & 52 deletions src/components/CalculateButton/CalculateButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ describe("CalculateButton", () => {

it("renders initial state", () => {
expect(
screen.getByLabelText("select operations to change item value amount"),
screen.getByLabelText("select operation type to item value"),
).toBeInTheDocument();
});

it("opens popover when clicking the button", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);

Expand All @@ -40,20 +40,18 @@ describe("CalculateButton", () => {
}),
).toBeInTheDocument();

expect(
screen.getByLabelText("change item value amount"),
).toBeInTheDocument();
expect(screen.getByLabelText("addition")).toBeInTheDocument();

expect(
screen.getByRole("button", {
name: "accept change item value amount",
name: "apply change to item value",
}),
).toBeInTheDocument();
});

it("closes when clicking the button", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);

Expand All @@ -68,114 +66,93 @@ describe("CalculateButton", () => {

it("closes when pressing Escape key", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);

const button2 = screen.getByRole("button", {
name: "select type of operation on item value",
});

await userEvent.type(
screen.getByLabelText("change item value amount"),
"{Escape}",
);
await userEvent.type(screen.getByLabelText("addition"), "{Escape}");

expect(button2).not.toBeInTheDocument();
});

it("calls onCalculate when accepting change > 0", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);
const acceptButton = screen.getByRole("button", {
name: "accept change item value amount",
name: "apply change to item value",
});

await userEvent.type(
screen.getByLabelText("change item value amount"),
"123",
);
await userEvent.type(screen.getByLabelText("add"), "123");
await userEvent.click(acceptButton);

expect(onCalculate).toBeCalledWith(123, "add");
});

it("calls onCalculate when change > 0 and enter is pressed", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);
await userEvent.type(
screen.getByLabelText("change item value amount"),
"123",
);
await userEvent.type(
screen.getByLabelText("change item value amount"),
"{enter}",
);
await userEvent.type(screen.getByLabelText("addition"), "123");
await userEvent.type(screen.getByLabelText("addition"), "{enter}");

expect(onCalculate).toBeCalledWith(123, "add");
});

it("calls onCalculate with sub", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);
const acceptButton = screen.getByRole("button", {
name: "accept change item value amount",
name: "apply change to item value",
});

await userEvent.type(
screen.getByLabelText("change item value amount"),
"123",
);
await userEvent.type(screen.getByLabelText("add"), "123");

await userEvent.click(screen.getByLabelText("subtract to item value"));
await userEvent.click(screen.getByLabelText("subtraction"));
await userEvent.click(acceptButton);

expect(onCalculate).toBeCalledWith(123, "sub");
expect(onCalculate).toBeCalledWith(123, "subtract");
});

it("calls onCalculate with mul", async () => {
it("calls onCalculate with multiply", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);
const acceptButton = screen.getByRole("button", {
name: "accept change item value amount",
name: "apply change to item value",
});

await userEvent.type(
screen.getByLabelText("change item value amount"),
"123",
);
await userEvent.type(screen.getByLabelText("add"), "123");

await userEvent.click(screen.getByLabelText("multiply item value"));
await userEvent.click(screen.getByLabelText("multiplication"));
await userEvent.click(acceptButton);

expect(onCalculate).toBeCalledWith(123, "mul");
expect(onCalculate).toBeCalledWith(123, "multiply");
});

it("calls onCalculate with div", async () => {
const button = screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
});
await userEvent.click(button);
const acceptButton = screen.getByRole("button", {
name: "accept change item value amount",
name: "apply change to item value",
});

await userEvent.type(
screen.getByLabelText("change item value amount"),
"123",
);
await userEvent.type(screen.getByLabelText("add"), "123");

await userEvent.click(screen.getByLabelText("divide item value"));
await userEvent.click(screen.getByLabelText("division"));
await userEvent.click(acceptButton);

expect(onCalculate).toBeCalledWith(123, "div");
expect(onCalculate).toBeCalledWith(123, "divide");
});
});
40 changes: 20 additions & 20 deletions src/components/CalculateButton/CalculateButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,44 +68,44 @@ function CalculateButton({
variant="outline-secondary"
id="dropdown-operation"
>
{operation === "add" && <CgMathPlus />}
{operation === "sub" && <BsDashLg />}
{operation === "mul" && <BsXLg />}
{operation === "div" && <CgMathDivide />}
{operation === "add" && <CgMathPlus aria-hidden />}
{operation === "subtract" && <BsDashLg aria-hidden />}
{operation === "multiply" && <BsXLg aria-hidden />}
{operation === "divide" && <CgMathDivide aria-hidden />}
</Dropdown.Toggle>

<Dropdown.Menu>
<Dropdown.Item
aria-label="add to item value"
aria-label="addition"
onClick={() => setOperation("add")}
>
<CgMathPlus />
<CgMathPlus aria-hidden />
</Dropdown.Item>
<Dropdown.Item
aria-label="subtract to item value"
onClick={() => setOperation("sub")}
aria-label="subtraction"
onClick={() => setOperation("subtract")}
>
<BsDashLg />
<BsDashLg aria-hidden />
</Dropdown.Item>
<Dropdown.Item
aria-label="multiply item value"
onClick={() => setOperation("mul")}
aria-label="multiplication"
onClick={() => setOperation("multiply")}
>
<BsXLg />
<BsXLg aria-hidden />
</Dropdown.Item>
<Dropdown.Item
aria-label="divide item value"
onClick={() => setOperation("div")}
aria-label="division"
onClick={() => setOperation("divide")}
>
<CgMathDivide />
<CgMathDivide aria-hidden />
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<CurrencyInput
id={`${label}-${itemForm.id}-operation-value`}
key={`item-${itemForm.id}-operation-value`}
className="text-end form-control straight-corners fixed-width-font"
aria-label={"change item value amount"}
aria-label={`${operation}`}
name="item-operate-value"
intlConfig={intlConfig}
defaultValue={0}
Expand All @@ -120,15 +120,15 @@ function CalculateButton({
<Button
id={`item-${itemForm.id}-trigger-operation-button`}
key={`${itemForm.id}-trigger-operation-button`}
aria-label={"accept change item value amount"}
aria-label={"apply change to item value"}
variant="outline-secondary"
type="button"
onClick={() => {
handleCalculate();
opButtonRef?.current?.click();
}}
>
<BsCheckLg />
<BsCheckLg aria-hidden />
</Button>
</InputGroup>
</Popover.Body>
Expand All @@ -138,7 +138,7 @@ function CalculateButton({
<Button
id={`${label}-${itemForm.id}-operate-button`}
key={`${itemForm.id}-operate-button`}
aria-label={"select operations to change item value amount"}
aria-label={"select operation type to item value"}
aria-haspopup="dialog"
variant="outline-secondary"
type="button"
Expand All @@ -149,7 +149,7 @@ function CalculateButton({
}, 0);
}}
>
<BsPlusSlashMinus />
<BsPlusSlashMinus aria-hidden />
</Button>
</OverlayTrigger>
</>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Chart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ function Chart({
disabled
/>
<InputGroup.Text>
<BsPercent />
<BsPercent aria-hidden />
</InputGroup.Text>
</InputGroup>
)}
Expand Down
20 changes: 13 additions & 7 deletions src/components/ErrorModal/ErrorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function ErrorModal({
handleShow(false);
}}
>
<BsXLg />
<BsXLg aria-hidden />
</Button>
</Modal.Header>
<Modal.Body className="textarea mx-1">
Expand All @@ -87,7 +87,7 @@ function ErrorModal({
<Button
data-testid="json-error-close"
className="align-self-end"
aria-label="dismiss error message"
aria-label="close error dialog"
key={"modal-dismiss-button"}
variant="delete-modal"
type="button"
Expand All @@ -96,7 +96,7 @@ function ErrorModal({
handleError();
}}
>
<BsXLg />
<BsXLg aria-hidden />
</Button>
</Modal.Header>
<Modal.Body key="json-error-modal-body">
Expand All @@ -110,7 +110,10 @@ function ErrorModal({
key={`${jsonError.file}-item-${i}`}
eventKey={jsonError.file}
>
<Accordion.Header key={`${jsonError.file}-header-${i}`}>
<Accordion.Header
aria-label="file"
key={`${jsonError.file}-header-${i}`}
>
{jsonError.file}
</Accordion.Header>
<Accordion.Body
Expand Down Expand Up @@ -146,15 +149,15 @@ function ErrorModal({
data-testid="csv-error-close"
className="align-self-end"
key={"modal-dismiss-button"}
aria-label="dismiss error message"
aria-label="close error dialog"
variant="delete-modal"
type="button"
onClick={() => {
handleShow(false);
handleError();
}}
>
<BsXLg />
<BsXLg aria-hidden />
</Button>
</Modal.Header>
<Modal.Body key="csv-error-modal-body">
Expand All @@ -168,7 +171,10 @@ function ErrorModal({
key={`${csvError.file}-item-${i}`}
eventKey={csvError.file}
>
<Accordion.Header key={`${csvError.file}-header-${i}`}>
<Accordion.Header
aria-label="file"
key={`${csvError.file}-header-${i}`}
>
{csvError.file}
</Accordion.Header>
<Accordion.Body
Expand Down
2 changes: 1 addition & 1 deletion src/components/ItemForm/ItemFormGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe("ItemFormGroup", () => {
it("opens popover when clicking the button", async () => {
await userEvent.click(
screen.getByRole("button", {
name: "select operations to change item value amount",
name: "select operation type to item value",
}),
);

Expand Down
4 changes: 2 additions & 2 deletions src/components/ItemForm/ItemFormGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function ItemFormGroup({
handleRemove(itemForm);
}}
>
<BsXLg />
<BsXLg aria-hidden />
</Button>
</OverlayTrigger>
</Popover.Body>
Expand All @@ -196,7 +196,7 @@ function ItemFormGroup({
}, 0);
}}
>
<BsXLg />
<BsXLg aria-hidden />
</Button>
</OverlayTrigger>
</InputGroup>
Expand Down
Loading

0 comments on commit edc5bf5

Please sign in to comment.