fix: use SPA navigation for sidebar Automations button (#217)

This commit is contained in:
Hiep Le
2026-05-09 18:08:56 +07:00
committed by GitHub
parent b336afb3d5
commit 7ebf95a66b
2 changed files with 44 additions and 6 deletions
@@ -1,14 +1,39 @@
import { createEvent, fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { AutomationsButton } from "#/components/shared/buttons/automations-button";
import {
NavigationProvider,
type NavigationContextValue,
} from "#/context/navigation-context";
vi.mock("#/components/shared/buttons/styled-tooltip", () => ({
StyledTooltip: ({ children }: { children: unknown }) => children,
}));
function renderAutomationsButton(
props: { disabled?: boolean } = {},
overrides: Partial<NavigationContextValue> = {},
) {
const value: NavigationContextValue = {
currentPath: "/",
conversationId: null,
isNavigating: false,
navigate: vi.fn(),
...overrides,
};
const result = render(
<NavigationProvider value={value}>
<AutomationsButton {...props} />
</NavigationProvider>,
);
return { ...result, navigate: value.navigate };
}
describe("AutomationsButton", () => {
it("should render a link to /automations", () => {
render(<AutomationsButton />);
renderAutomationsButton();
const link = screen.getByTestId("automations-button");
expect(link).toBeInTheDocument();
@@ -16,15 +41,26 @@ describe("AutomationsButton", () => {
});
it("should be focusable and accessible when enabled", () => {
render(<AutomationsButton />);
renderAutomationsButton();
const link = screen.getByTestId("automations-button");
expect(link).toHaveAttribute("tabIndex", "0");
expect(link).toHaveAttribute("aria-label", "SIDEBAR$AUTOMATIONS");
});
it("should navigate via SPA routing without a full page reload when clicked", () => {
const { navigate } = renderAutomationsButton();
const link = screen.getByTestId("automations-button");
const clickEvent = createEvent.click(link);
fireEvent(link, clickEvent);
expect(navigate).toHaveBeenCalledWith("/automations", { replace: false });
expect(clickEvent.defaultPrevented).toBe(true);
});
it("should prevent navigation and remove from tab order when disabled", () => {
render(<AutomationsButton disabled />);
const { navigate } = renderAutomationsButton({ disabled: true });
const link = screen.getByTestId("automations-button");
expect(link).toHaveAttribute("tabIndex", "-1");
@@ -32,5 +68,6 @@ describe("AutomationsButton", () => {
const clickEvent = createEvent.click(link);
fireEvent(link, clickEvent);
expect(clickEvent.defaultPrevented).toBe(true);
expect(navigate).not.toHaveBeenCalled();
});
});
@@ -1,5 +1,6 @@
import { useTranslation } from "react-i18next";
import { I18nKey } from "#/i18n/declaration";
import { NavigationLink } from "#/components/shared/navigation-link";
import { StyledTooltip } from "#/components/shared/buttons/styled-tooltip";
import AutomationsIcon from "#/icons/automations.svg?react";
import { cn } from "#/utils/utils";
@@ -17,8 +18,8 @@ export function AutomationsButton({
return (
<StyledTooltip content={label} placement="right">
<a
href="/automations"
<NavigationLink
to="/automations"
data-testid="automations-button"
aria-label={label}
tabIndex={disabled ? -1 : 0}
@@ -32,7 +33,7 @@ export function AutomationsButton({
})}
>
<AutomationsIcon width={24} height={24} />
</a>
</NavigationLink>
</StyledTooltip>
);
}